aboutsummaryrefslogtreecommitdiff
path: root/src/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.y')
-rw-r--r--src/parser.y170
1 files changed, 88 insertions, 82 deletions
diff --git a/src/parser.y b/src/parser.y
index cb3544e..f03e54f 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -17,93 +17,99 @@ void yyerror(const char *s) {
%union {
int num;
char *id;
- int op;
struct ASTNode *node;
}
-%start program
-
-%token <id> TOKEN_IDENTIFIER
-%token <num> TOKEN_NUMERAL
-%token TOKEN_ASSIGN
-%token TOKEN_LEFT_PARENTHESIS TOKEN_RIGHT_PARENTHESIS
-%token TOKEN_SEMICOLON
-%token TOKEN_SKIP
-%token TOKEN_IF TOKEN_THEN TOKEN_ELSE TOKEN_END TOKEN_WHILE TOKEN_DO TOKEN_VAR TOKEN_IN
-%token TOKEN_PLUS TOKEN_MINUS TOKEN_MULTIPLY
-%token TOKEN_NOT TOKEN_OR TOKEN_AND
-%token TOKEN_EQUALS TOKEN_NOT_EQUALS TOKEN_LESS_THAN TOKEN_LESS_EQUAL TOKEN_GREATER_THAN TOKEN_GREATER_EQUAL
-
-%type <node> program statement variable arithmetic_expression boolean_expression
-%type <op> arithmetic_operation boolean_operation relational_operation
-
+%start prog
+
+%token <num> T_NUM
+%token <id> T_ID
+%token T_EQ T_NE T_LT T_LE T_GT T_GE
+%token T_TRUE T_FALSE
+%left T_OR
+%left T_AND
+%token T_NOT
+%left T_PLUS T_MINUS
+%left T_STAR
+%right T_UMINUS
+%token T_END T_IF T_THEN T_ELSE T_WHILE T_DO T_VAR T_IN
+%token T_SKIP
+%token T_ASSIGN
+%token T_LPAREN T_RPAREN
+%token T_SEM
+
+%type <node> prog stm var aexp bexp
%%
-
-program : statement
- { ast_root = $1; }
- ;
-
-statement : TOKEN_SKIP
- { $$ = ast_skip(); }
- | variable TOKEN_ASSIGN arithmetic_expression
- { $$ = ast_assign($1, $3); }
- | TOKEN_LEFT_PARENTHESIS statement TOKEN_SEMICOLON statement TOKEN_RIGHT_PARENTHESIS
- { $$ = ast_seq($2, $4); }
- | TOKEN_IF boolean_expression TOKEN_THEN statement TOKEN_ELSE statement TOKEN_END
- { $$ = ast_if($2, $4, $6); }
- | TOKEN_WHILE boolean_expression TOKEN_DO statement TOKEN_END
- { $$ = ast_while($2, $4); }
- | TOKEN_VAR variable TOKEN_ASSIGN arithmetic_expression TOKEN_IN statement TOKEN_END
- { $$ = ast_let($2, $4, $6); }
- ;
-
-variable : TOKEN_IDENTIFIER
- { $$ = ast_var($1); }
- ;
-
-arithmetic_expression : TOKEN_LEFT_PARENTHESIS arithmetic_expression arithmetic_operation arithmetic_expression TOKEN_RIGHT_PARENTHESIS
- { $$ = ast_aop($3, $2, $4); }
- | variable
- { $$ = $1; }
- | TOKEN_NUMERAL
- { $$ = ast_int($1); }
- ;
-
-arithmetic_operation : TOKEN_PLUS
- { $$ = AOP_ADD; }
- | TOKEN_MINUS
- { $$ = AOP_SUB; }
- | TOKEN_MULTIPLY
- { $$ = AOP_MUL; }
- ;
-
-boolean_expression : TOKEN_LEFT_PARENTHESIS boolean_expression boolean_operation boolean_expression TOKEN_RIGHT_PARENTHESIS
- { $$ = ast_bop($3, $2, $4); }
- | TOKEN_NOT boolean_expression
- { $$ = ast_not($2); }
- | arithmetic_expression relational_operation arithmetic_expression
- { $$ = ast_rop($2, $1, $3); }
- ;
-
-boolean_operation : TOKEN_OR
- { $$ = BOP_OR; }
- | TOKEN_AND
- { $$ = BOP_AND; }
- ;
-relational_operation : TOKEN_EQUALS
- { $$ = ROP_EQ; }
- | TOKEN_NOT_EQUALS
- { $$ = ROP_NE; }
- | TOKEN_LESS_THAN
- { $$ = ROP_LT; }
- | TOKEN_LESS_EQUAL
- { $$ = ROP_LE; }
- | TOKEN_GREATER_THAN
- { $$ = ROP_GT; }
- | TOKEN_GREATER_EQUAL
- { $$ = ROP_GE; }
- ;
+prog : stm
+ { ast_root = $1; }
+ ;
+
+stm : T_SKIP
+ { $$ = ast_skip(); }
+ | var T_ASSIGN aexp
+ { $$ = ast_assign($1, $3); }
+ | T_LPAREN stm T_SEM stm T_RPAREN
+ { $$ = ast_seq($2, $4); }
+ | stm T_SEM stm
+ { $$ = ast_seq($1, $3); }
+ | stm T_SEM
+ { $$ = $1; }
+ | T_IF bexp T_THEN stm T_ELSE stm T_END
+ { $$ = ast_if($2, $4, $6); }
+ | T_IF bexp T_THEN stm T_END
+ { $$ = ast_if($2, $4, ast_skip()); }
+ | T_WHILE bexp T_DO stm T_END
+ { $$ = ast_while($2, $4); }
+ | T_VAR var T_ASSIGN aexp T_IN stm T_END
+ { $$ = ast_let($2, $4, $6); }
+ ;
+
+var : T_ID
+ { $$ = ast_var($1); }
+ ;
+
+aexp : aexp T_PLUS aexp
+ { $$ = ast_aop(AOP_ADD, $1, $3); }
+ | aexp T_MINUS aexp
+ { $$ = ast_aop(AOP_SUB, $1, $3); }
+ | aexp T_STAR aexp
+ { $$ = ast_aop(AOP_MUL, $1, $3); }
+ | T_MINUS aexp %prec T_UMINUS
+ { $$ = ast_aop(AOP_SUB, ast_int(0), $2); }
+ | T_LPAREN aexp T_RPAREN
+ { $$ = $2; }
+ | var
+ { $$ = $1; }
+ | T_NUM
+ { $$ = ast_int($1); }
+ ;
+
+bexp : bexp T_OR bexp
+ { $$ = ast_bop(BOP_OR, $1, $3); }
+ | bexp T_AND bexp
+ { $$ = ast_bop(BOP_AND, $1, $3); }
+ | T_NOT bexp
+ { $$ = ast_not($2); }
+ | aexp T_EQ aexp
+ { $$ = ast_rop(ROP_EQ, $1, $3); }
+ | aexp T_NE aexp
+ { $$ = ast_rop(ROP_NE, $1, $3); }
+ | aexp T_LE aexp
+ { $$ = ast_rop(ROP_LE, $1, $3); }
+ | aexp T_LT aexp
+ { $$ = ast_rop(ROP_LT, $1, $3); }
+ | aexp T_GE aexp
+ { $$ = ast_rop(ROP_GE, $1, $3); }
+ | aexp T_GT aexp
+ { $$ = ast_rop(ROP_GT, $1, $3); }
+ | T_LPAREN bexp T_RPAREN
+ { $$ = $2; }
+ | T_TRUE
+ { $$ = ast_rop(ROP_EQ, ast_int(1), ast_int(1)); }
+ | T_FALSE
+ { $$ = ast_rop(ROP_EQ, ast_int(0), ast_int(1)); }
+ ;
%%