Source

arana-main / arana / grammar.y

Full commit
/*
 * grammar.y
 *
 * (c) Copyright 2009 by Georg Brandl.
 */

%include {
#include "arana.h"

/* redefining AR_ISIG so that AR_ macros work in parser functions */
#undef  AR_ISIG
#define AR_ISIG  ps->AI, ps->CF
}

%name ArParse
%extra_argument { ArParseState *ps }
%token_type     { AR }
%token_prefix   AR_TOK_
%token_destructor { ps = ps; }
%syntax_error   {
    // detect several special kinds of syntax error
    if (yypParser->yyidx > 0 &&
        yypParser->yystack[yypParser->yyidx].major == AR_TOK_NEWLINE &&
        yypParser->yystack[yypParser->yyidx-1].major == AR_TOK_COLON) {
        // expected indentation (after colon/newline)
        ps->errortype = AR_SYN_ERROR_INDENT_EXPECTED;
    } else if (yymajor == AR_TOK_INDENT) {
        ps->errortype = AR_SYN_ERROR_UNEXPECTED_INDENT;
    } else if (yymajor == AR_TOK_DEDENT) {
        ps->errortype = AR_SYN_ERROR_UNEXPECTED_DEDENT;
    } else if (yymajor == AR_TOK_NEWLINE) {
        ps->errortype = AR_SYN_ERROR_UNEXPECTED_NEWLINE;
    }
    AR_PARSE_ERROR(ps);
}

%left     COMMA.
%left     OR AND.
%right    ADDASSIGN SUBASSIGN MULASSIGN DIVASSIGN MODASSIGN POWASSIGN ASSIGN.
%left     EQ NEQ.
%left     GT GTE LT LTE.
%left     PIPE CARET.
%left     AMP.
%left     BITL BITR.
%left     ADD SUB TILDE.
%left     MUL DIV MOD.
%right    POW.
%nonassoc MADD MSUB.
%right    NOT.
%left     LPAREN LBRACKET DOT.

%type module       { ArStmtSeq *  }
%type statements   { ArStmtSeq *  }
%type statement    { ArStmtNode * }
%type suite        { ArStmtNode * }
%type small_stmts  { ArStmtSeq * }
%type small_stmt   { ArStmtNode * }
%type expr         { ArExprNode * }
%type interp_items { ArExprSeq * }
%type interp_item  { ArExprNode * }
%type exprlist     { ArExprSeq * }
%type exprlist1    { ArExprSeq * }
%type simpletarget { ArExprNode * }
%type target       { ArExprNode * }
%type targetlist   { ArExprSeq * }

module ::= statements(B) newlines END.          { ps->ast = AR_AST(Module, B); }

newlines ::= NEWLINE newlines.
newlines ::= .

statements(A) ::= statements(B) statement(C). { AR_AST_SEQ_ADD(Stmt, A, B, C); }
statements(A) ::= statement(B).                 { AR_AST_SEQ_NEW1(Stmt, A, B); }

statement(A) ::= IF expr(B) suite(C) ELSE suite(D). { A = AR_AST(If, B, C, D); }
statement(A) ::= IF expr(B) suite(C).            { A = AR_AST(If, B, C, NULL); }
statement(A) ::= FOR target(B) IN expr(C) suite(D).
						   { A = AR_AST(For, B, C, D); }
//statement(A) ::= DEF NAME(B) LPAREN arglist(C) RPAREN suite(D).
//                               { A = AR_AST(def_stmt, AR_AS_CHARP(B), C, D); }
statement(A) ::= small_stmts(B).                    { A = AR_AST(Compound, B); }

suite(A) ::= COLON small_stmts(B).                  { A = AR_AST(Compound, B); }
suite(A) ::= COLON NEWLINE INDENT statements(B) DEDENT.
                                                    { A = AR_AST(Compound, B); }

