Eine Permutationsphrase ist eine Erweiterung der kontextfreien Grammatikdefinitionen von Standard (E) BNF: Eine Permutationsphrase enthält n Produktionen (oder entsprechend Nichtterminale) A 1 bis A n . An der Stelle der Permutationsphrase möchten wir jede dieser Produktionen genau einmal sehen, aber die Reihenfolge dieser Nichtterminale interessiert uns nicht.
Beispielsweise:
S <- X { A, B, C } Y
ist äquivalent zu:
S <- X A B C Y
S <- X A C B Y
S <- X B A C Y
S <- X B C A Y
S <- X C A B Y
S <- X C B A Y
Das Konzept scheint in "Erweitern von kontextfreien Grammatiken mit Permutationsphrasen" eingeführt worden zu sein . Darin wird auch beschrieben, wie diese Phrasen in linearer Zeit unter Verwendung eines LL (1) -Parsers analysiert werden.
Der Artikel " Analysieren von Permutationsphrasen " beschreibt eine Methode zum Analysieren von Permutationsphrasen mit Parser-Kombinatoren. Dies sind die einzigen zwei Artikel, die ich gefunden habe und die sich mit Permutationsphrasen und deren Analyse befassen.
Angesichts der Tatsache, dass wir diese Art von Permutationsphrasen mit LL (1) -basierten Parsern leicht analysieren können, würde ich davon ausgehen, dass wir dasselbe mit Parsern im LR (1) -Stil tun können. Meine Frage lautet daher:
Kann eine Grammatik, die Permutationsphrasen enthält, in der Größe der Eingabezeichenfolge unter Verwendung der LR (1) -Maschinerie zeitlinear analysiert werden, während eine Tabelle mit angemessener Größe beibehalten wird?
Obwohl dies besser ist, ist es natürlich nicht gut genug - eine Permutationsphrase von 30 Elementen würde die Grammatik unbrauchbar machen. Es gibt noch einen Teil des LR-Parsings, den wir noch nicht behandelt haben, und das ist das eigentliche stapelbasierte Verfahren, das für das Parsing verwendet wird. Ich kann mir vorstellen, dass das Speichern von Zählern auf dem Stapel das Problem lösen kann, aber ich bin mir nicht sicher, wie ich das tun soll.
Ich implementiere derzeit einen Parser-Generator und im Problembereich wären Permutationsphrasen ein Geschenk des Himmels. Da ich LR (1) -Maschinen benutze, folgte die obige Frage.
quelle
Antworten:
Haben Sie darüber nachgedacht, dies in ein semantisches Problem umzuwandeln? Anstelle von Grammatikregeln für alle Permutationen von Nichtterminalen {A, B, C} muss nur eine Regel (A | B | C) ^ 3 zusammen mit einem speziellen internen Code erkannt werden, der sicherstellt, dass jeweils nur eine davon erkannt wird, andernfalls wird deklariert ein Fehler. Ich würde eine leere Produktion vor der obigen Klausel einfügen, deren Reduktion die Initialisierung dessen auslöst, was Sie zum Zählen von A, B und C verwenden, und eine nachfolgende, deren Reduktion die Zählerüberprüfung auslöst und (falls erforderlich) den Fehler bestätigt. (Natürlich kann dies etwas schwierig werden, wenn die Grammatik durch A, B und / oder C rekursiv ist.)
quelle
Ich glaube nicht, dass man einen Zähler braucht. Im Wesentlichen überprüfen Sie nur alle Permutationen, brechen aber ab
Pseudocode:
Hier ist ein konkreteres Beispiel
Angenommen, wir versuchen, eine Permutation von abcd abzugleichen, und unsere Zeichenfolge lautet bcda
Sie sehen also, dass dieser einfache Algorithmus ganz einfach nach einer Permutation suchen kann, indem er "Strings" in der falschen Reihenfolge vergleicht. Beachten Sie, dass die Komplexität der Funktion O (n!) Worst Case und O (1) Best Case ist. In gewisser Weise zählen wir, indem wir die übereinstimmenden Symbole in einem Array speichern. Ich würde denken, dass dies im Allgemeinen "schnell" sein würde, da man in den meisten Fällen nicht mit sehr großen n umgehen würde.
quelle