【问题标题】:Bison/yacc parser skipping grammer when not separated by space - "unexpected $end"Bison/yacc 解析器在不被空格分隔时跳过语法 - “意外的 $end”
【发布时间】:2020-05-11 15:52:39
【问题描述】:

您好,我有一个场景,如果有空格分隔语法,bison 将成功解析我的输入...

情况如下:我正在尝试声明一个变量:

int a = 31 ;

这个yyin解析成功

int a = 31;

解析不成功

我收到的错误是:

syntax error, unexpected $end, expecting TSEMI

这里是野牛代码部分

%token <string> TIDENTIFIER TINTEGER TDOUBLE
%token <token> TCEQUAL TCNE TCLT TCLE TCGT TCGE TASSIGN
%token <token> TLPAREN TRPAREN TLBRACE TRBRACE TCOMMA TDOT TSEMI
%token <token> TPLUS TMINUS TMUL TDIV

...

var_decl : ident ident TSEMI { $$ = new VarDel($1, $2); }
         | ident ident TASSIGN expr TSEMI {$$ = new VarDel($1, $2, $4);}
         ;

ident : TIDENTIFIER { $$ = new Var($1->c_str()); delete $1; }
      ;

expr : ident { $<ident>$ = $1; }
     | numeric
     ;

numeric : TINTEGER { $$ = new Num(atol($1->c_str())); delete $1; }
        | TDOUBLE { $$ = new Num(atof($1->c_str())); delete $1; }
        ;

这是我的 flex 文件的一部分


[ \t\n]                 ;
[a-zA-Z_][a-zA-Z0-9_]*  SAVE_TOKEN; return TIDENTIFIER;
[0-9]+.[0-9]*           SAVE_TOKEN; return TDOUBLE;
[0-9]+                  SAVE_TOKEN; return TINTEGER;
"="                     return TOKEN(TASSIGN);
"=="                    return TOKEN(TCEQUAL);
"!="                    return TOKEN(TCNE);
"<"                     return TOKEN(TCLT);
"<="                    return TOKEN(TCLE);
">"                     return TOKEN(TCGT);
">="                    return TOKEN(TCGE);
"("                     return TOKEN(TLPAREN);
")"                     return TOKEN(TRPAREN);
"{"                     return TOKEN(TLBRACE);
"}"                     return TOKEN(TRBRACE);
"."                     return TOKEN(TDOT);
","                     return TOKEN(TCOMMA);
"+"                     return TOKEN(TPLUS);
"-"                     return TOKEN(TMINUS);
";"                     return TOKEN(TSEMI);
"*"                     return TOKEN(TMUL);
"/"                     return TOKEN(TDIV);
.                       printf("Unknown token!n"); yyterminate();


为什么有空格解析成功,有空格解析不成功?

谢谢

【问题讨论】:

    标签: c++ parsing grammar bison flex-lexer


    【解决方案1】:

    [0-9]+.[0-9]* 应该是 [0-9]+\.[0-9]*。正如所写,它匹配31;

    您最好启用 flex 调试(-d 命令行标志)以查看它是如何标记化的。此外,使用atof 会默默隐藏令牌不是有效数字的事实。考虑使用更安全的字符串→数字转换器;你会在 C++ 标准库中找到一个;在 C 中,它将是 strtod,然后检查 endptr 是否位于末尾。 (您可以在词法分析器中进行这种转换,避免不必要的字符串分配和释放。)

    【讨论】:

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