这是一个使用Flex的词法分析器。
#include <iostream>
#include <cstdio>
#define YY_DECL extern "C" int yylex()
#include "conv.tab.h"
using namespace std;
%}
eq [ \t]*=
%%
[ \t] ;
(?:POINT|LINE) { yylval.ename = strdup(yytext); return ENAME; }
x{eq} { yylval.xval = atof(yytext);
return XVAL; }
y{eq} { yylval.yval = atof(yytext);
return YVAL; }
. ;
%%
和其他文件是Bison语法文件
%{
#include <iostream>
#include <cstdio>
#include <stdio.h>
using namespace std;
extern "C" int yylex ();
extern "C" int yyparse (void);
extern "C" FILE *yyin;
extern int line_no;
void yyerror(const char *s);
%}
%union{
float xval;
float yval;
char *ename;
}
%token <ename> ENAME
%token XVAL
%token YVAL
%%
converter:
converter ENAME { cout << "entity = " << $2 << endl; }
| converter XVAL {// x -> xval = $2;
cout << "x value = " << endl; }
| converter YVAL {// y -> yval = $2;
cout << "y value = " << endl; }
| ENAME { cout << "entity = " << $1 << endl; }
| XVAL { cout << "xvalue " << endl; }
| YVAL { cout << "yvalue " << endl; }
%%
main() {
FILE *myfile = fopen("conv.aj", "r");
if (!myfile) {
cout << "I can't open file" << endl;
return -1;
}
yyin = myfile;
do{
yydebug = 1;
yyparse();
} while (!feof(yyin));
yydebug = 2;
}
void yyerror(const char *s) {
cout << "Parser error! Message: " << s << endl;
exit(-1);
}
实际上,我想从文件中检索值。我使用了Bison调试器,并了解到这些值无法推送到Bison Stack。所以基本上我想把这些值推送到stack.My文件中,就像这样: POINT x=38 y=47
发布于 2014-09-05 23:30:45
您的词法分析器中没有与数字匹配的内容,因此输入中的38
和47
都将由您的默认规则(. ;
)处理,这将导致它们被忽略。在XVAL
和YVAL
的规则中,您在yytext
上调用atoi
,它将是x=
(或y=
);这显然不是一个数字,atoi
可能会返回0
。
我不清楚您所说的“这些值不能推入Bison Stack”是什么意思,但我认为这个问题与bison或它的堆栈无关。
顺便说一下:
xval
和yval
的语义类型中有两个不同的成员。该类型是一个union
,而不是一个struct
,所以拥有两个相同类型(float
)的成员是不会执行正则表达式捕获的。因此,避免使用(?:...)
进行捕获是没有意义的;它只会模糊您的语法。你也可以使用:POINT|LINE:{ yylval.ename = strdup(yytext);return ENAME;}
另一方面,您最好定义两种不同的令牌类型,这样可以避免对strdup
的需要。(您似乎没有对重复的字符串执行free
操作,因此strdup
也是一个内存泄漏。)或者,您可以在语义类型中使用枚举值:
POINT { yylval.ename_enum=POINT;return ENAME;}行{ yylval.ename_enum=LINE;return ENAME;}
. ;
实际上不是一个好主意,特别是在开发期间,因为它会隐藏错误(比如您有的错误)。你可以使用%option nodefault
来避免flex
的默认规则,然后当一个非法的字符是flex时,flex会显示一个错误。如果你使用的是非常旧的bison
和flex
版本,你可以将生成的代码编译成c++
。https://stackoverflow.com/questions/25680020
复制相似问题