program: decls_and_stmts EOF { $1 } ;; decl: PROC ID stmt {PROC_TREE ($2,$3)} ;; decls_and_stmts: decl { [$1] } | stmt { [$1] } | stmt SEMI decls_and_stmts { $1 :: $3 } | decl SEMI decls_and_stmts { $1 :: $3 } ;; stmtgroup: stmt { [$1] } | stmt SEMI stmtgroup { $1 :: $3 } ;; stmt: stmt_a1 { $1 } | stmt_a2 { $1 } ;; stmt_a1: /* empty */ { NOOP_TREE } | LBRACE stmtgroup RBRACE { STMT_GROUP_TREE $2 } | PRINT expr { PRINT_TREE $2 } | CALL ID { CALL_TREE $2 } | GET ID { GET_TREE $2 } | ID EQ expr { ASSIGN_TREE ($1,$3) } | ID PLUS_EQ expr { ASSIGN_TREE ($1,(PLUS_TREE((ID_TREE $1),$3))) } | ID MINUS_EQ expr { ASSIGN_TREE ($1,(MINUS_TREE((ID_TREE $1),$3))) } | ID TIMES_EQ expr { ASSIGN_TREE ($1,(TIMES_TREE((ID_TREE $1),$3))) } | WHILE LPAREN expr RPAREN stmt_a1 { WHILE_TREE($3,$5)} | IF LPAREN expr RPAREN stmt_a1 ELSE stmt_a1 { IF_TREE($3,$5,$7) } ;; stmt_a2: WHILE LPAREN expr RPAREN stmt_a2 { WHILE_TREE($3,$5)} | IF LPAREN expr RPAREN stmt { IF_TREE($3,$5,NOOP_TREE) } | IF LPAREN expr RPAREN stmt_a1 ELSE stmt_a2 { IF_TREE($3,$5,$7) }