Okay Sie die Antwort mehr oder weniger von selbst gefunden haben, mit dieser Antwort von mir, damit ich auf die Erläuterung konzentrieren, warum die Problem aufgetreten an erster Stelle.
Zunächst einmal - für alle, die auf diese Frage stolpern - das Problem war, dass er eine andere implizite Lexer-Regel definiert hatte, die so aussah ' or'
(beachten Sie die Leerzeichen). Das Ändern zu 'or'
löste das Problem.
Aber warum war das ein Problem?
Um zu verstehen, müssen Sie verstehen, was ANTLR macht, wenn Sie '<something>'
in einer Ihrer Parser-Regeln schreiben: Beim Kompilieren der Grammatik erzeugt es eine neue Lexer-Regel für jede dieser Deklarationen. Diese Lexerregeln werden vor den in Ihrer Grammatik definierten Lexerregeln erstellt. Der Lexer selbst passt die gegebene Eingabe in Tokens an und verarbeitet dafür jede Lexer-Regel in der Reihenfolge, in der sie deklariert wurden. Daher wird es immer mit den impliziten Token-Definitionen beginnen und dann zur obersten "echten" Lexer-Regel übergehen.
Das Problem ist, dass der Lexer ist nicht zu schlau über diesen Prozess, das bedeutet, sobald es einige Eingabe mit der aktuellen Lexer-Regel übereinstimmt, wird es ein entsprechendes Token erstellen und weiter mit der abschließenden Eingabe.
Als Ergebnis wird eine Lexer-Regel, die danach kommt, die Eingabe ebenfalls abgeglichen (aber als ein anderes Token, da es eine andere Lexer-Regel ist) übersprungen, so dass die entsprechende Eingabe möglicherweise nicht den erwarteten Token-Typ hat Die Lexerregeln haben sich selbst überschrieben. In Ihrem Beispiel lauten die Regeln zum Selbstüberschreiben ' or'
(Token 1) und 'or'
(Token 2). Jede dieser impliziten Lexer-Regeldelkarationen führt zu einer anderen Lexer-Regel, und da die erste Übereinstimmung gefunden wurde, nehme ich an, dass sie vor der zweiten deklariert wird. Nun schauen Sie sich Ihre Eingabe an: whenever ~ or ~
Der Lexer wird anfangen zu interpretieren und die erste Regel, auf die es stößt, ist ' or'
(Nach dem Start wird natürlich angepasst) und es passt die Eingabe da es wirklich ein Leerzeichen vor der or
ist. Daher wird es als Token 1 abgeglichen.
Der Parser auf der anderen Seite erwartet zu diesem Zeitpunkt ein Token 2, so dass es sich über die gegebene Eingabe beschweren wird (obwohl es sich wirklich über den falschen Token-Typ beschwert). Wenn Sie den Eingang auf whenever ~or ~
ändern, führt dies zu einer korrekten Interpretation.
Genau dies ist der Grund, warum Sie keine impliziten Token-Definitionen in Ihrer Grammatik verwenden sollten (außer es ist wirklich klein). Erstellen Sie eine neue Lexer-Regel für jede Eingabe und beginnen Sie mit den spezifischsten Regeln. Das bedeutet, dass Regeln, die mit speziellen Zeichenfolgen (z. B. Schlüsselwörtern) übereinstimmen, vor allgemeinen Lexer-Regeln wie ID
oder STRING
oder etwas ähnlichem deklariert werden sollten. Regeln, die mit allen Zeichen übereinstimmen, um zu verhindern, dass der Lexer einen Fehler bei nicht erkannter Eingabe verursacht, müssen als letztes deklariert werden, da sie jede nachfolgende Lexer-Regel überschreiben würden.
Ihre "STRING" -Regel wird nicht gefunden, da die Eingabe immer als "OTHER" betrachtet wird, bevor die "STRING" -Regel überprüft wird. Und ich bin mir nicht sicher über die impliziten Lexer-Definitionen in Ihrer Grammatik und darüber, wie sie die "OTHER" -Regel stören könnten ... Versuchen Sie, es am Ende der Grammatik zu setzen und zu sehen, ob sich das ändert – Raven
http: // stackoverflow .com/documentation/antlr/3271/lexer-rules-in-v4/11235/priority-rules # t = 201704141056079647247 –
@Raven Ich habe die SONSTIGE Regel am Ende und sogar entfernt, es hat nichts geändert. Die STRING-Regel war nur ein Platzhalter, den ich gemacht habe, kommt für mein Beispiel nicht einmal ins Spiel. LucasTrzesniewski Ich habe die Dokumente gelesen, aber nichts in Bezug auf Leerzeichen/Leerzeichen gesehen, die meinem Problem helfen. – IronWaffleMan