c - 设置/获取可重入 Flex 扫描仪的列号

标签 c flex-lexer lexer

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

我已经阅读了有关使用 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; }

%%

当此词法分析器在此示例输入上失败时(“””不匹配,因此我的词法分析器将返回 -2)

foo = 1 && bar = 1.2 || b = "foo

那么yyget_column(myScanner)将返回4,而我期望的是类似35(输入结束)的结果。看来它并没有像我想象的那样积累。

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

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

更新:我已经更接近了。我向 YY_USER_ACTION 添加了 printf 来调试累积,如下所示:

#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

最佳答案

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

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

所以,我现在很高兴:)

关于c - 设置/获取可重入 Flex 扫描仪的列号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18304455/

相关文章:

更改函数中的变量无效

c - Flex 不识别标识符

visual-c++ - vc++下编译bison和flex程序时unistd.h相关困难

c - 如何直接从词法分析器返回 '+'(不带 token )

xml - 解析器与词法分析器和 XML

c - Makefile编译错误

c - 指针的烦恼

python - 如何使用 C 程序的 python 回调设置参数值

c - flex 如何识别子字符串?

c++ - 柔性 : trying to generate a C++ lexer using Flex; "unrecognized rule" error