繁体   English   中英

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

[英]Python NLTK: parse sentence using conjoint structure, getting into infinite recursion

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

foo while bar and baz

基于这两个结构:

S-> S while S
S-> S and S

我拥有的两种不同的树如下:

树 A)

     S
   / | \
  P  U  S
  |    /|\
  W   P U P  
      |   |
      W   W

这是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)

       S
     / | \
    S  U  P
  / | \    \
 P  U  P    W
 |     |
 W     W

现在对于 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 -> 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。

NLTK 书,第 8 章

递归下降解析有三个主要缺点。 首先,像 NP -> NP PP 这样的左递归产生式将其送入无限循环。

一个办法

幸运的是,您可以简单地将您使用的解析器更改为不共享左递归阿喀琉斯之踵的解析器。 简单改变这个:

rd_parser = nltk.RecursiveDescentParser(groucho_grammar)

对此:

rd_parser = nltk.parse.chart.BottomUpLeftCornerChartParser(groucho_grammar)

这样你就可以使用抗左递归的BottomUpLeftCornerChartParser

进一步阅读

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

  1. http://www.cs.engr.uky.edu/~lewis/essays/compilers/rec-des.html
  2. http://www.umsl.edu/~kjs9rc/CS4890/presentation.pdf
  3. http://research.microsoft.com/pubs/68869/naacl2k-proc-rev.pdf

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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