aboutsummaryrefslogtreecommitdiff
path: root/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y103
1 files changed, 103 insertions, 0 deletions
diff --git a/parser.y b/parser.y
new file mode 100644
index 0000000..5974b96
--- /dev/null
+++ b/parser.y
@@ -0,0 +1,103 @@
+%{
+#include <stdio.h>
+#include "ast.h"
+
+extern char *yytext;
+extern int yylineno;
+extern int yylex();
+void yyerror(const char *s) { fprintf(stderr, "Parse error at token \"%s\", line %d: %s\n", yytext, yylineno, s); }
+ASTNode *ast_root;
+%}
+
+
+%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 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
+
+
+%%
+
+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); }
+ ;
+
+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; }
+ ;
+
+%%