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

War es hilfreich?

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top