Antlr Hidden Channel Whitespace -Problem
-
18-09-2019 - |
Frage
Ich habe die folgende Antlr -Grammatik:
grammar MyGrammar;
doc : intro planet;
intro : 'hi';
planet : 'world';
MLCOMMENT
: '/*' ( options {greedy=false;} : . )* '*/' { $channel = HIDDEN; };
WHITESPACE : (
(' ' | '\t' | '\f')+
|
// handle newlines
( '\r\n' // DOS/Windows
| '\r' // Macintosh
| '\n' // Unix
)
)
{ $channel = HIDDEN; };
In den Antlrworks 1.2.3 Interpreter die Eingaben hi world
,hi/**/world
und hi /*A*/ world
Arbeit, wie erwartet.
Die Eingabe jedoch jedoch hiworld
, die sollte nicht Arbeit, wird auch akzeptiert. Wie mache ich hiworld
scheitern? Wie erzwinge ich mindestens eine Whitespace (oder einen Kommentar) zwischen "Hallo" und "Welt"?
Beachten Sie, dass ich in diesem Beispiel nur mlComent und Whitespace verwendet habe, um zu vereinfachen, aber andere Arten von Kommentaren würden unterstützt.
Lösung
Sie müssen ein allgemeines ID -Token erstellen. Da der Lexer das längste Token erstellt, das es kann, würde es die Eingabe "Hiworld" als einzelnes Wort sehen, da es länger als "hi" oder "welt" von selbst ist. Eine solche Regel könnte aussehen:
ID : ('a'..'z' | 'A'..'Z')+;
Genau so trennen Parser für Programmiersprachen das Schlüsselwort "do" von "Double" (Schlüsselworttyp, beginnt mit 'Do') oder "Fertig" (Variablenname).
Andere Tipps
Eine Möglichkeit, die Zeichenfolge zu machen hiworld
Fail besteht darin, ein validierendes semantisches Prädikat zu verwenden, das garantiert wie folgt fehlschlägt:
doc: intro planet;
failure : 'hiworld' { false }?;
intro : 'hi';
planet : 'world';
// rest of grammar omitted