2016-03-28 8 views
2

Ich definiere eine ANTLR4-Grammatik und möchte, dass bestimmte - aber nicht alle - Dinge anders dargestellt werden, wenn sie in Anführungszeichen stehen, als wenn sie außerhalb von Anführungszeichen stehen. Hier ist die Grammatik habe ich bisher:ANTLR4 - Wie in Anführungszeichen anders zu symbolisieren?

grammar SimpleGrammar; 

AND: '&'; 
TERM: TERM_CHAR+; 
PHRASE_TERM: (TERM_CHAR | '%' | '&' | ':' | '$')+; 
TRUNCATION: TERM '!'; 
WS: WS_CHAR+ -> skip; 

fragment TERM_CHAR: 'a' .. 'z' | 'A' .. 'Z'; 
fragment WS_CHAR: [ \t\r\n]; 

// Parser rules 
expr: 
    expr AND expr 
    | '"' phrase '"' 
    | TERM 
    | TRUNCATION 
    ; 

phrase: 
    (TERM | PHRASE_TERM | TRUNCATION)+ 
    ; 

Die obige Grammatik funktioniert, wenn a! & b Parsen, die richtig analysiert zu:

AND 
/\ 
/ \ 
a! b 

Allerdings, wenn ich versuchen, "a! & b" zu analysieren, die ich erhalten:

Zeile 1: 4 externer Eingang '&' erwartet {'"', TERM, PHRASE_TERM, TRUNCATION}

Die Fehlermeldung ist sinnvoll, weil die & als AND Token erhalten wird. Was ich möchte, ist jedoch, die & bekommen als PHRASE_TERM Token, wenn es innerhalb von Anführungszeichen (innerhalb einer "Phrase") erscheint. Beachten Sie, ich möchte die a! als TRUNCATION Tokenize, auch wenn es innerhalb der Phrase erscheint.

Ist das möglich?

Antwort

2

Es ist möglich, wenn Sie Lexer-Modi verwenden. Es ist möglich, den Modus nach der Begegnung eines bestimmten Tokens zu ändern. Lexerregeln müssen jedoch separat definiert werden, nicht in kombinierter Grammatik.

In Ihrem Fall ändern Sie den Modus, nachdem Sie auf ein Angebot gestoßen sind. Wenn Sie auf ein anderes Angebot gestoßen sind, wechseln Sie wieder in den Standardmodus.

LBRACK : '[' -> pushMode(CharSet); 
RBRACK : ']' -> popMode; 

Weitere Informationen google 'ANTLR Lexer Mode'