eine Baumbank von vertikalen Bäume s-Ausdrücke Umwandlung
Frage
ich eine Sammlung von Parse-Bäumen haben, und sie sind in dieser Darstellung ascii wo Vertiefung die Struktur bestimmt (und Schließen Klammern sind implizit). Ich muß sie s-Ausdrücke konvertieren, so dass Klammern, um die Struktur zu bestimmen. Es ist ein bisschen wie die Python signifikante Leerzeichen vs. Klammern. Das Eingabeformat ist eine vertikale Darstellung von Bäumen, etwa so:
STA:fcl
=S:np
==DN:pron-dem("tia" <*> <Dem> <Du> <dem> DET P NOM) Tiaj
==H:n("akuzo" <act> <sd> P NOM) akuzoj
=fA:adv("certe") certe
=P:v-fin("dauxri" <va+TEMP> <mv> FUT VFIN) dauxros
.
Sollte werden:
(STA:fcl (S:np (DN:pron-dem Tiaj) (H:n akuzoj)) (fA:adv certe) (P:v-fin dauxros) .)
Ich habe Code, dass fast es tut, aber nicht ganz. Es gibt immer eine fehlende paren irgendwo; es wird immer sehr frustrierend. Soll ich einen richtigen Parser verwenden, vielleicht einen CFG? Der Strom (chaotisch) -Code ist http://github.com/andreasvc/ eodop / Blob / Master / arbobanko.py
Lösung
Die Fokussierung nur auf das Beispiel, das Sie in diesem Q geben, und den Titel der Q über das Konvertieren von vertikalen Bäumen zu S-Ausdrücke, so etwas wie ...:
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()
scheint zu funktionieren, und Ausgänge
(S (NP (DT the) (N man)) (VP (V walks)))
Ich weiß, Sie versuchen, viel mehr „Reinigung“ zu tun, als ich hier mache, aber das kann in der clean
Funktion konzentriert werden, reparse
verlassen mit der Q-Titel zu behandeln. Wenn Sie nicht drucken möchten, wie Sie gehen, sondern vielmehr das Ergebnis als String zurück, sind die Änderungen natürlich ganz minor:
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)