NLTK CFG递归深度错误

时间:2016-08-28 00:44:11

标签: python nltk

import nltk   
from nltk.parse.generate import generate,demo_grammar   
from nltk import CFG   
grammar = CFG.fromstring("""   
ROOT -> S
S -> NP VP
NP -> NP PP
NP -> DT NN
DT -> 'The'
NN -> 'work'
PP -> IN NP
IN -> 'of'
NP -> DT NN
DT -> 'the'
NN -> 'painter'
VP -> VBZ ADJP
VBZ -> 'is'
ADJP -> JJ
JJ -> 'good'
""")    
print(grammar)   
for sentence in generate(grammar, n=100):   
   print(' '.join(sentence))

给出错误

RuntimeError: maximum recursion depth exceeded while calling a Python object

尝试改变functools.py中的隐蔽功能,仍然是同样的问题。

2 个答案:

答案 0 :(得分:3)

函数generate,作为其文档字符串状态,"生成来自CFG的所有句子的迭代器。"显然,它是通过按照语法中列出的顺序选择替代扩展来实现的。因此,第一次看到NP,它会使用规则NP -> NP PP对其进行扩展。它现在有另一个NP来扩展,它也会以相同的规则扩展......等等无限期,或者更确切地说,直到超出python的限制。

要解决您提供的语法问题,只需重新排序前两个NP规则,以便递归规则不是第一个遇到的规则:

grammar = CFG.fromstring("""   
ROOT -> S
S -> NP VP
NP -> DT NN
NP -> NP PP
DT -> 'The'
...
""")

这样做,发生器会产生大量完整的句子供你检查。请注意,更正的语法仍然是递归的,因此是无限的;如果生成足够多的句子,最终会达到相同的递归深度限制。

答案 1 :(得分:-1)

我试图对NP NN DT等的重复出现进行编号。由于唯一识别(我推测),似乎解决了这个问题。令我感到奇怪的是它应该在第一时间就是这样,即抛出的树木生产应该序列化词性。

import nltk   
from nltk.parse.generate import generate,demo_grammar   
from nltk import CFG   
grammar = CFG.fromstring("""
ROOT -> S   
S -> NP VP
NP -> NP1 PP
NP1 -> DT1 NN1
DT1 -> 'The'
NN1 -> 'work'
PP -> IN NP2
IN -> 'of'
NP2 -> DT2 NN2
DT2 -> 'the'
NN2 -> 'painter'
VP -> VBZ ADJP
VBZ -> 'is'
ADJP -> JJ
JJ -> 'good'
""")    
print(grammar)   
for sentence in generate(grammar, n=100):   
   print(' '.join(sentence))