繁体   English   中英

前缀表示法的算术表达式语法(Java Cup)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM