[英]Arithmetic expression grammar in prefix notation (Java Cup)
我正在用前缀表示法为算术表达式编写语法。 但是在解析负数或减数时我遇到了一个问题。 语法示例是这样的:
precedence right +, -;
precedence right *, /;
precedence right uminus;
E ::= + E E
| - E E
| * E E
| / E E
| ( E )
| - E %prec uminus
| id
| digit
;
但是,如果我的输入是- 5 4
,它将5
减少为E
,接下来将其减少- E
(负数),然后解析器给出4
的语法错误。 正确的一个应该是5
作为E
,其次是4
作为E
,然后- EE
作为E
如何使用关联性解决此问题? 还是我需要重写语法?
(从评论中提升)
您的语法确实是模棱两可的,并且优先声明对您毫无帮助。
考虑输入包括以下各项的输入N
-
令牌,随后M
1
令牌。
- - - - - - - ... - 1 1 1 ... 1
为了使其成为表达式, -
令牌的M-1
必须是二进制的,其余N-(M-1)
一元的,但是无法分辨出哪一个(除非它们都是二进制的)。
即使你武断地说,第一N-(M-1)
-
s为一元,你看不出来的价值是什么N-(M-1)
直到你读完整个输入,这意味着你可以不用有限的前瞻进行解析。
但是,前缀表示法的全部要点是避免使用括号。 像上面这样的任意声明使它无法表示替代解释,因此某些表达式将无法用前缀表示法表示。 那是完全错误的。
这是一个简单的案例:
- 5 - - - 4 3 1
或者是
5 - (- (4 - (3 - 1)))
5 - ((- (4 - 3)) - 1)
5 - (((- 4) - 3) - 1)
在前缀表示法中,您需要声明每个运算符的“ arity”,或者隐式地声明(每个运算符都有已知数量的参数),或者显式地使用从Prolog借来的这种表示法:
-/2 5 -/2 -/2 -/1 4 3 1
另外,您可以使用强制括号来分隔参数,例如Lisp / Scheme“ s-exprs”:
(- 5 (- (- (- 4) 3) 1))
首先,删除所有优先级声明。 前缀语法中不需要它们。 实际上,这足以解决任何解析器生成器中的问题。 BTW,您使用的是哪一个?
杯子前瞻性有限。 正如@rici所指出的,在这种情况下无法解决歧义。 你可以做的是限制文法所以只是一个连续的一元-
可以使用。
B ::= E
| - E
;
E ::= + B B
| - B B
| * B B
| / B B
| ( B )
| id
| digit
;
由于我很生疏,请多次检查以上内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.