这个生产规则是否是递归的?

时间:2016-12-31 01:54:51

标签: compiler-construction antlr formal-languages

我对形式语言和编译器理论的了解有限。所以我正在通过 Terence Parr 的书The Definitive ANTLR 4 Reference学习。

在书中,它说:

  

现在,使用v4,您可以将表达式与看起来像的规则匹配   这样:

expr : expr '*' expr // match subexpressions joined with '*' operator
     | expr '+' expr // match subexpressions joined with '+' operator
     | INT           // matches simple integer atom
     ;
     

像expr这样的自引用规则是递归的,特别是,   左递归,因为它至少有一个替代品   指自己。

但我认为大胆的部分是不正确的。如果右侧最左边的符号与左侧的非终端符号相同,则生成为here,生成为左递归。例如,

    expr → expr + term.

回到Terence的书中,既没有递归也没有递归。它只是递归的。

我是对的吗?或者我误解了作者?

ADD 1

感谢目前为止的回复。对不起,我没有让自己清楚。

我的理解是:left-recursive表示右侧的left-most部分与左侧的非终端相同。 AND 右侧的剩余部分是后缀 NOT 左侧。

在Parr的书籍样本中,右侧的重新部分不是后缀,而是另一个 expr,所以我不# 39;认为严格符合左递归规则。

2 个答案:

答案 0 :(得分:1)

让我们比较一下这本书给出的左递归规则的例子:

expr → expr + term.

使用您正在检查的复合规则的第一部分:

expr : expr '*' expr // match subexpressions joined with '*' operator

这里左侧是expr;右侧是expr '*' expr,右侧最左侧的符号是expr。由于右侧最左边的符号expr与左侧的符号相同,也是expr,因此规则的这一部分是递归的。

复合规则的第二部分也将是左递归的,原因相同:

expr : expr '+' expr

复合规则的第三部分不是递归的,因为INT是一个原子:

expr : INT           // matches simple integer atom

当您使用expr运算符将|的这三个不同表达式合并为一个表达式时,您会在问题中得到原始表达式:

expr : expr '*' expr // match subexpressions joined with '*' operator
     | expr '+' expr // match subexpressions joined with '+' operator
     | INT           // matches simple integer atom
     ;

其中,由于其三个选项中至少有一个是左递归的,因此本身是左递归的。

答案 1 :(得分:1)

“如果右侧最左边的符号与左侧的非终端符号相同,则生产是递归的。”

在您的示例中,“expr - > expr + term”右侧最左侧的符号为“expr”,左侧的非终端符号为“expr”,因此它们是相同的。制作是左递归的。您的替代品是“expr * expr”和“expr + expr”没有区别;你的定义仍然是左递归的。

如果您认为您正在创建解析器来解析此语言,那么您将拥有一个名为“parseExpr”的函数来解析“expr”。根据定义,为了评估“expr +(anything)”,首先必须做的是解析“expr”。因此它应该调用函数来解析“expr”,这当然是本身。这基本上就是左递归的意思。