我正在尝试设置列号,以便在扫描仪发生故障时可以检索它。
我已经读过使用YY_USER_ACTION
在[1]处增加变量的技巧,所以我认为我可以对我的可重入扫描程序执行相同的操作,而是使用yyget_column
/ { {1}}以扫描程序为参数的宏。
我的尝试就是这个(不包括我的Lemon语法/解析器,因为这纯粹是一个Flex问题):
yyset_column
当这个Lexer在这个示例输入上失败时(不匹配'“',所以我的词法分析器将返回-2)
%{
#include "BooleanParser.h"
#define YY_USER_ACTION yyset_column(yyget_column(yyscanner) + yyget_leng(yyscanner), yyscanner);
%}
%option outfile="BooleanScanner.cpp" header-file="BooleanScanner.h"
%option reentrant
%option noyywrap
%option yylineno
%x DOUBLE_QUOTED
%%
[ \t] {}
\n { return NL; }
"||" { return OR; }
"&&" { return AND; }
"<" { return LT; }
">" { return GT; }
"=" { return EQ; }
"!=" { return NEQ; }
"(" { return LPAREN; }
")" { return RPAREN; }
"true" { return TRUE; }
"false" { return FALSE; }
[0-9]+ { return INT; }
[0-9]+\.[0-9]+ { return FLOAT; }
[A-Za-z_][A-Za-z0-9]* { return ID; }
["] { BEGIN(DOUBLE_QUOTED); }
<DOUBLE_QUOTED>[^"]+ {}
<DOUBLE_QUOTED>["] { BEGIN(INITIAL); return STRING; }
<DOUBLE_QUOTED><<EOF>> { return -2; }
. { return -1; }
%%
然后foo = 1 && bar = 1.2 || b = "foo
将返回4,当我期望类似35(输入结束)时。它似乎没有像我想象的那样累积。
所以我的问题:使用可重入扫描程序,设置当前列号的正确方法是什么,以便在扫描失败时可以检索它?
非常感谢(这是我第一次使用词法分析器/解析器生成器)。
更新:我离得更近了。我在yyget_column(myScanner)
添加了printf
来调试累积,如下所示:
YY_USER_ACTION
上面提到的输入输出是:
#define YY_USER_ACTION \
printf("yyget_column(yyscanner): %i, yyget_leng(yyscanner): %i\n", yyget_column(yyscanner), yyget_leng(yyscanner)); \
yyset_column(yyget_column(yyscanner) + yyget_leng(yyscanner), yyscanner);
所以它积累得很好,但最后,似乎Flex将其重置为0 :(任何想法我怎么能阻止/解决这个问题?在失败后获取列号特别有趣。
[1] http://oreilly.com/linux/excerpts/9780596155971/error-reporting-recovery.html
答案 0 :(得分:1)
我将继续回答自己:“问题”是因为我的测试输入发生的事情是扫描程序意外地在引用字符串内输入结束(我的规则是{{1}如此匹配),此时Flex自然地重置扫描仪,包括累积的列号。
我现在意识到这是一个特殊情况,此时列号并没有多大意义。它适用于我的其他错误条件(无法识别的字符,我返回-1)。
所以,我现在很开心:)。