PythonNLTK:使用联合结构解析句子,进入无限递归

PythonNLTK:使用联合结构解析句子,进入无限递归,python,nltk,context-free-grammar,Python,Nltk,Context Free Grammar,我被要求为以下句子创建两个不同的解析树: foo while bar and baz 基于这两种结构: S-> S while S S-> S and S 我拥有的两棵不同的树如下: groucho_grammar = nltk.CFG.fromstring (""" S -> S U P | P U P P -> W U -> 'while' | 'and' W -> 'foo'|'bar'|'baz' """) 树A) 以下是A的代码: import

我被要求为以下句子创建两个不同的解析树:

foo while bar and baz
基于这两种结构:

S-> S while S
S-> S and S
我拥有的两棵不同的树如下:

groucho_grammar = nltk.CFG.fromstring ("""
S -> S U P | P U P
P -> W
U -> 'while' | 'and'
W -> 'foo'|'bar'|'baz'
""")
树A)

以下是A的代码:

import nltk

groucho_grammar = nltk.CFG.fromstring ("""
S -> P U S | P U P
P -> W
U -> 'while' | 'and'
W -> 'foo'|'bar'|'baz'
""")

print(groucho_grammar)

sentence = "foo while bar and baz"

rd_parser = nltk.RecursiveDescentParser(groucho_grammar)
for tree in rd_parser.parse(sentence.split()):
    print(tree)
A的结果是:

(S (P (W foo)) (U while) (S (P (W bar)) (U and) (P (W baz))))
树B)

对于第二部分,我只是将语法修改为:

groucho_grammar = nltk.CFG.fromstring ("""
S -> S U P | P U P
P -> W
U -> 'while' | 'and'
W -> 'foo'|'bar'|'baz'
""")
但我得到了无限递归错误:

    if isinstance(index, (int, slice)):
RuntimeError: maximum recursion depth exceeded in __instancecheck__
任何帮助都将不胜感激


谢谢。

你的问题是这条规则:
S->sup | pup

通过允许S以S的实例开始,您可以实现这种无限递归:

S -> S U P
S -> (S U P) U P
S -> ((S U P) U P) U P
S -> (((S U P) U P) U P) U P
这称为左递归,它是由符号扩展到自身引起的,在本例中,S扩展到S

从:

递归下降解析有三个关键缺点首先, 像NP->NP-PP这样的左递归产品将其发送到一个无限域中 循环。

解决方案

幸运的是,您可以简单地将所使用的解析器更改为不具有左递归弱点的解析器。简单的更改如下:

rd_parser = nltk.RecursiveDescentParser(groucho_grammar)
为此:

rd_parser = nltk.parse.chart.BottomUpLeftCornerChartParser(groucho_grammar)
这样您就可以使用左递归函数

进一步阅读

左递归问题在自动机理论中是众所周知的。有一些方法可以使语法非递归,如以下链接所述:


  • 非常感谢你。非常感谢。
    rd_parser = nltk.parse.chart.BottomUpLeftCornerChartParser(groucho_grammar)