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

99 lines
1.6 KiB
Plaintext

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int yylineno;
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
%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 <input_file>\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;
}