%{ #include #include "node.h" extern int yylex(void); extern int yylineno; int errors = 0; struct node; void yyerror(char const *); pNode root; %} %define api.value.type {struct node*} %token INTEGER FLOAT %token SEMI COMMA ASSIGNOP PLUS MINUS TIMES DIV AND OR DOT NOT LP RP LB RB LC RC STRUCT RETURN IF ELSE WHILE %token TYPE_INT TYPE_FLOAT ID %token LINE_COMMENT BLOCK_COMMENT %% // High-level Definitions Program: ExtDefList { pNode children[1] = { $1 }; $$ = newNode(Program, $1->line, 1, children, nullValue()); root = $$; } ; ExtDefList: ExtDef ExtDefList { pNode children[2] = { $1, $2 }; $$ = newNode(ExtDefList, $1->line, 2, children, nullValue()); } | { $$ = newNode(ExtDefList, -1, 0, NULL, nullValue()); } ; ExtDef: Specifier ExtDecList SEMI { pNode children[3] = { $1, $2, $3 }; $$ = newNode(ExtDef, $1->line, 3, children, nullValue()); } | Specifier SEMI { pNode children[2] = { $1, $2 }; $$ = newNode(ExtDef, $1->line, 2, children, nullValue()); } | Specifier FunDec CompSt { pNode children[3] = { $1, $2, $3 }; $$ = newNode(ExtDef, $1->line, 3, children, nullValue()); } ; ExtDecList: VarDec { pNode children[1] = { $1 }; $$ = newNode(ExtDecList, $1->line, 1, children, nullValue()); } | VarDec COMMA ExtDecList { pNode children[3] = { $1, $2, $3 }; $$ = newNode(ExtDecList, $1->line, 3, children, nullValue()); } ; // Specifiers Specifier: TYPE_INT { pNode children[1] = { $1 }; $$ = newNode(Specifier, $1->line, 1, children, nullValue()); } | TYPE_FLOAT { pNode children[1] = { $1 }; $$ = newNode(Specifier, $1->line, 1, children, nullValue()); } | StructSpecifier { pNode children[1] = { $1 }; $$ = newNode(Specifier, $1->line, 1, children, nullValue()); } ; StructSpecifier: STRUCT OptTag LC DefList RC { pNode children[5] = { $1, $2, $3, $4, $5 }; $$ = newNode(StructSpecifier, $1->line, 5, children, nullValue()); } | STRUCT Tag { pNode children[2] = { $1, $2 }; $$ = newNode(StructSpecifier, $1->line, 2, children, nullValue()); } ; OptTag: ID { pNode children[1] = { $1 }; $$ = newNode(OptTag, $1->line, 1, children, nullValue()); } | { $$ = newNode(OptTag, -1, 0, NULL, nullValue()); } ; Tag: ID { pNode children[1] = { $1 }; $$ = newNode(Tag, $1->line, 1, children, nullValue()); } ; // Declarators VarDec: ID { pNode children[1] = { $1 }; $$ = newNode(VarDec, $1->line, 1, children, nullValue()); } | VarDec LB INTEGER RB { pNode children[4] = { $1, $2, $3, $4 }; $$ = newNode(VarDec, $1->line, 4, children, nullValue()); } ; FunDec: ID LP VarList RP { pNode children[4] = { $1, $2, $3, $4 }; $$ = newNode(FunDec, $1->line, 4, children, nullValue()); } | ID LP RP { pNode children[3] = { $1, $2, $3 }; $$ = newNode(FunDec, $1->line, 3, children, nullValue()); } ; VarList: ParamDec COMMA VarList { pNode children[3] = { $1, $2, $3 }; $$ = newNode(VarList, $1->line, 3, children, nullValue()); } | ParamDec { pNode children[1] = { $1 }; $$ = newNode(VarList, $1->line, 1, children, nullValue()); } ; ParamDec: Specifier VarDec { pNode children[1] = { $1 }; $$ = newNode(ParamDec, $1->line, 1, children, nullValue()); } ; // Statements CompSt: LC DefList StmtList RC { pNode children[4] = { $1, $2, $3, $4 }; $$ = newNode(CompSt, $1->line, 4, children, nullValue()); } ; StmtList: Stmt StmtList { pNode children[2] = { $1, $2 }; $$ = newNode(StmtList, $1->line, 2, children, nullValue()); } | { $$ = newNode(StmtList, -1, 0, NULL, nullValue()); } ; Stmt: Exp SEMI { pNode children[2] = { $1, $2 }; $$ = newNode(Stmt, $1->line, 2, children, nullValue()); } | CompSt { pNode children[1] = { $1 }; $$ = newNode(Stmt, $1->line, 1, children, nullValue()); } | RETURN Exp SEMI { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Stmt, $1->line, 3, children, nullValue()); } | IF LP Exp RP Stmt { pNode children[5] = { $1, $2, $3, $4, $5 }; $$ = newNode(Stmt, $1->line, 5, children, nullValue()); } | IF LP Exp RP Stmt ELSE Stmt { pNode children[7] = { $1, $2, $3, $4, $5, $6, $7 }; $$ = newNode(Stmt, $1->line, 7, children, nullValue()); } | WHILE LP Exp RP Stmt { pNode children[5] = { $1, $2, $3, $4, $5 }; $$ = newNode(Stmt, $1->line, 5, children, nullValue()); } | error SEMI ; // Local Definitions DefList: Def DefList { pNode children[2] = { $1, $2 }; $$ = newNode(DefList, $1->line, 2, children, nullValue()); } | { $$ = newNode(DefList, -1, 0, NULL, nullValue()); } ; Def: Specifier DecList SEMI { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Def, $1->line, 3, children, nullValue()); } ; DecList: Dec { pNode children[1] = { $1 }; $$ = newNode(DecList, $1->line, 1, children, nullValue()); } | Dec COMMA DecList { pNode children[3] = { $1, $2, $3 }; $$ = newNode(DecList, $1->line, 3, children, nullValue()); } ; Dec: VarDec { pNode children[1] = { $1 }; $$ = newNode(Dec, $1->line, 1, children, nullValue()); } | VarDec ASSIGNOP Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Dec, $1->line, 3, children, nullValue()); } ; // Expressions Exp: Exp ASSIGNOP Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp AND Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp OR Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp PLUS Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp MINUS Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp TIMES Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp DIV Exp { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | LP Exp RP { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | MINUS Exp { pNode children[2] = { $1, $2 }; $$ = newNode(Exp, $1->line, 2, children, nullValue()); } | NOT Exp { pNode children[2] = { $1, $2 }; $$ = newNode(Exp, $1->line, 2, children, nullValue()); } | ID LP Args RP { pNode children[4] = { $1, $2, $3, $4 }; $$ = newNode(Exp, $1->line, 4, children, nullValue()); } | ID LP RP { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | Exp LB Exp RB { pNode children[4] = { $1, $2, $3, $4 }; $$ = newNode(Exp, $1->line, 4, children, nullValue()); } | Exp DOT ID { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Exp, $1->line, 3, children, nullValue()); } | ID { pNode children[1] = { $1 }; $$ = newNode(Exp, $1->line, 1, children, nullValue()); } | INTEGER { pNode children[1] = { $1 }; $$ = newNode(Exp, $1->line, 1, children, nullValue()); } | FLOAT { pNode children[1] = { $1 }; $$ = newNode(Exp, $1->line, 1, children, nullValue()); } ; Args: Exp COMMA Args { pNode children[3] = { $1, $2, $3 }; $$ = newNode(Args, $1->line, 3, children, nullValue()); } | Exp { pNode children[1] = { $1 }; $$ = newNode(Exp, $1->line, 1, children, nullValue()); } ; %% void yyerror(char const *s) { errors += 1; fprintf(stderr, "Error type B at Line %d: \"%s\".\n", yylineno, s); }