Flex令牌订单

时间:2014-03-16 22:43:28

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

我在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&gt; b)。它忽略了&gt;并匹配而不是IF'('expression')'where expression - &gt;标识符规则。但是有一个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&gt;&gt; b){}

&LT;&LT;符合此规则:

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

为什么?

...

thx rici ...

1 个答案:

答案 0 :(得分:1)

<<EOF>>不是一个角色,它是一个特殊的弹性规则。所以你不能把它放在[...]里面,使它成为一个字符类的一部分。当您尝试这样做时,字母<>EOF将成为角色类的一部分。

无论如何,你几乎不需要<<EOF>>规则,你当然不应该试图忽略它。

请记住,当多个模式具有相同的最长匹配时,flex将在扫描程序定义中使用第一个匹配模式。订单很重要。除非你压制或忽略了flex的警告,否则它会告诉你,你的"<""<<"规则永远不会匹配,因为它们被错误的空格规则所覆盖。阅读并尝试理解警告总是很重要(或者至少询问它们的含义,特别是当它们看起来相关时。)

根据您对EOF匹配错误模式的评论,我怀疑您使用空匹配来触发错误情况。 不要这样做。您的错误(默认)规则应该是定义中的最后一个规则,如果您确定,它应该与.|\n匹配(或仅. \n将始终与某些规则匹配。)这将捕获任何其他无法识别的单个字符,但不会被文件末尾触发,因为正如我之前所说,<<EOF>>不是一个角色。

相关问题