我正在尝试使用给定的前缀编译一个简单的野牛解析器 - 已解决in this question。我使用Bison版本2.4.1和flex版本2.5.35(我不能使用bison 2.6)。我遇到了一个编译错误,让我在圈子里跑来跑去:
即:
make
Making all in src
make[1]: Entering directory `/stage/pool14/eholum/yacc_example/src'
/bin/sh ../ylwrap parcalc.y y.tab.c parcalc.c y.tab.h parcalc.h y.output parcalc.output -- bison -y -d -p="calcYY"
...yacc_example/src/parcalc.y:27.7-13: warning: type clash on default action: <result> != <>
conflicts: 4 shift/reduce
updating parcalc.h
gcc -DPACKAGE_NAME=\"calculator\" -DPACKAGE_TARNAME=\"calculator\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"calculator\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"calculator\" -DVERSION=\"1.0\" -I. -g -O2 -MT parcalc.o -MD -MP -MF .deps/parcalc.Tpo -c -o parcalc.o parcalc.c
parcalc.c:1053: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1061: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1064: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1067: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1089: error: expected identifier or ‘(’ before ‘=’ token
parcalc.y:75:21: error: lexcalc.c: No such file or directory
make[1]: *** [parcalc.o] Error 1
我目前正在使用automake,但如果我使用flex和bison构建然后尝试使用c进行编译,则会出现相同的错误。这是我的Makefile.am:
bin_PROGRAMS = calculator
AM_YFLAGS = -d -p="calcYY"
calculator_SOURCES = parcalc.y lexcalc.l
lex代码在lexcalc.l中(注意我使用%选项指定前缀,但是当我使用cl标志时出现相同的错误):
%{
#include <stdio.h>
#include "parcalc.h"
%}
%option noyywrap
%option prefix="yy"
%%
[ \t] ;
[0-9]+\.[0-9]+ {
yylval.flval = atof(yytext);
return FLOAT;
}
[0-9]+ {
yylval.inval = atoi(yytext);
return INT;
}
- { return MINUS; }
\+ { return PLUS; }
\n {
yylineno++;
return NEWLINE;
}
. ;
%%
Bison代码是parcalc.y:
%{
#include <stdio.h>
%}
%token INT FLOAT PLUS MINUS NEWLINE;
%union {
int inval;
float flval;
char oper;
char result[100];
}
%type <inval> INT;
%type <flval> calc FLOAT
%type <oper> PLUS MINUS;
%type <result> line;
%%
lines:
line lines
| line
;
line:
NEWLINE
| calc NEWLINE {
printf("Result = %f\n", $1);
}
;
calc :
calc PLUS calc {
($$ = $1 + $3);
}
| calc MINUS calc {
($$ = $1 - $3);
}
| INT {
($$ = $1);
}
| FLOAT {
($$ = $1);
}
;
%%
extern int calcYYparse();
extern FILE *calcYYin;
int main() {
FILE *myfile = fopen("infile.txt", "r");
if (!myfile) {
fprintf(stderr, "can't open infile.txt\n");
return 1;
}
calcYYin = myfile;
do {
calcYYparse();
} while (!feof(calcYYin));
return 0;
}
void calcYYerror(const char *s) {
fprintf(stderr, "Unrecognized format\n");
}
我应该注意到,当我丢弃前缀时,一切似乎都能正常工作,所以我猜测在生成的c文件中外部声明的内容有些不妥。仔细研究那些我还没能想到的东西。如果有人弄乱了多个解析器,并对如何使这些东西很好地融合在一起有一些见解,我会非常感激。
答案 0 :(得分:2)
感谢Michael发现前缀标志传递给bison编译器的问题。即
AM_YFLAGS = -d -p="calcYY"
与
AM_YFLAGS = -d -p"calcYY"
还有一点点相关的是前缀只会改变yyparse,yylex,yyerror,yynerrs,yylval,yylloc,yychar和yydebug。所以yyin不需要改变。
将一个例子倾倒到: