2008-12-10 11 views
9

Wie würden Sie Ihre Parser- und Lexer-Regeln definieren, um eine Sprache zu analysieren, die den Einzug zum Definieren des Bereichs verwendet.Wie würden Sie Einrückung (Python-Stil) analysieren?

Ich habe bereits gegoogelt und einen cleveren Ansatz für die Analyse gefunden, indem ich Indent und DEDENT Token im Lexer erzeugt habe.

Ich werde tiefer auf dieses Problem eingehen und eine Antwort posten, wenn ich zu etwas interessantem komme, aber ich würde gerne andere Ansätze zu dem Problem sehen.

EDIT: Wie Charlie darauf hingewiesen, there is already another thread very similar if not the same. Sollte mein Beitrag gelöscht werden?

Antwort

1

Sie können auch irgendwo in Lexer verfolgen, wie viele Ident-Elemente der ersten Zeile vorangehen und es an Parser übergeben. Der interessanteste Teil wäre der Versuch, den Parser korrekt zu übergeben :) Wenn Ihr Parser Lookahead verwendet (ich meine, der Parser kann nach einer variablen Anzahl von Token fragen, bevor er wirklich mit einem übereinstimmt), dann scheint es, ihn durch eine globale Variable zu leiten sehr schlechte Idee (weil Lexer in der nächsten Zeile rutschen und den Wert des Einrückungszählers ändern kann, während der Parser noch versucht, die vorherige Zeile zu parsen). Auch Globals sind in vielen anderen Fällen böse;) Das Markieren eines "echten" Tokens der ersten Zeile in irgendeiner Weise mit einem Einrückzähler ist vernünftiger. Ich kann Ihnen kein genaues Beispiel geben (ich weiß nicht einmal, welche Parser- und Lexer-Generatoren Sie verwenden werden, wenn es welche gibt ...), sondern etwas wie das Speichern von Daten in der ersten Zeile (es könnte unkomfortabel sein, wenn Sie können). t leicht erhalten solche Token aus Parser) oder Speichern von benutzerdefinierten Daten (map, dass Links Token zum Einrücken, Array wo jede Zeile im Quellcode als Index und Einrückung Wert als Element Wert) scheint genug zu sein. Ein Nachteil dieses Ansatzes ist die zusätzliche Komplexität des Parsers, der zwischen Ident-Werten unterscheiden und sein Verhalten basierend darauf ändern muss. Etwas wie LOOKAHEAD ({yourConditionInJava}) für JavaCC kann hier funktionieren, aber es ist NICHT eine sehr gute Idee. Viele zusätzliche Tokens in Ihrem Ansatz scheint weniger böse Sache zu sein :)

Als eine andere Alternative würde ich vorschlagen, diese beiden Ansätze zu mischen. Sie können zusätzliche Token nur generieren, wenn der Einzugzähler seinen Wert in der nächsten Zeile ändert. Es ist wie ein künstliches BEGIN- und END-Token. Auf diese Weise können Sie die Anzahl der "künstlichen" Tokens in Ihrem Stream reduzieren, die von Lexer in den Parser eingespeist werden. Nur Ihre Parser-Grammatik sollte angepasst werden, um zusätzliche Token zu verstehen ...

Ich habe das nicht versucht (habe keine echte Erfahrung mit solchen Sprachen Parsing), nur meine Gedanken über mögliche Lösungen zu teilen. Das Überprüfen bereits erstellter Parser für diese Art von Sprachen könnte für Sie von großem Wert sein. Open Source ist dein Freund;)

10

Dies ist irgendwie hypothetisch, da es davon abhängen würde, welche Technologie du für deinen Lexer und Parser hast, aber der einfachste Weg wäre, BEGINBLOCK- und ENDBLOCK-Tokens analog zu geschweiften Klammern zu haben C. Unter Verwendung der "offsides rule" Ihr Lexer muss einen Stapel von endndation Ebenen verfolgen. Wenn der Einzugswert erhöht wird, geben Sie einen BEGINBLOCK für den Parser aus. Wenn der Eindruck kleiner wird, emittieren Sie die ENDBLOCK- und Pop-Level vom Stapel.

Here's another discussion davon auf SO, btw.

Verwandte Themen