%{ #include void yyerror(const char *s); extern int yylex(); extern char *yytext; extern FILE *yyin; %} %union { char *str; } %token IDENTIFIER NUMBER %token LBRACE RBRACE LPAREN RPAREN SEMICOLON ASSIGN PLUS MINUS MULT DIV MOD RET PRINT WHILE %type 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; }