【问题标题】:Flex token order弹性代币订单
【发布时间】:2014-03-16 22:43:28
【问题描述】:

我在 flex 中声明以下标记时遇到问题:>、=、>、>=、

我这样声明:(flex)

ID          [_a-zA-Z][_a-zA-Z0-9]*

">"         {
                ultimo_token = ">";
                return BT_OP;
            }

"<"         {
                ultimo_token = "<";
                return LT_OP;
            }

"<<"        {
                ultimo_token = "<<";
                return ESQ_OP;
            }
">>"        {
                ultimo_token = "<<";
                return DIR_OP;
            }                               

"<="        {
                ultimo_token = "<=";
                return LE_OP;
            }

">="        {
                ultimo_token = ">=";
                    return GE_OP;
                }
">>="       {
                ultimo_token = ">>=";
                return DIR_ATRIBUICAO;
            }           

"<<="       {
                ultimo_token = "<<=";
                return ESQ_ATRIBUICAO;
                }

{ID}+       {
                ultimo_token = "IDENTIFICADOR ";
                ultimo_token += yytext;
                yylval.sval = new string(yytext) ;
                return IDENTIFICADOR;
            }

在野牛中它在这里不起作用:

expressao_relacional
    : expressao_shift { $$ = $1; }
    | expressao_relacional LE_OP expressao_shift { $$ = new NOperacaoBinaria($1, Operador::LE_OP, $3, $1->linha); }
    | expressao_relacional GE_OP expressao_shift { $$ = new NOperacaoBinaria($1, Operador::GE_OP, $3, $1->linha); }
    | expressao_relacional LT_OP expressao_shift { $$ = new NOperacaoBinaria($1, Operador::LT_OP, $3, $1->linha); }
    | expressao_relacional BT_OP expressao_shift { $$ = new NOperacaoBinaria($1, Operador::BT_OP, $3, $1->linha); }
    ;

在这样的代码示例中:if(a > b)。它忽略 > 并匹配而不是 IF '(' expression ')' where expression -> identifier 规则。但是有一个b标识符所以报错...

我用 -d 选项编写了测试扫描仪,它打印了这个:

--(end of buffer or a NUL)
--accepting rule at line 434 ("if")
if
--accepting rule at line 274 ("(")
(
--accepting rule at line 478 ("a")
a
--accepting rule at line 484 (" >> ")
--accepting rule at line 478 ("b")
b
--accepting rule at line 280 (")")
)
--accepting rule at line 484 (" ")
--accepting rule at line 446 ("then")
then
--accepting rule at line 484 ("
")
--accepting rule at line 248 ("{")
{
--accepting rule at line 484 ("

")
--accepting rule at line 259 ("}")
}
--(end of buffer or a NUL)
--accepting rule at line 484 ("
")
--(end of buffer or a NUL)
--EOF (start condition 0)

代码:if(a >>b) { }

[ <<EOF>>\0\t\v\r\n\f]+ ; /* eat up whitespace */

为什么?

...

谢谢你...

【问题讨论】:

  • 您需要显示更多的语法和/或扫描规则。 (例如,标识符的扫描器规则是什么?)另外,bison 是否报告任何冲突?
  • 看起来不错。例如,如果将“.”替换为“>”并测试一个 . b,它有效。它不工作 >>、、>=、= 和 >b) { }。似乎 flex 没有返回 "
  • flex 会给你任何警告吗?您是否尝试过使用-d 选项构建一个调试扫描器,它将为每个识别的令牌打印一条消息?
  • 我写了一个测试扫描器和这段代码:if (a >> b) then { },它打印了:if, (, a, b, then, {, }。
  • 当然是把+1识别为一个token。您的数字规则是 [+-]?0?{D}+,它明确允许 + 作为数字的一部分。

标签: c++ compiler-construction bison flex-lexer


【解决方案1】:

&lt;&lt;EOF&gt;&gt; 不是字符,它是一个特殊的弹性规则。所以你不能把它放在[...] 中,让它成为字符类的一部分。当您尝试这样做时,字母 &lt;&gt;EOF 将成为字符类的一部分。

无论如何,您几乎不需要&lt;&lt;EOF&gt;&gt; 规则,您当然不应该试图忽略它。

请记住,当多个模式具有相同的最长匹配时,flex 将在扫描器定义中使用 first 匹配模式。所以顺序很重要。除非您抑制或忽略 flex 的警告,否则它会告诉您您的 "&lt;""&lt;&lt;" 规则永远不会匹配,因为它们被错误的空白规则覆盖。阅读并尝试理解警告总是很重要的(或者至少询问它们的含义,尤其是当它们看起来相关时。)

根据您关于 EOF 匹配错误模式的评论,我怀疑您正在使用空匹配来触发错误条件。 不要那样做。 你的错误(默认)规则应该是定义中的最后一个,它应该匹配 .|\n(或者如果你确定 \n 会匹配 .总是被某些规则匹配。)这将捕获任何其他无法识别的单个字符,但不会在文件末尾触发,因为正如我之前所说,&lt;&lt;EOF&gt;&gt; 不是 一个字符。

【讨论】:

  • @brlebtag:我用 flex (2.5.35) 尝试过,它警告“duplrule.l:3:警告,规则无法匹配”。您是否使用-w 抑制了警告?或者你有一个很旧的 flex?
  • 我猜它是旧版本。 Makefile: lex.yy.c: lexico.l sintatico.tab.h flex lexico.l
猜你喜欢
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多