%{ #include #include #include extern int yylineno; void yyerror(const char *s); int yylex(); extern FILE *yyin; %} %union { int num; char *str; } %token NUMBER %token IDENTIFIER %token IF ELSE WHILE RETURN PRINT %token AND OR NOT GE LE EQ NE %nonassoc '>' '<' GE LE EQ NE %left OR %left AND %left '=' '+' '-' %left '*' '/' '%' %right NOT UMINUS %% program: | program statement ; statement: expr ';' semicolons | IF '(' expr ')' statement ELSE statement | IF '(' expr ')' statement | WHILE '(' expr ')' statement | RETURN expr ';' semicolons | PRINT expr ';' semicolons | '{' program '}' ; semicolons: /* empty */ | semicolons ';' ; expr: NUMBER | IDENTIFIER | IDENTIFIER '=' expr | expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | expr '%' expr | expr AND expr | expr OR expr | NOT expr | '-' expr %prec UMINUS | '+' expr | expr '>' expr | expr '<' expr | expr GE expr | expr LE expr | expr EQ expr | expr NE expr | '(' expr ')' ; %% void yyerror(const char *s) { fprintf(stderr, "Error at line %d: %s\n", yylineno, s); exit(1); } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } FILE *input = fopen(argv[1], "r"); if (!input) { perror("Error opening file"); return 1; } yyin = input; yyparse(); fclose(input); printf("Parsing completed successfully!\n"); return 0; }