c-lexems中包含的运算符(bison/flex)



我很难弄清楚如何解决这个问题。基本上(这对任何运算符来说都是有价值的,但我用"+"作为例子),假设我们在lexer中有这个规则来源:

[+-]?[0-9]+  { yylval = atoi(yytext); return INTEGER; }

而且,在过去,我们会有

exp: INTEGER
| exp '+' exp  { $$ = $1 + $3; }
| // etc etc

然后,在生成的计算器中,如果我进行

2 + 2

它会按预期工作,并给我4号。

但如果我做

2+2

即在2、+和其他2之间没有空格,我有语法错误。原因是"+2"本身是一个令牌,所以bison读取"exp-exp",却找不到任何东西,因为它不是解析器规则的一部分。

但是,

2++2

很好,因为野牛做"2"+"+2"。

我的问题是……我们如何修复这种行为,使"2+2"与"2+2"的工作方式相同?


EDIT:正如下面的评论所指出的,这个问题似乎是另一个问题的重复。嗯,我已经找到了答案,但仍然如此。

如果我们把它作为解析器的工作,并为一元规则定义一个自定义的优先级,如下所示:

exp:
| // bla bla bla
| '+' exp %prec UPLUS { $$ = +$2; }
| '-' exp %prec UMINUS { $$ = -$2; }

我还是觉得有问题。事实上,从技术上讲,我们可以在计算器中做到这一点:

2+++++2
4
2+++++++++++2
4
2++++3
5

有没有办法避免这种丑陋的语法,并触发错误或至少警告,这样只允许2+2,更糟的是,只允许2+2+2和2++2,这是唯一有意义的两个选择!

谢谢!

一元运算符最好在语法中处理,而不是在扫描程序中处理。没有理由这么做。只允许在"primary"的生成中使用一元运算符"+"one_answers"-";忽略一元运算符"+";如果一元运算符的数量为奇数,则输出代码以否定操作数。

去掉[-+]?在lex规范中。目前,你似乎正在努力处理这两个问题。

也没有理由禁止一元运算符和它们的操作数之间的空格,或者只允许一个一元运算符,这就是在lexer中处理它所要做的。按照语法做。只有

最新更新