我有一个PENN语法树,我想递归地得到这个树包含的所有规则。在
(ROOT
(S
(NP (NN Carnac) (DT the) (NN Magnificent))
(VP (VBD gave) (NP ((DT a) (NN talk))))
)
)
我的目标是获得如下语法规则:
^{pr2}$正如我所说的,我需要递归地执行此操作,而不需要NLTK包或任何其他模块或正则表达式。以下是我目前所掌握的情况。参数tree
是在每个空间上拆分的Penn树。在
def extract_rules(tree):
tree = tree[1:-1]
print("\n\n")
if len(tree) == 0:
return
root_node = tree[0]
print("Current Root: "+root_node)
remaining_tree = tree[1:]
right_side = []
temp_tree = list(remaining_tree)
print("remaining_tree: ", remaining_tree)
symbol = remaining_tree.pop(0)
print("Symbol: "+symbol)
if symbol not in ["(", ")"]:
print("CASE: No Brackets")
print("Rule: "+root_node+" --> "+str(symbol))
right_side.append(symbol)
elif symbol == "(":
print("CASE: Opening Bracket")
print("Temp Tree: ", temp_tree)
cursubtree_end = bracket_depth(temp_tree)
print("Subtree ends at position "+str(cursubtree_end)+" and Element is "+temp_tree[cursubtree_end])
cursubtree_start = temp_tree.index(symbol)
cursubtree = temp_tree[cursubtree_start:cursubtree_end+1]
print("Subtree: ", cursubtree)
rnode = extract_rules(cursubtree)
if rnode:
right_side.append(rnode)
print("Rule: "+root_node+" --> "+str(rnode))
print(right_side)
return root_node
def bracket_depth(tree):
counter = 0
position = 0
subtree = []
for i, char in enumerate(tree):
if char == "(":
counter = counter + 1
if char == ")":
counter = counter - 1
if counter == 0 and i != 0:
counter = i
position = i
break
subtree = tree[0:position+1]
return position
目前它适用于S
的第一个子树,但所有其他子树都不能递归地解析。很乐意为您效劳。。在
我倾向于让它尽可能的简单,不要尝试重新设计当前不允许使用的解析模块。比如:
输出
^{pr2}$注意
我把你原来的树改成这样:
似乎不正确,因为它在web上可用的语法树图示器上生成了一个空节点,因此我将其简化为:
根据需要进行调整。在
这可以用一种更简单的方式来完成。如果我们知道我们的语法结构是CNF-LR,我们可以使用递归正则表达式解析器来解析文本。在
有一个名为pyparser的包(如果您还没有,可以用
pip install pyparser
安装它)。在这给了
^{pr2}$因此,我们成功地将字符串转换为列表的层次结构。现在我们需要编写一些代码来解析列表和提取规则。在
正如我提到的,我们已经知道我们的语法结构,所以我们只需要注意有限的几个条件。在
按如下方式调用此函数:
输出:
你要什么就点这个。在
相关问题 更多 >
编程相关推荐