Einige Klassen
sind nur für die grafische Benutzeroberfläche zuständig,
eine weitere liest Textdateien vom Server ein, andere übernehmen die
eigentlichen Parsing-Algorithmen, wieder andere Klassen sind auf das Errechnen
und Malen der grafischen Strukturbäume gedrillt.
Die Klassen für das eigentliche Parsing sind streng hierarchisiert: Die Klasse Parser (eigentlich ein Interface, keine Klasse) steht ganz oben und ist so allgemein wie möglich gehalten: Sie spezifiziert nur, was ein Parsing-Algorithmus so alles können muss: Lexikon und Regeln einlesen, den Parsing-Vorgang starten, den fertig geparsten Satz mit den zugeordneten Kategorien zurückgeben sowie über nicht im Lexikon gefundene Wörter informieren. Die Klasse ParserBasics realisiert einiges von dem, was die Klasse Parser vorschreibt, nämlich das, was bei jedem Parser, ob Cocke- oder Earley-Algorithmus, gleich ist: das Einlesen des Lexikons und der Grammatik-Regeln und das Speichern in Hashtables; vom Benutzer geänderte Regeln aufnehmen; darüber informieren, ob ein bestimmtes Symbol (z.B. NP) ein Terminal- oder Nicht- Terminalsymbol ist etc. Schließlich gibt es die speziellen Parsing-Algorithmen, die sich von der Klasse ParserBasics ableiten: CockeParser und EarleyParser. Sie erfüllen jeweils auf ihre spezielle Weise die restlichen Forderungen, die die Klasse Parser vorschreibt und die nicht in ParserBasics implementiert sind: den Parsing-Vorgang starten und auf die jeweils eigene Weise durchführen (hier entscheidet sich, ob Bottom-Up oder Top-Down; ob von links nach rechts oder umgekehrt etc...), den Working-Table produzieren und schließlich den fertig geparsten Satz zurückgeben. Aufgrund des objektorientierten Ansatzes ist eine Erweiterung des Programms um neue Parsing-Algorithmen ziemlich unkompliziert: Es muss nur eine weitere Klasse geschrieben werden, die sich von ParserBasics ableitet. Sie kann, wie EarleyParser und CockeParser auch, auf dessen grundlegenden Funktionalitäten aufbauen und muss nur die speziellen Eigenheiten neu formulieren. |