2

我正在尝试设置列号,以便在扫描仪失败时可以检索它。

我已经阅读了关于使用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(输入结束)时。它似乎没有像我想象的那样积累。

所以我的问题是:使用可重入扫描仪,设置当前列号的正确方法是什么,以便在扫描失败时可以检索它?

非常感谢(这是我第一次使用词法分析器/解析器生成器)。

更新:我已经接近了一点。我添加了一个printfYY_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

4

1 回答 1

2

我要继续回答自己:“问题”是因为我的测试输入发生的事情是扫描仪意外到达带引号的字符串内的输入末尾(我的规则<<EOF>>应该匹配),并且此时 Flex 自然会重置扫描仪,包括累积的列号。

我现在意识到这是一种特殊情况,此时列号并没有真正的意义。它适用于我的其他错误情况(无法识别的字符,我返回 -1)。

所以,我现在很开心:)

于 2013-08-18T23:23:20.643 回答