递归遍历语法树



我有一个语法解析的句子。例如,"我妈妈想做饭"。解析是[('我的', 1(, ('妈妈', 2(, ('想要', -1(, ('to',2(, ('cook', 3(]。数字表示单词所依赖的项目的索引:"mom"取决于"wants","wants"是数组的第二个元素(像往常一样从零开始(。"想要"有"-1",因为这是句子的核心,它不依赖于其他任何东西。我需要在这里获得"我妈妈"的主题。我该怎么做?

到目前为止,我只尝试编写并非在所有情况下都有效的循环。交易是主题可以由 2 个以上的单词组成,并且该数字未定义。像这样的东西...

"价值观"是[("我的",1(,("妈妈",2(,("想要",-1(,("到",2(,("厨师",3(]

for indx, value in enumerate(values):
m = morph.parse(value[0])
if isinstance(m, list):
m = m[0]
if 'NOUN' in m.tag:
if value[1] == str(index[0]): #it checks if the word (part of the subject) depends on the verb
terms.append([value[0], indx])
if len(terms) > 0:
term = terms[0][0]
t = []
for indx, value in enumerate(values):
if value[1] == str(terms[0][1]): #it checks if the word depend on the found part of the subject
m = morph.parse(value[0])
if isinstance(m, list):
m = m[0]
if 'NOUN' in m.tag:
t.append([value[0], terms[0][0]])

该算法应该像这样工作:遍历整个数组,并在找到给定单词的所有依赖项以及这些依赖项的所有依赖项时停止。(在示例中,"mom"的所有依赖项(。请帮忙!

抱歉,我花了这么长时间才回复您。
我终于想通了。代码在底部,但我将首先解释它是如何工作的:

调用parse(values)时,它会遍历值中的句子,并为每个单词调用递归getDepth。 "getDepth"计算给定单词和动词之间的单词关系数。
例如,对于"The",深度是1,因为它直接调用动词。
对于"King",它是2,因为"King"调用"The","The"调用动词(其中call =有一个指向某个单词的指针(


计算完所有深度后,parse找到深度最高的单词("France"(,并使用递归traceFrom()将主题串在一起。


你真正关心的只是parse()它接受预解析的字符串,如[('我的',1(,('妈妈',2(,('wants',-1(,('to',2(,('cook',3(]并吐出完整的主题。适用于这两个示例,但您应该进行更多测试。

values = [('The', 4), ('King', 0), ('of', 1), ('France', 2), ('died', -1)]
#values = [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)]
def getDepth(i, s, n = 0):
print('D is %d' % n)
if s[i][1] == -1:
return n
else:
return getDepth(s[i][1], s, n+1)
def traceFrom(m, s, dt=[]):
print('Got n:%d, s:' % m, s)
if s[m][1] == -1:
d = []
n = 0
for i in range(len(s)):
if i in dt:
d.append(s[i][0])
return " ".join(d)
else:
dt.append(m)
return traceFrom(s[m][1], s, dt)

def parse(sentence):
d = []
for i in range(len(sentence)):
d.append(getDepth(i, sentence))
m = d.index(max(d))
print('Largest is ' , d[m], ' of ', d)
return traceFrom(m, sentence)
print('Subject :', parse(values))

给定您的预解析数组,这很容易:

values = [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)]

def parseFrom(n, data):
if values[n][1] != -1:
#print('Stepping (%s,%d)' % (values[n][0], values[n][1]))
data.append(values[n][0])
return parseFrom(values[n][1], data)
else:
#print('At verb')
return data
subject = ' '.join(parseFrom(0, []))
print('Sentence has subject:', subject)

如果当前单词不是动词,则该函数是递归的,否则将主语作为数组返回。抱歉,如果它不适用于所有句子

最新更新