【问题标题】:Bison Flex cannot access first token in bison rule sectionBison Flex 无法访问野牛规则部分中的第一个令牌
【发布时间】:2012-10-30 02:13:47
【问题描述】:

弹性:

%option noyywrap
%{
    #include "syntax.hpp"
    #include <cstdlib>
    extern "C" int isatty(int);
%}
%%

\#.*                                                {}
\[[A-Za-z_]*\]                                      {yylval.val_char=yytext; return SECTION_NAME;}
[A-Z_a-z[:digit:]]*[A-Z_a-z][A-Z_a-z[:digit:]]*     {yylval.val_char=yytext ;return OPTION_NAME;}
\n                                                  {}
=\".*?\"                                            {yylval.val_char=yytext+1; return VALUE_STRING;}
=[ A-Z_a-z[:digit:]]*[A-Z_a-z][A-Z_a-z[:digit:] ]*  {yylval.val_char=yytext+1; return VALUE_ENUM;}
=[ [:digit:] ]*                                     {yylval.val_int=atoi(yytext+1); return VALUE_INTEGER;}
=[ [:digit:]\.[:digit:]]+                           {yylval.val_float=atof(yytext+1); return VALUE_FLOAT;}


" "                                                 {}
%%

野牛:

%{
    #include <iostream> 
    int yylex();
    int yyerror(const char *p) {return 0;}

%}

     %union  {
            float val_float;
            int val_int;
            char* val_char;
           };   
     %token <val_char> SECTION_NAME
     %token <val_char> OPTION_NAME
     %token <val_int> VALUE_INTEGER
     %token <val_float> VALUE_FLOAT
     %token <val_char> VALUE_STRING
     %token <val_char> VALUE_ENUM

%%
    input
        :input line
        |line
        ;
    line
       :section
       |value
       ;


    section
        :SECTION_NAME {std::cout<<$1; std::cout<<std::endl;}
        ;

    value
        :OPTION_NAME VALUE_INTEGER  {std::cout<<$1, std::cout<<std::endl;}
        |OPTION_NAME VALUE_FLOAT {std::cout<<$1; std::cout<<std::endl;}
        |OPTION_NAME VALUE_ENUM {std::cout<<$1; std::cout<<std::endl;}
        |OPTION_NAME VALUE_STRING {std::cout<<$1;std::cout<<std::endl;}
        ;
%%

我正在尝试测试小型 ini 配置文件解析器。它必须解析 option=value 对,其中 value 可以是 int、float、带引号的字符串或枚举常量。此代码应将文件中的 SECTION_NAMEs 和 OPTION_NAMEs 提供给控制台输出。但事实并非如此。相反,它会打印整个文件。如果我将 $1 更改为 $2,它可以正常工作并打印 SECTION_NAMEs 和 VALUES。它出什么问题了?如何访问 OPTION_NAME 令牌值?提前致谢。

UPD。 Flex 部分工作正常。 {printf(yylval.val_char); return OPTION_NAME;} 为控制台提供正确的令牌值。可能是野牛部分的问题。

【问题讨论】:

    标签: parsing bison lex flex-lexer


    【解决方案1】:

    问题是您将指针返回到 yytext 以获取令牌语义值。 yytext 是 flex 用于匹配令牌的内部缓冲区,它仅在下次调用 yylex 以读取下一个令牌之前有效。因此,您的语义值($1 等)最终都会成为指向缓冲区的悬空指针,该缓冲区将被来自以后令牌的更多令牌数据覆盖。

    您需要将字符串从yytext 复制到一些可用时间更长的存储中。 strdup 对此非常有用:

    \[[A-Za-z_]*\]                                      {yylval.val_char=strdup(yytext); return SECTION_NAME;}
    [A-Z_a-z[:digit:]]*[A-Z_a-z][A-Z_a-z[:digit:]]*     {yylval.val_char=stdrup(yytext); return OPTION_NAME;}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多