LEX和YACC - 表达式中的空格

4

我正在读取一个文件,但是当我尝试使用像5+5这样的表达式时,出现了语法错误。然而,如果我写成5 + 5,它就可以正常工作。我对为什么会这样感到困惑?

这是我的词法分析器文件(我会省略主函数读取文件的部分):

%{

 #include "y.tab.h"
 #include "stdio.h"
 #include <stdlib.h>

%}
%%
(\/\*([^*]|(\*+([^*/]|[\r\n])))*\*+\/)+ {}
\/\/[^\n]*\n          {}
fd                    { return FD; }
[\r\t\n]+             {}
[ ]*                  {}
bk                    { return BK;}
setc                  {return SETC;}
[-+]?[0-9]+           { yylval = atoi(yytext); return NUMBER;}
fd[0-9]+              { }
rt                    {return RT;}
pink                  {return COLOR_TYPE;}
magenta               {return COLOR_TYPE; }
if                    {return IF; }
ifelse                {return IFELSE; }
\[                    {return LBRACKET; }
\]                    {return RBRACKET; }
\<                    {return LESS_THAN; }
\>                    {return GREATER_THAN; }
\+                    {return PLUS; }
\-                    {return MINUS; }
\/                    {return DIVIDE; }
\*                    {return MULT; }
\(                    {return LPAREN;}
\)                    {return RPAREN;}
\=                    {return EQ;}

%%

这是我 yacc 文件中处理表达式的一部分:
expr    : NUMBER     { printf("EXPR-->NUMBER: %d\n", $1);}
   |expr PLUS expr   {$$ = $1 + $3; printf("EXPR-->expression PLUS expression: %d\n", $$);}
   |expr DIVIDE expr {$$ = $1 / $3; printf("EXPR-->expression DIVIDE expression %d\n", $$);}
   |expr MULT expr   {$$ = $1 * $3; printf("EXPR-->expression MULTIPLY expression %d\n", $$);}
   |expr MINUS expr  {$$ = $1 - $3; printf("EXPR-->expression MINUS expression %d\n", $$);}
   |COLOR_TYPE       {printf("EXPR-->COLOR\n");}
   ;

问题会在词法分析文件中吗?
1个回答

6
分词器(词法分析器)返回给解析器的是 5+5。从你的语法(和逻辑上)来看,这是无效的。
我认为,更好的方法是修改你的词法分析器并将运算符规则提前。(至少在返回NUMBER规则之前)
编辑:经过一些思考(编辑 #2:并得到Jerry Coffin的非常有用的评论后),建议将NUMBER的词法规则更改为[0-9]+。为了使解析器仍然能够接受像“+123”或“-123”这样的输入,应该将以下内容添加到你的语法中:
%left PLUS MINUS ...
%right UNARY

%%

expr   : number
       | expr PLUS expr
      ...
       ;

number : PLUS NUMBER %prec UNARY {$$ = $2}
       | MINUS NUMBER %prec UNARY {$$ = -$2}
       | NUMBER 
       ;

这将允许在任何数字之前使用一元的+-,同时仍然使运算符+-具有更高的优先级。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接