2013-03-19 17 views
12

Ich habe viele ANTLR Grammatiken gesehen, die Verarbeitung von Leerzeichen wie folgt verwenden:ANTLR4: Leer Handhabung

WS: [ \n\t\r]+ -> skip; 
// or 
WS: [ \n\t\r]+ -> channel(HIDDEN); 

So sind die Whitespaces weggeworfen werden jeweils an den verborgenen Kanal senden.

Mit einer Grammatik wie folgt aus:

grammar Not; 

start:  expression; 
expression: NOT expression 
      | (TRUE | FALSE); 

NOT: 'not'; 
TRUE: 'true'; 
FALSE: 'false'; 
WS: [ \n\t\r]+ -> skip; 

gültige Eingaben ‚ nicht wahr‘ oder ‚falsch nicht‘, sondern auch ‚nottrue‘, die nicht ein erwünschtes Ergebnis ist. Ändern der Grammatik:

grammar Not; 

start:  expression; 

expression: NOT WS+ expression 
      | (TRUE | FALSE); 

NOT: 'not'; 

TRUE: 'true'; 
FALSE: 'false'; 

WS: [ \n\t\r]; 

behebt das Problem, aber ich will nicht die Leerzeichen manuell in jeder Regel behandeln.

Im Allgemeinen möchte ich ein Leerzeichen zwischen jedem Token mit einigen Ausnahmen (z. B. '! True' braucht kein Leerzeichen dazwischen).

Gibt es eine einfache Möglichkeit, dies zu tun?

Antwort

11

Fügen Sie eine IDENTIFIER Lexer-Regel hinzu, um Wörter zu behandeln, die keine Schlüsselwörter sind.

IDENTIFIER : [a-zA-Z]+; 

Jetzt ist der Text nottrue ist ein einzelne IDENTIFIER Token, das Ihr Parser anstelle der verschiedenen Keywords in not true nicht akzeptieren würde.

Stellen Sie sicher IDENTIFIER ist definiert nach Ihre anderen Schlüsselwörter. Der Lexer wird feststellen, dass sowohl NOT als auch IDENTIFIER dem Text not entsprechen, und weist den Tokentyp dem ersten Typ zu, der in der Grammatik erscheint.

+0

Danke. Das funktioniert wie gewünscht für '* nottrue *' (ungültig) und '*! True *' (gültig). Haben Sie auch eine Idee, wie ich eine Ausnahme von dieser Regel machen kann, so dass es für einige andere Eingaben möglich ist, den Whitespace wegzulassen? Wie '* A B true *', wobei das Leerzeichen zwischen A und B optional ist. Also gilt das auch: '* AB true *', aber '* ABtrue *' nicht. – flux