Ich migriere einen C # -basierten Programmiersprachencompiler von einem manuellen Lexer / Parser zu Antlr.
Antlr hat mir starke Kopfschmerzen bereitet, weil es normalerweise meistens funktioniert, aber dann gibt es die kleinen Teile, die nicht und sind unglaublich schmerzhaft zu lösen.
Ich habe entdeckt, dass die meisten meiner Kopfschmerzen durch die Lexer-Teile von Antlr und nicht durch den Parser verursacht werden. Dann bemerkte ich parser grammar X;
und erkannte, dass ich vielleicht meinen manuell geschriebenen Lexer und dann einen von Antlr erzeugten Parser haben könnte.
Ich suche nach mehr Dokumentation zu diesem Thema. Ich denke, ein benutzerdefinierter ITokenStream könnte funktionieren, aber es scheint praktisch keine Online-Dokumentation zu diesem Thema zu geben ...
Ich habe herausgefunden, wie. Es ist vielleicht nicht der beste Ansatz, aber es scheint zu funktionieren.
ITokenStream
-Parameter ITokenSource
s ITokenSource
ist eine deutlich einfachere Schnittstelle als ITokenStream
ITokenSource
in ein ITokenStream
umzuwandeln, besteht darin, ein CommonSourceStream
zu verwenden, das einen ITokenSource
-Parameter Jetzt müssen wir nur noch zwei Dinge tun:
Das Anpassen der Grammatik ist sehr einfach. Entferne einfach alle Lexer-Deklarationen und vergewissere dich, dass du die Grammatik als parser grammar
deklarierst. Ein einfaches Beispiel wird hier für die Bequemlichkeit geschrieben:
Beachten Sie, dass die folgende Datei class mygrammar
anstelle von class mygrammarParser
ausgibt.
Nun wollen wir einen "falschen" Lexer implementieren. Ich habe den folgenden Pseudocode persönlich benutzt:
%Vor% Schließlich müssen wir TokenQueue
definieren. TokenQueue
ist nicht unbedingt notwendig, aber ich habe es aus Bequemlichkeit verwendet.
Es sollte Methoden zum Empfangen der Lexer-Token und Methoden zum Ausgeben von Antlr-Tokens haben. Wenn also keine nativen Antlr-Token verwendet werden, muss eine Antlr-Token-Methode implementiert werden.
Außerdem muss TokenQueue
ITokenSource
implementieren.
Beachten Sie, dass es sehr wichtig ist, die Token-Variablen korrekt zu setzen. Anfangs hatte ich einige Probleme, weil ich CharPositionInLine
falsch berechnet habe. Wenn diese Variablen falsch festgelegt sind, kann der Parser fehlschlagen.
Außerdem ist der normale Kanal (nicht versteckt) 0.
Das scheint für mich bisher zu funktionieren. Ich hoffe, dass andere es auch nützlich finden. Ich bin offen für Feedback. Insbesondere, wenn Sie einen besseren Weg finden, um dieses Problem zu lösen, zögern Sie nicht, eine separate Antwort zu veröffentlichen.
Tags und Links c# antlr lexer parser-generator