small_stmts(A) ::= small_stmt(B) NEWLINE.       { AR_AST_SEQ_NEW1(Stmt, A, B); }
small_stmts(A) ::= small_stmt(B) SEMICOLON NEWLINE.
                                                { AR_AST_SEQ_NEW1(Stmt, A, B); }
small_stmts(A) ::= small_stmt(B) SEMICOLON small_stmts(C).
                                              { AR_AST_SEQ_ADD(Stmt, A, C, B); }

small_stmt(A) ::= PASS.                          { A = AR_AST(Compound, NULL); }
small_stmt(A) ::= exprlist(B).
                   { ArExprNode *tmp; AR_AST_MAYBE_TUPLE(tmp, B, AR_CTX_Load);
                                                    A = AR_AST(ExprStmt, tmp); }
small_stmt(A) ::= exprlist(B) COMMA.
                        { A = AR_AST(ExprStmt, AR_AST(Tuple, B, AR_CTX_Load)); }

// simple expressions (literals and names)
expr(A) ::= CONST(B).                                { A = AR_AST(Literal, B); }
expr(A) ::= INTERP_START INTERP_END.     { A = AR_AST(Literal, AR_STRING("")); }
expr(A) ::= INTERP_START interp_items(B) INTERP_END.
                                               { A = AR_AST(Interpolation, B); }
expr(A) ::= NAME(B).          { A = AR_AST(Name, AR_AS_CHARP(B), AR_CTX_Load); }

// unary ops
expr(A) ::= ADD expr(B). [NOT]         { A = AR_AST(UnaryOp, B, AR_ASTOP_POS); }
expr(A) ::= SUB expr(B). [NOT]         { A = AR_AST(UnaryOp, B, AR_ASTOP_NEG); }
expr(A) ::= NOT expr(B).               { A = AR_AST(UnaryOp, B, AR_ASTOP_NOT); }

// binary ops
expr(A) ::= expr(B) TILDE expr(C).
                                { A = AR_AST(BinaryOp, B, C, AR_ASTOP_CONCAT); }
expr(A) ::= expr(B) ADD expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_ADD); }
expr(A) ::= expr(B) SUB expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_SUB); }
expr(A) ::= expr(B) MUL expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_MUL); }
expr(A) ::= expr(B) DIV expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_DIV); }
expr(A) ::= expr(B) MOD expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_MOD); }
expr(A) ::= expr(B) POW expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_POW); }

expr(A) ::= expr(B) EQ  expr(C).    { A = AR_AST(BinaryOp, B, C, AR_ASTOP_EQ); }
expr(A) ::= expr(B) NEQ expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_NEQ); }
expr(A) ::= expr(B) GT  expr(C).    { A = AR_AST(BinaryOp, B, C, AR_ASTOP_GT); }
expr(A) ::= expr(B) GTE expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_GTE); }
expr(A) ::= expr(B) LT  expr(C).    { A = AR_AST(BinaryOp, B, C, AR_ASTOP_LT); }
expr(A) ::= expr(B) LTE expr(C).   { A = AR_AST(BinaryOp, B, C, AR_ASTOP_LTE); }

// attribute access (XXX is that good?)
expr(A) ::= expr(B) DOT NAME(C).
                  { A = AR_AST(Attribute, B, AR_AST(Literal, C), AR_CTX_Load); }
expr(A) ::= expr(B) DOT LBRACKET expr(C) RBRACKET.
                                   { A = AR_AST(Attribute, B, C, AR_CTX_Load); }

// calls
expr(A) ::= expr(B) LPAREN RPAREN.
                      { A = AR_AST(Call, B, AR_AST(Tuple, NULL, AR_CTX_Load)); }
expr(A) ::= expr(B) LPAREN exprlist(C) RPAREN.
                         { A = AR_AST(Call, B, AR_AST(Tuple, C, AR_CTX_Load)); }
expr(A) ::= expr(B) LPAREN exprlist(C) COMMA RPAREN.
                         { A = AR_AST(Call, B, AR_AST(Tuple, C, AR_CTX_Load)); }

