Welche Zeichen können bei einer gegebenen Zeichenfolge und einer CFG der Zeichenfolge folgen (in den Sententialformen der CFG)?


10

Lassen die Menge der Klemme und sein N die Menge der Nicht-Terminal - Symbole einiger kontextfreien Grammatik G .ΣNG

Sagen , ich habe einen String , so dass x a y S ( G ) , wobei x , y ( & Sigma; N ) * und S ( G ) sind die Formen der sentential G .a(ΣN)+xayS(G)x,y(ΣN)S(G)G

Bei gegebenem möchte ich eine Menge C = { b w a b z S ( G ) , b Σ N } bestimmen .GC={bwabzS(G),bΣN}

Zur Verdeutlichung sind in diesem Fall Zeichenfolgen von Anschlüssen und Nichtanschlüssen und b hat die Länge eins.w,x,y,z,a,bb

Ich kann sehen, wie das geht, wenn auch die Länge eins hat; Jedes b ist ein Mitglied der folgenden Menge von a (einschließlich Nicht-Terminals).aba

Ich bin jedoch gespannt, ob es für eine Folge von Zeichen möglich ist. Für meine Anwendung, die Zeichenfolge nicht viel länger als die rechte Seite der Produktionen in G .aG

Die Unterscheidung zwischen Terminals und Nicht-Terminals ist in meiner Anwendung etwas stumm, da ich eine generative Grammatik verwende. und ich glaube, dass dies nicht zu viel Ärger führen wird, da Länge eins hat.b


1
Was ist Ihre Bewerbung? Bauen Sie einen Parser?
Raphael

Können wir annehmen, dass die Grammatik in irgendeiner normalen Form vorliegt oder muss sie für beliebige funktionieren?
Raphael

@AlextenBrink - und y sind beliebige Zeichenfolgen. Ich betrachte nur ein Fragment / einen Teilstring. xy
Thomas

@ Raphael - Ich versuche, Transformationen von L-System-Grammatiken zu automatisieren ... es ist also nicht in normaler Form. Tatsächlich werde ich diese Frage noch einmal bearbeiten, um sie genauer zu machen.
Thomas

Ich hoffe, dass ich die Frage nicht zu sehr geändert habe - sie hat jetzt einen etwas anderen Charakter.
Thomas

Antworten:


6

Ich werde einen Algorithmus beschreiben, der funktioniert. Die Laufzeit sollte nicht schlecht sein. Sie können auch einiges davon vorberechnen.

axyaAA

aax

Wir verwenden eine Anpassung des Earley-Algorithmus . Sie sollten diesen Algorithmus zuerst verstehen. Unser Algorithmus funktioniert fast genauso, außer dass unsere Initialisierungs- und Abschlussschritte unterschiedlich sind.

a1a

Jetzt führen wir den Earley-Algorithmus für jedes mögliche derartige anfängliche Earley-Element separat durch. Wir können nicht einfach alle gleichzeitig ausführen, da sich die Parses gegenseitig stören können. Ich kann keine schnellere Methode als das Zurückverfolgen hier sehen.

LALR(1)LALR(1)

LALR(1)

a

Bearbeiten: Ich glaube, ich habe die Methode gefunden, mit der der größte Teil des durch das Backtracking verursachten Overheads entfernt wird. Wir verknüpfen mit jedem Earley-Element eine Reihe von Bezeichnern, die Zeichenfolgen sind, da wir Präfixe dieser Bezeichner verwenden müssen. Bei der Initialisierung fügen wir alle anfänglichen Elemente zum Earley-Set hinzu und ordnen jedem Set eine eindeutige Kennung zu.

In den Scanner- und Prädiktorschritten werden Kennungen auf neue Elemente übertragen. Earley-Elemente in demselben Earley-Set, die sich nur in ihren Kennungen unterscheiden, werden zusammengeführt, indem ihre Kennungen zusammengeführt werden. Beachten Sie, dass wir für diese neuen Elemente Scanner- und Prädiktorschritte mit Bezeichnern ausführen können, ohne diesen Schritt für jeden Bezeichner separat ausführen zu müssen.

LALR(1)

Im Wesentlichen führen wir das Backtracking mit diesen Kennungen durch, damit wir nicht doppelt in den Scanner- und Prädiktorschritten arbeiten.


aa

@Thomas Das ist nicht allzu schwer: Sie betrachten das Nichtterminal einfach als Terminal für diese bestimmte Position in der Analyse: Sie sagen es immer noch wie gewohnt voraus und vervollständigen es, aber Sie betrachten es auch beim Scannen.
Alex Ten Brink

Ja, in der Tat - jetzt, wo ich Ihre Lösung verstehe, sollte es keinen Unterschied machen.
Thomas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.