flex-bison-in-action/analyzers/cpl/cpl.y

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;
}