Сосредоточение только на примере, который вы даете в этом Q, и на заголовке Q о преобразовании вертикальных деревьев в S-выражения, что-то вроде ...:
import re
import sys
samp='''S
=NP
==(DT +def) the
== (N +ani) man
=VP
==V walks'''.splitlines()
relinelev = re.compile(r'(=*)(.*)')
reclean = re.compile(r'\s*\((\S+)[^)]*\)')
def clean(line):
return reclean.sub(r'\1', line)
def reparse(tree=samp):
stack = [-1]
for line in tree:
equals, rest = relinelev.match(line).groups()
linelev = len(equals)
while linelev < stack[-1]:
sys.stdout.softspace = False
print ')',
curlev = stack.pop()
if linelev == stack[-1]:
sys.stdout.softspace = False
print ')',
else:
stack.append(linelev)
print '(%s' % clean(rest),
while stack[-1] >= 0:
sys.stdout.softspace = False
print ')',
stack.pop()
print
reparse()
вроде работает и выводит
(S (NP (DT the) (N man)) (VP (V walks)))
Я понимаю, что вы пытаетесь сделать намного больше "очистки", чем я здесь, но это может быть сконцентрировано в функции clean
, в результате чего reparse
будет иметь дело с заголовком Q. Если вы не хотите печатать по ходу, а возвращаете результат в виде строки, изменения, конечно, довольно незначительны:
def reparse(tree=samp):
stack = [-1]
result = []
for line in tree:
equals, rest = relinelev.match(line).groups()
linelev = len(equals)
while linelev < stack[-1]:
result[-1] += ')'
curlev = stack.pop()
if linelev == stack[-1]:
result[-1] += ')'
else:
stack.append(linelev)
result.append('(%s' % clean(rest))
while stack[-1] >= 0:
result[-1] += ')'
stack.pop()
return ' '.join(result)