106 lines
1.9 KiB
Plaintext
106 lines
1.9 KiB
Plaintext
%{
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
extern int yylineno;
|
|
extern char *last_lexeme;
|
|
void yyerror(const char *s);
|
|
int yylex();
|
|
|
|
extern FILE *yyin;
|
|
%}
|
|
|
|
%union {
|
|
int num;
|
|
char *str;
|
|
}
|
|
|
|
%token <num> NUMBER
|
|
%token <str> IDENTIFIER
|
|
%token IF ELSE WHILE RETURN PRINT
|
|
%token AND OR NOT GE LE EQ NE
|
|
|
|
%right '='
|
|
%left OR
|
|
%left AND
|
|
%left EQ NE
|
|
%left '<' '>' GE LE
|
|
%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) {
|
|
if (last_lexeme) {
|
|
fprintf(stderr, "\033[91mError at line %d: %s (near '%s')\n\033[0m", yylineno, s, last_lexeme);
|
|
} else {
|
|
fprintf(stderr, "\033[91mError at line %d: %s\n\033[0m", yylineno, s);
|
|
}
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc < 2) {
|
|
fprintf(stderr, "\033[91mUsage: %s <input_file>\n\033[0m", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
FILE *input = fopen(argv[1], "r");
|
|
if (!input) {
|
|
perror("\033[91mError opening file"); printf("\033[0m");
|
|
return 1;
|
|
}
|
|
|
|
yyin = input;
|
|
yyparse();
|
|
fclose(input);
|
|
|
|
printf("\033[92mParsing completed successfully!\033[0m\n");
|
|
return 0;
|
|
} |