Ich lerne ANTLR4 und versuchte mit lexikalischen Modi zu spielen. Wie kann ich das gleiche Token in mehreren lexikalischen Modi erscheinen lassen? Als ein sehr einfaches Beispiel nehmen wir an, dass meine Grammatik zwei Modi hat, und ich möchte Leerzeichen und Zeilenende in beiden zusammenfassen, wie kann ich es tun, ohne zum Beispiel mit WS_MODE1 und WS_MODE2 zu enden. Gibt es eine Möglichkeit, dieselbe Definition in beiden Fällen wiederzuverwenden? Ich hoffe, WS-Token im Ausgabestrom für alle Leerräume zu erhalten, unabhängig vom Modus. Dasselbe gilt für EOL und andere Schlüsselwörter, die in beiden Modi angezeigt werden können.Wie können Token definiert werden, die in ANTLR4 in mehreren lexikalischen Modi angezeigt werden können?
10
A
Antwort
12
Die Regeln müssen unterschiedliche Namen haben, aber Sie können den Befehl lexer -> type(...)
verwenden, um ihnen den gleichen Typ zu geben.
WS : [ \t]+;
mode Mode1;
Mode1_WS : WS -> type(WS);
mode Mode2;
Mode2_WS : WS -> type(WS);
Obwohl Mode1_WS
und Mode2_WS
sind nicht fragment
Regeln, wird der Code-Generator finden Sie in der type
Befehl und wissen, dass Sie ihre Typen zugewiesen, so wird es nicht definieren Token für sie.
Kurze Frage zur Verwendung dieser Lexer-Regeln: In den Parser-Regeln beziehen Sie sich auf WS oder Mode1_WS, Mode2_WS? Ich habe beides versucht, aber anscheinend definieren Sie nur die Lexer-Regeln, ohne direkt auf die Parser-Regeln zu verweisen. In diesem Fall ist es eher eine 'Import-Aussage' als ein 'Alias'. –
Der Befehl 'type' weist explizit den Tokentyp zu, der vom Parser angezeigt wird. In diesem Fall würde 'WS' verwendet, um Token zu referenzieren, die durch eine dieser 3 Regeln erzeugt wurden. –
@SamHarwell was beendet die final mode spec? Ich habe bemerkt, dass einige Lexer-Dokumente Fragmente defs haben, die der letzten Modus-Spezifikation folgen, wobei die Fragment-Verwendung zeigt, dass die Fragmente für alle Modi verfügbar sind, einschließlich des Standards. – bvj