我正在尝试设置列号,以便在扫描仪失败时可以检索它。
我已经阅读了关于使用YY_USER_ACTION
在 [1] 处增加变量的技术,所以我认为我可以对我的可重入扫描器执行相同的操作,而是使用将扫描器作为参数的yyget_column
/宏。yyset_column
我的尝试是这样的(不包括我的 Lemon 语法/解析器,因为这纯粹是一个 Flex 问题):
%{
#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; }
%%
当这个 Lexer 在这个示例输入上失败时(不匹配的 '"',所以我的 lexer 将返回 -2)
foo = 1 && bar = 1.2 || b = "foo
然后yyget_column(myScanner)
将返回 4,当我期望像 35(输入结束)时。它似乎没有像我想象的那样积累。
所以我的问题是:使用可重入扫描仪,设置当前列号的正确方法是什么,以便在扫描失败时可以检索它?
非常感谢(这是我第一次使用词法分析器/解析器生成器)。
更新:我已经接近了一点。我添加了一个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);
上面提到的输入的输出是:
yyget_column(yyscanner): 0, yyget_leng(yyscanner): 3
yyget_column(yyscanner): 3, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 4, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 5, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 6, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 7, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 8, yyget_leng(yyscanner): 2
yyget_column(yyscanner): 10, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 11, yyget_leng(yyscanner): 3
yyget_column(yyscanner): 14, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 15, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 16, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 17, yyget_leng(yyscanner): 3
yyget_column(yyscanner): 20, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 21, yyget_leng(yyscanner): 2
yyget_column(yyscanner): 23, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 24, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 25, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 26, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 27, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 28, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 0, yyget_leng(yyscanner): 4
所以它累积得很好,但最后,似乎 Flex 将它重置为 0 :( 知道我如何防止/解决这个问题吗?在失败后获取列号特别有趣。
[1] http://oreilly.com/linux/excerpts/9780596155971/error-reporting-recovery.html