涉及大括号的语法

Abh*_*raj 3 prolog left-recursion dcg

我正在尝试解决序言中的 DCG 语法并在一定程度上取得了成功,但我一直在评估涉及此类大括号的表达式。\nexpr( T, [\xe2\x80\x99(\xe2\x80\x99, 5, +, 4, \xe2\x80\x99)\xe2\x80\x99, *, 7], []),

\n\n
expr(Z) --> num(Z).\nexpr(Z) --> num(X), [+], expr(Y), {Z is X+Y}.\nexpr(Z) --> num(X), [-], expr(Y), {Z is X-Y}.\nexpr(Z) --> num(X), [*], expr(Y), {Z is X*Y}.\nnum(D) --> [D], {number(D)}.\n\neval(L, V, []) :- expr(V, L, []).\n
Run Code Online (Sandbox Code Playgroud)\n

Nic*_*rey 5

Prolog 的 DCG 语法实现的解析器是递归下降 LL( something )(预测)语法。它从左到右遍历输入并生成最左推导。它们很容易制作,但语法必须符合一些限制:

它们不能是左递归的。可以/将会产生无限递归。这意味着在遵循递归路径之前必须从输入流中删除至少一个符号(令牌)。重构语法以消除左递归是一项相当机械的练习,尽管很乏味。请参阅任何不错的编译器书籍来了解如何做到这一点。

运算符优先级通常内置于语法本身的结构中。下面的 BNF 表示法显示了一种定义递归下降语法以解析/评估简单算术表达式的方法:

ArithmeticExpression     : AdditiveExpression
                         ;

AdditiveExpression       : MultiplicativeExpression
                         | MultiplicativeExpression '+' AdditiveExpression
                         | MultiplicativeExpression '-' AdditiveExpression
                         ;

MultiplicativeExpression : ExponentialExpression
                         | ExponentialExpression '*' MultiplicativeExpression
                         | ExponentialExpression '/' MultiplicativeExpression
                         | ExponentialExpression '%' MultiplicativeExpression
                         ;

ExponentialExpression    : UnaryExpression
                         | UnaryExpression '^' ExponentialExpression
                         ;

UnaryExpression          : '-' UnaryExpression
                         | AtomicExpression
                         ;

AtomicExpression         : '(' ArithmeticExpression ')'
                         | ['0'..'9']+
                         ;
Run Code Online (Sandbox Code Playgroud)

每个运算符优先级级别的术语都是根据下一个更高优先级的表达式构建的。所以任意算术表达式只是一个单一的加法表达式。

每个加法表达式是 1 个或多个乘法表达式,由加法和减法运算符连接。

每个乘法表达式是 1 个或多个指数表达式,由乘法、除法和余数运算符连接。

每个指数表达式都是一个一元表达式,带有一个选项指数运算符,后跟另一个一元表达式。

每个一元表达式要么是原子表达式,要么是一元减号后跟另一个一元表达式。

每个原子表达式要么是括在括号中的任意算术表达式,要么是无符号整数标记。

将以上内容翻译成 Prolog 的 DCG 语法应该很简单。如何评价语法中每个子句所代表的术语应该是不言而喻的。

  • 上面的语法不正确。您无法解析 1 + 2 + 3,因为 MultiplicativeExpression 与 AdditiveExpression 之间缺少某些链接。所以我必须投票反对你。因此,与您所写的“每个加法表达式是 1 个或多个乘法表达式,由加法和减法运算符连接”相反。语法不会这样做。它最多仅涵盖 1 个附加乘法表达式。 (2认同)
  • 如果你正确地修正了语法,那么短语“将上述内容翻译成 Prolog 的 DCG 语法应该是微不足道的”。可能不会再坚持下去了。因此,人们将不得不回归到“重构语法以消除左递归是一项相当机械的练习,尽管很乏味。” 这使得你的整个帖子有点不一致。 (2认同)
  • 您写道“在 Prolog 中,您将必须从头开始连接 Packrat 解析器”,我不知道,许多 Prolog 都有表格,并且通过断言进行表格也不是那么困难。然后,您可以将制表和 DCG 结合起来。只是想法,必须检查一次详细信息。我提到制表是因为我想指出重构并不是处理左递归的唯一方法,制表是另一种方法。 (2认同)