Python 从解析树中提取乔姆斯基范式语法

Python 从解析树中提取乔姆斯基范式语法,python,grammar,nltk,parse-tree,chomsky-normal-form,Python,Grammar,Nltk,Parse Tree,Chomsky Normal Form,我试图从一个句子的解析树中提取乔姆斯基范式(CNF)-语法产物: (ROOT (S (NP (DT the) (NNS kids)) (VP (VBD opened) (NP (DT the) (NN box)) (PP (IN on) (NP (DT the) (NN floor)))))) 我将整个树放入一个名为S的字符串中,然后: tree = Tree.fromstring(S) tree.chomsky_normal_fo

我试图从一个句子的解析树中提取乔姆斯基范式(CNF)-语法产物:

(ROOT
  (S
    (NP (DT the) (NNS kids))
    (VP (VBD opened)
      (NP (DT the) (NN box))
      (PP (IN on)
        (NP (DT the) (NN floor)))))) 
我将整个树放入一个名为S的字符串中,然后:

tree = Tree.fromstring(S)
tree.chomsky_normal_form()
for p in tree.productions():
    print p
输出是

(1) NN -> 'box'
(2) PP -> IN NP
(3) DT -> 'the'
(4) ROOT -> S
(5) NP -> DT NN
(6) VBD -> 'opened'
(7) VP|<NP-PP> -> NP PP
(8) VP -> VBD VP|<NP-PP>
(9) NP -> DT NNS
(10) NN -> 'floor'
(11) IN -> 'on'
(12) NNS -> 'kids'
(13) S -> NP VP
(1)NN->“盒子”
(2) NP中的PP->
(3) DT->“the”
(4) 根->S
(5) NP->DT-NN
(6) VBD->“已打开”
(7) VP |->NP PP
(8) VP->VBD VP|
(9) NP->DT NNS
(10) NN->“地板”
(11) 在->“on”中
(12) NNS->“儿童”
(13) S->NP VP
但有些作品(7号和8号)似乎不是CNF!有什么问题吗?

VP |
是一个非终结符号。竖条并不意味着传统意义上的多个选项。相反,NLTK把它放在那里是为了表明规则的来源,即“这个新的非终结符号是从VP和NP-PP的组合中派生出来的。”它是NLTK创建的一个新的产生式规则,用于将语法转换为乔姆斯基范式

看看这棵树的制作,在CNF之前:

ROOT -> S
S -> NP VP
NP -> DT NNS
DT -> 'the'
NNS -> 'kids'
VP -> VBD NP PP ***
VBD -> 'opened'
NP -> DT NN
DT -> 'the'
NN -> 'box'
PP -> IN NP
IN -> 'on'
NP -> DT NN
DT -> 'the'
NN -> 'floor'
具体来说,请查看规则
VP->VBD NP PP
,它不在CNF中(任何生成规则的RHS上必须正好有两个非终结符)

你问题中的两条规则(7):
VP |->NP-PP
和(8):
VP->VBD-VP
在功能上等同于更一般的规则
VP->VBD-NP-PP

当检测到
VP
时,规则应用程序将导致:

VBD VP |

并且,
VP |
是创建的产生式规则的LHS,其结果是:

VBD NP PP

具体地说,如果隔离规则本身,可以查看特定符号(实际上是单数):

>>tree.chomsky\u normal\u form()
>>>prod=tree.productions()
>>>x=prod[7]#VP |->NP-PP
>>>x.lhs().symbol()#单数!
u'VP |'

那么,我如何区分表示或(始终在RHS上)的条形图和不表示或且可能同时出现在RHS和LHS上的条形图(如您所述)?在什么上下文中,您需要“区分”它们?在最基本的级别上,在LHS上输入非终结符符号(如
VP |
)将抛出错误,因为符号中不应包含空格。还要认识到规范
A->B|C
是更正式的
A->B
A->C
的简写。事实上,NLTK将这些规则分解为它们的组成形式,因此除了手动输入类似
A->B|C
的规则外,您不会发现出现了表示“多个选项”的
在NLTK语法中。试试
nltk.CFG.fromstring(“A->B | C”)
,它创建了一个包含两个产生式规则的语法。我正在尝试实现需要CNF的CKY算法。
在处理nltk时是明确的-您原始帖子中的语法确实是有效的CNF。如果要创建解析这些产品的脚本,请确保它考虑到
并不意味着“多个选项”。
>>> tree.chomsky_normal_form()
>>> prod = tree.productions()
>>> x = prod[7]  # VP|<NP-PP> -> NP PP
>>> x.lhs().symbol()  # Singular!
u'VP|<NP-PP>'