编辑:错误是这一行 if len(rhs) == 2 and rhs[0] in T[i][k] and rhs[1] in T[k + 1][j]:
我能够基于cky解析器Wiki,使用少量规则,终端和非终端来实现cky算法。但是我将其缩放为具有更多规则,单词,语法,现在它给了我。
IndexError: list index out of range
有人对更大的语法集有什么误解吗?
如果有帮助的话,这是以前较小的语法规模。
non_terminals = ["NP", "Nom", "Det", "AP",
"Adv", "A"]
terminals = ["book", "orange", "man",
"tall", "heavy",
"very", "muscular"]
# Rules of the grammar
R = {
"NP": [["Det", "Nom"]],
"Nom": [["AP", "Nom"], ["book"],
["orange"], ["man"]],
"AP": [["Adv", "A"], ["heavy"],
["orange"], ["tall"]],
"Det": [["a"]],
"Adv": [["very"], ["extremely"]],
"A": [["heavy"], ["orange"], ["tall"],
["muscular"]]
}
这是我的方法
def cykParse(w):n = len(w)
# Initialize the table
T = [[set([]) for j in range(n)] for i in range(n)]
# Filling in the table
for j in range(0, n):
# Iterate over the rules
for lhs, rule in R.items():
for rhs in rule:
# If a terminal is found
if len(rhs) == 1 and rhs[0] == w[j]:
T[j][j].add(lhs)
for i in range(j, -1, -1):
# Iterate over the range i to j + 1
for k in range(i, j + 1):
# Iterate over the rules
for lhs, rule in R.items():
for rhs in rule:
# If a terminal is found
if len(rhs) == 2 and rhs[0] in T[i][k] and rhs[1] in T[k + 1][j]:
T[i][j].add(lhs)
# If word can be formed by rules
# of given grammar
if len(T[0][n-1]) != 0:
print("True")
else:
print("False")
我猜(因为你没有显示表明错误发生在哪里的实际错误),它在这一行中:
if len(rhs) == 2 and rhs[0] in T[i][k] and rhs[1] in T[k + 1][j]:
那k
就是n-1
。如果前两个条件为真,则第三个条件将执行并爆炸。
我怀疑的迭代限制中存在一个错误的错误k
。一些代码注释会很有用,或者至少是对实现所基于的伪代码的引用。
抱歉,错误在哪里,我将其添加到问题中。我将继续尝试找出如何更改它以使该行正常工作
@john:您从哪里获得算法的?(即“ cky解析器Wiki”的实际链接。您也许在谈论Wikipedia?)
是的,我是从en.wikipedia.org/wiki/CYK_algorithm实施它的,有些事情我不知道该怎么做,所以才改变了它。
@约翰:好的。检查您的计算是否有的迭代限制
k
。我认为这是一个问题。我解决了这个问题,k限制就是问题,在检查以确保它没有超出范围之前,我添加了另一个条件