// tuple displays (or grouping)
expr(A) ::= LPAREN RPAREN.             { A = AR_AST(Tuple, NULL, AR_CTX_Load); }
expr(A) ::= LPAREN exprlist(B) RPAREN.
                                      { AR_AST_MAYBE_TUPLE(A, B, AR_CTX_Load); }
expr(A) ::= LPAREN exprlist(B) COMMA RPAREN.
                                          { A = AR_AST(Tuple, B, AR_CTX_Load); }

// list displays
expr(A) ::= LBRACKET RBRACKET.                       { A = AR_AST(List, NULL); }
expr(A) ::= LBRACKET exprlist(B) RBRACKET.              { A = AR_AST(List, B); }
expr(A) ::= LBRACKET exprlist(B) COMMA RBRACKET.        { A = AR_AST(List, B); }

// subscription
expr(A) ::= expr(B) LBRACKET expr(C) RBRACKET.
                                   { A = AR_AST(Subscript, B, C, AR_CTX_Load); }

// assignments
expr(A) ::= target(B) ASSIGN expr(C).              { A = AR_AST(Assign, B, C); }
expr(A) ::= simpletarget(B) ADDASSIGN expr(C).
                                  { A = AR_AST(AugAssign, B, C, AR_ASTOP_ADD); }
expr(A) ::= simpletarget(B) SUBASSIGN expr(C).
                                  { A = AR_AST(AugAssign, B, C, AR_ASTOP_SUB); }
expr(A) ::= simpletarget(B) MULASSIGN expr(C).
                                  { A = AR_AST(AugAssign, B, C, AR_ASTOP_MUL); }
expr(A) ::= simpletarget(B) DIVASSIGN expr(C).
                                  { A = AR_AST(AugAssign, B, C, AR_ASTOP_DIV); }
expr(A) ::= simpletarget(B) MODASSIGN expr(C).
                                  { A = AR_AST(AugAssign, B, C, AR_ASTOP_MOD); }
expr(A) ::= simpletarget(B) POWASSIGN expr(C).
                                  { A = AR_AST(AugAssign, B, C, AR_ASTOP_POW); }

interp_items(A) ::= interp_items(B) interp_item(C).
                                              { AR_AST_SEQ_ADD(Expr, A, B, C); }
interp_items(A) ::= interp_item(B).             { AR_AST_SEQ_NEW1(Expr, A, B); }

interp_item(A) ::= INTERP_STRING(B).                 { A = AR_AST(Literal, B); }
interp_item(A) ::= LBRACE expr(B) RBRACE.                             { A = B; }

exprlist(A) ::= exprlist(B) COMMA expr(C).    { AR_AST_SEQ_ADD(Expr, A, B, C); }
exprlist(A) ::= expr(B).                        { AR_AST_SEQ_NEW1(Expr, A, B); }

simpletarget(A) ::= NAME(B). { A = AR_AST(Name, AR_AS_CHARP(B), AR_CTX_Store); }
simpletarget(A) ::= expr(B) DOT NAME(C).
                 { A = AR_AST(Attribute, B, AR_AST(Literal, C), AR_CTX_Store); }
simpletarget(A) ::= expr(B) DOT LBRACKET expr(C) RBRACKET.
                                  { A = AR_AST(Attribute, B, C, AR_CTX_Store); }
simpletarget(A) ::= expr(B) LBRACKET expr(C) RBRACKET.
                                  { A = AR_AST(Subscript, B, C, AR_CTX_Store); }

target(A) ::= simpletarget(B).                                        { A = B; }
target(A) ::= LPAREN exprlist(B) RPAREN.
            { AR_AST_MAYBE_TUPLE(A, B, AR_CTX_Store); AR_AST_SET_STORE_CTX(A); }
target(A) ::= LPAREN exprlist(B) COMMA RPAREN.
                { A = AR_AST(Tuple, B, AR_CTX_Store); AR_AST_SET_STORE_CTX(A); }