%{ # include "ast.h" void yyerror (const char *msg); %} %union { ast * t; int n; char v; } %token T_print "print" %token T_let "let" %token T_begin "begin" %token T_end "end" %token T_for "for" %token T_do "do" %token T_if "if" %token T_then "then" %token T_id %token T_num %left '+' '-' %left '*' '/' %left UMINUS %type stmt_list %type stmt %type expr %% program: stmt_list { prologue(); ast_compile($1); epilogue(); } ; stmt_list: /* nothing */ { $$ = ast_empty(); } | stmt stmt_list { $$ = ast_seq($1, $2); } ; stmt: "print" expr { $$ = ast_print($2); } | "let" T_id '=' expr { $$ = ast_let($2, $4); } | "begin" stmt_list "end" { $$ = $2; } | "for" expr "do" stmt { $$ = ast_for($2, $4); } | "if" expr "then" stmt { $$ = ast_if($2, $4); } ; expr: T_num { $$ = ast_num($1); } | T_id { $$ = ast_id($1); } | expr '+' expr { $$ = ast_op('+', $1, $3); } | expr '*' expr { $$ = ast_op('*', $1, $3); } | expr '-' expr { $$ = ast_op('-', $1, $3); } | expr '/' expr { $$ = ast_op('/', $1, $3); } | '-' expr { $$ = ast_op('~', $2, NULL); } %prec UMINUS | '(' expr ')' { $$ = $2; } ; %% void ERROR (const char * fmt, ...); void yyerror (const char *msg) { ERROR("parser said, %s", msg); } int main () { return yyparse(); }