Я пишу лексер и парсер с помощью flex и bison. Я не понимаю, почему мой код Bison не компилируется. Вот мой код:
scanner.y:
{%
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
%}
%token INT REAL BOOL STRING ID BASIC KEYWORD OP ASSIGN EQUAL NEQUAL RELATION SPECIAL
%type <boolean> BOOL
%type <num> NUM
%type <flnum> REAL
%type <name> STRING
%type <name> ID
%type <name> BASIC
%type <name> KEYWORD
%type <name> OP
%type <name> RELATION
%type <symbol> SPECIAL
%union{
bool boolean;
char name[20];
char symbol;
int num;
float flnum;
}
%%
prog:
block
;
block:
'{' decls stmts '}'
;
decls:
decls decl
|
;
decl:
type ID ';'
;
type:
type '[' NUM ']'
| BASIC
;
stmts:
stmts stmt
|
;
stmt:
loc ASSIGN BOOL ';'
| "if" '(' BOOL ')' stmt
| "if" '(' BOOL ')' stmt "else" stmt
| "while" '(' BOOL ')' stmt
| "do" stmt "while" '(' BOOL ')' ';'
| "break" ';'
| block
;
loc:
loc '[' BOOL ']'
| ID
;
bool:
bool "||" join
| join
;
join:
join "&&" equality
| equality
;
equality:
equality EQUAL rel
| equality NEQUAL rel
| rel
;
rel:
expr '<' expr
| expr "<=" expr
| expr ">=" expr
| expr '>' expr
|expr
;
expr:
expr '+' term
| expr '-' term
| term
;
term:
term '*' unary
| term '/' unary
| unary
;
unary:
'!' unary
| '-' unary
| factor
;
factor:
'(' bool ')'
| loc
| NUM
| REAL
| BOOL
;
%%
#include "lex.yy.c"
yyerror() {printf("input error!");}
int main()
{
#ifdef YYDEBUG
yydebug = 1;
#endif
yyparse();
return 0;
}
scanner.l
%{
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "y.tab.h"
%}
sign -?
alph [A-Za-z]
digit [0-9]
bool "true"|"false"
%option noyywrap
%%
"if" {sscanf(yytext, "%s", yylval.name); return(KEYWORD);}
"while" {sscanf(yytext, "%s", yylval.name); return(KEYWORD);}
"do" {sscanf(yytext, "%s", yylval.name); return(KEYWORD);}
"break" {sscanf(yytext, "%s", yylval.name); return(KEYWORD);}
"int" {sscanf(yytext,"%s", yyval.name); return(BASIC);}
"float" {sscanf(yytext,"%s", yyval.name); return(BASIC);}
"bool" {sscanf(yytext,"%s", yyval.name); return(BASIC);}
{bool} {if(strcmp(yytext, "true") == 0){yylval.boolean = true;}else if(strcmp(yytext, "false") == 0){yylval.boolean = false;} return(BOOL);}
{alph}(_|{digit}|{alph})* {sscanf(yytext, "%s", yylval.name); return(ID);}
{digit}+ {yylval.num = atoi(yytext); return(NUM);}
{sign}{digit}+.{digit}+ {yylval.flnum = atof(yytext); return(REAL);}
[\t] {}
" " {}
[\n] {}
"+" {yylval.symbol = yytext[0]; return(OP);}
"-" {yylval.symbol = yytext[0]; return(OP);}
"*" {yylval.symbol = yytext[0]; return(OP);}
"/" {yylval.symbol = yytext[0]; return(OP);}
"==" {return(EQUAL);}
"!=" {return(NEQUAL);}
"=" {return(ASSIGN);}
")" {yylval.symbol = yytext[0]; return(SPECIAL);}
"{" {yylval.symbol = yytext[0]; return(SPECIAL);}
"}" {yylval.symbol = yytext[0]; return(SPECIAL);}
"(" {yylval.symbol = yytext[0]; return(SPECIAL);}
"]" {yylval.symbol = yytext[0]; return(SPECIAL);}
"[" {yylval.symbol = yytext[0]; return(SPECIAL);}
";" {yylval.symbol = yytext[0]; return(SPECIAL);}
(\'){alph}(\') {printf("<const, %s>", yytext);}
(\"){alph}{alph}+(\") {printf("<const, %s>", yytext);}
. {printf("error%s", yytext);}
%%
и сначала я запускаю flex scanner.l
, который создает lex.yy. c как и ожидалось, а затем я запускаю bison -dy scanner.y
, что вызывает ошибку:
scanner.y:1.1-7.2: syntax error, unexpected {...}
, которую я не понимаю. Я пробовал --debug
и -t
, но получил тот же результат.