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

77 lines
2.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

%{
#include <stdio.h>
void yyerror(const char *s);
extern int yylex();
extern char *yytext;
extern FILE *yyin;
%}
%union {
char *str;
}
%token <str> IDENTIFIER NUMBER
%token LBRACE RBRACE LPAREN RPAREN SEMICOLON ASSIGN PLUS MINUS MULT DIV MOD RET PRINT WHILE
%type <str> expr program statement block
%left PLUS MINUS
%left MULT DIV MOD
%right UNARY
%%
// Program - последовательность утверждений
program:
| program statement
;
// Утверждение - либо блок {...}, либо выражение с ; в конце
statement:
{ printf("\033[93mANOTHER STATEMENT\n\033[0m"); } expr SEMICOLON
| block
| WHILE { printf("\033[1;34m>>> WHILE LOOP DETECTED\033[0m\n"); }
LPAREN expr RPAREN
{ printf("\033[1;34m>>> WHILE BODY STARTS\033[0m\n"); }
block
{ printf("\033[1;34m>>> WHILE LOOP ENDED\033[0m\n"); }
;
// Блок - { program }, т.е. это последовательность утверждений и она находится в скобках { }
block:
LBRACE program RBRACE
;
// Возможные выражения
expr:
RET { printf("RET\n") } expr // выражение вида return expr
| PLUS { printf("UNARY PLUS\n"); } expr %prec UNARY // выражение вида +expr
| MINUS { printf("UNARY MINUS\n"); } expr %prec UNARY // выражение вида -expr
| PRINT { printf("PRINT\n") } expr // выражение вида print expr
| IDENTIFIER { printf("IDENTIFIER(%s)\n", $1); free($1); } ASSIGN { printf("ASSIGN\n"); } expr // выражения вида a=expr
| expr PLUS { printf("PLUS\n") } expr // выражения вида expr+expr
| expr MINUS { printf("MINUS\n") } expr // выражения вида expr-expr
| expr MULT { printf("MULT\n") } expr // выражения вида expr*expr
| expr DIV { printf("DIV\n") } expr // выражения вида expr/expr
| expr MOD { printf("MOD\n") } expr // выражения вида expr%expr
| LPAREN { printf("LPAREN\n") } expr RPAREN { printf("RPAREN\n") } // выражения вида (expr)
| IDENTIFIER { printf("IDENTIFIER(%s)\n", $1); free($1); }
| NUMBER { printf("NUMBER(%s)\n", $1); free($1); }
;
%%
int main(int argc, char **argv) {
if (argc > 1) {
FILE *f = fopen(argv[1], "r");
if (!f) {
perror("\033[91mFail open file\033[0m");
return 1;
}
yyin = f;
}
yyparse();
printf("\033[92m\nGood code\033[0m");
return 0;
}