diff --git a/src/parser/syntax_analyzer.y b/src/parser/syntax_analyzer.y index 8b0d34714c24ae459c57054abd0c5e3208d2c55c..d5883f298644248b7aac0e81e65f3a179a8ed378 100644 --- a/src/parser/syntax_analyzer.y +++ b/src/parser/syntax_analyzer.y @@ -26,16 +26,118 @@ syntax_tree_node *node(const char *node_name, int children_num, ...); %} /* TODO: Complete this definition. */ -%union {} +%union { + syntax_tree_node *node; +} /* TODO: Your tokens here. */ %start program +%token ADD SUB MUL DIV +%token LT LTE GT GTE EQ NEQ ASSIN +%token SEMICOLON COMMA LPARENTHESE RPARENTHESE LBRACKET RBRACKET LBRACE RBRACE +%token ELSE IF INT FLOAT RETURN VOID WHILE IDENTIFIER LETTER INTEGER FLOATPOINT ARRAY +%type type-specifier relop addop mulop +%type declaration-list declaration var-declaration fun-declaration local-declarations +%type compound-stmt statement-list statement expression-stmt iteration-stmt selection-stmt return-stmt +%type simple-expression expression var additive-expression term factor integer float call +%type params param-list param args arg-list program + %% /* TODO: Your rules here. */ -program : declaration-list { $$ = node("program", 1, $1); gt->root = $$; } +program : declaration-list { $$ = node("program", 1, $1); gt->root = $$; } ; +declaration-list : declaration-list declaration { $$ = node("declaration-list", 2, $1, $2); } + | declaration { $$ = node("declaration-list", 1, $1); } + ; +declaration : var-declaration { $$ = node("declaration", 1, $1); } + | fun-declaration { $$ = node("declaration", 1, $1); } + ; +var-declaration : type-specifier IDENTIFIER SEMICOLON { $$ = node("var-declaration", 3, $1, $2, $3); } + | type-specifier IDENTIFIER LBRACKET INTEGER RBRACKET SEMICOLON { $$ = node("var-declaration", 6, $1, $2, $3, $4, $5, $6); } + ; +type-specifier : INT { $$ = node("type-specifier", 1, $1); } + | FLOAT { $$ = node("type-specifier", 1, $1); } + | VOID { $$ = node("type-specifier", 1, $1); } + ; +fun-declaration : type-specifier IDENTIFIER LPARENTHESE params RPARENTHESE compound-stmt { $$ = node("fun-declaration", 6, $1, $2, $3, $4, $5, $6); } ; +params : param-list { $$ = node("params", 1, $1); } + | VOID { $$ = node("params", 1, $1); } + ; +param-list : param-list COMMA param { $$ = node("param-list", 3, $1, $2, $3); } + | param { $$ = node("param-list", 1, $1); } + ; +param : type-specifier IDENTIFIER { $$ = node("param", 2, $1, $2); } + | type-specifier IDENTIFIER ARRAY { $$ = node("param", 3, $1, $2, $3); } + ; +compound-stmt : LBRACE local-declarations statement-list RBRACE { $$ = node("compound-stmt", 4, $1, $2, $3, $4); } ; +local-declarations : { $$ = node("local-declarations", 0); } + | local-declarations var-declaration { $$ = node("local-declarations", 2, $1, $2); } + ; +statement-list : { $$ = node("statement-list", 0); } + | statement-list statement { $$ = node("statement-list", 2, $1, $2); } + ; +statement : expression-stmt { $$ = node("statement", 1, $1); } + | compound-stmt { $$ = node("statement", 1, $1); } + | selection-stmt { $$ = node("statement", 1, $1); } + | iteration-stmt { $$ = node("statement", 1, $1); } + | return-stmt { $$ = node("statement", 1, $1); } + ; +expression-stmt : expression SEMICOLON { $$ = node("expression-stmt", 2, $1, $2); } + | SEMICOLON { $$ = node("expression-stmt", 1, $1); } + ; +selection-stmt : IF LPARENTHESE expression RPARENTHESE statement { $$ = node("selection-stmt", 5, $1, $2, $3, $4, $5); } + | IF LPARENTHESE expression RPARENTHESE statement ELSE statement { $$ = node("selection-stmt", 7, $1, $2, $3, $4, $5, $6, $7); } + ; +iteration-stmt : WHILE LPARENTHESE expression RPARENTHESE statement { $$ = node("iteration-stmt", 5, $1, $2, $3, $4, $5); } ; +return-stmt : RETURN SEMICOLON { $$ = node("return-stmt", 2, $1, $2); } + | RETURN expression SEMICOLON { $$ = node("return-stmt", 3, $1, $2, $3); } + ; +expression : var ASSIN expression { $$ = node("expression", 3, $1, $2, $3); } + | simple-expression { $$ = node("expression", 1, $1); } + ; +var : IDENTIFIER { $$ = node("var", 1, $1); } + | IDENTIFIER LBRACKET expression RBRACKET { $$ = node("var", 4, $1, $2, $3, $4); } + ; +simple-expression : additive-expression relop additive-expression { $$ = node("simple-expression", 3, $1, $2, $3); } + | additive-expression { $$ = node("simple-expression", 1, $1); } + ; +relop : LTE { $$ = node("relop", 1, $1); } + | LT { $$ = node("relop", 1, $1); } + | GT { $$ = node("relop", 1, $1); } + | GTE { $$ = node("relop", 1, $1); } + | EQ { $$ = node("relop", 1, $1); } + | NEQ { $$ = node("relop", 1, $1); } + ; +additive-expression : additive-expression addop term { $$ = node("additive-expression", 3, $1, $2, $3); } + | term { $$ = node("additive-expression", 1, $1); } + ; +addop : ADD { $$ = node("addop", 1, $1); } + | SUB { $$ = node("addop", 1, $1); } + ; +term : term mulop factor { $$ = node("term", 3, $1, $2, $3); } + | factor { $$ = node("term", 1, $1); } + ; +mulop : MUL { $$ = node("mulop", 1, $1); } + | DIV { $$ = node("mulop", 1, $1); } + ; +factor : LPARENTHESE expression RPARENTHESE { $$ = node("factor", 3, $1, $2, $3); } + | var { $$ = node("factor", 1, $1); } + | call { $$ = node("factor", 1, $1); } + | integer { $$ = node("factor", 1, $1); } + | float { $$ = node("factor", 1, $1); } + ; +integer : INTEGER { $$ = node("integer", 1, $1); } ; +float : FLOATPOINT { $$ = node("float", 1, $1); } ; +call : IDENTIFIER LPARENTHESE args RPARENTHESE { $$ = node("call", 4, $1, $2, $3, $4); } ; +args : { $$ = node("args", 0); } + | arg-list { $$ = node("args", 1, $1); } + ; +arg-list : arg-list COMMA expression { $$ = node("arg-list", 3, $1, $2, $3); } + | expression { $$ = node("arg-list", 1, $1); } + ; + %%