我正在使用flex 2.5.35和bison 2.7(虽然这是一个flex问题,我相信,所以我省略了parser.y)
我的Flex语法非常简单:
lexer.l
%{
#define YY_NO_INPUT
#include "parser.h"
#define YY_USER_ACTION yylloc->first_line = yylloc->last_line = yylineno; \
yylloc->first_column = yycolumn; yylloc->last_column = yycolumn + (int)yyleng - 1; \
yycolumn += (int)yyleng;
%}
%option yylineno
%option outfile="lexer.c" header-file="lexer.h"
%option warn
%option reentrant noyywrap never-interactive nounistd
%option nounput
%option bison-bridge
%option bison-locations
%%
[ \n\r\t]* { /* Skip blanks. */ }
[A-Za-z0-9_\-@]+ { yylval->value = strdup(yytext); return TOKEN_VAR; }
"&&" { return TOKEN_AND; }
"||" { return TOKEN_OR; }
"!" { return TOKEN_NOT; }
"(" { return TOKEN_LPAREN; }
")" { return TOKEN_RPAREN; }
%%
扫描字符串时,行号和列号的值是未初始化的垃圾。我遍历了代码,并在生成的lexer.c中将以下行添加到yy_scan_buffer中:
b->yy_bs_lineno = 1;
b->yy_bs_column = 1;
现在价值符合预期。
这是一个错误吗? yy_create_buffer
正确初始化这些字段,但yy_scan_buffer
没有。
解析字符串时,我不能使用%option yylineno
吗?
是否有解决方法,或者我是否真的需要修改生成的lexer.c?
答案 0 :(得分:3)
是的,我可以证实,这是野牛的问题。它发生在我身上,我通过在“编译器功能”中初始化它来修复它
void myParseFunction(const char* code, ...){
yyscan_t myscanner;
yylex_init(&myscanner);
struct yyguts_t * yyg = (struct yyguts_t*)myscanner;
yy_delete_buffer(YY_CURRENT_BUFFER,myscanner);
yy_scan_string(code, myscanner);
// [HACK] Those are not properly initialized for non file parsers
// and becuase of that we get garbage in yyerror...
yylineno = 1;
yycolumn = 0;
bool nasi = yyparse(myscanner, <your_args>);
yylex_destroy(myscanner);
return nasi;
}
请注意,yylineno和yycolumn可以与重入解析器一起使用,因为它们被定义为引用“yyg”的marcos。
答案 1 :(得分:1)
您可以将{YY_USER_ACTION代码'从oreilly book
中的“将位置添加到Lexer”部分复制我相信你忘了在定义YY_USER_ACTION之前添加int yycolumn = 1;
,因为它是在链接的代码示例中完成的。