2016-11-25 3 views
2

Ich versuche, das folgende Text-Format zu analysieren:ANTLR4 - Parsen `jede string`, ohne den gesamten Eingangsraubend

<identifier> { 
    <identifier> : <any-text-without-white-space-or-new-line> : <identifier> 
    <identifier> : <identifier>.<identifier> 
} 

Zum Beispiel:

john { 
    name : JohnJohnson.12.453.643-USA[NewYork] : default 
    reference : something.else 
} 

ich die folgenden Grammatik erstellt habe :

SPACE   : [ \t\r\n]+ -> skip; 
LEFT_BRACE  : '{'; 
RIGHT_BRACE : '}'; 
COLON   : ':'; 
DOT   : '.'; 
ID    : [a-z]+ 
ANY   : ~(' '|'\t'|'\r'|'\n')+; 

outer   : ID LEFT_BRACE inner_first inner_second RIGHT_BRACE EOF; 
inner_first : ID COLON (ANY | ID) COLON ID; 
inner_second : ID COLON ID DOT ID; 

Das Problem in diesem grammer ist das <identifier>.<identifier> im Eingang der zweiten Zeile wird als

erkannt
ANY 

und nicht als

ID DOT ID 

Ich kann dieses Problem beheben, wenn ich die Definition von ANY zu ändern:

ANY   : ~(' '|'\t'|'\r'|'\n'|'.')+; 

Aber diese bedeutet, dass das . Symbol nicht mehr Teil des beliebigen Textes in der ersten Zeile sein kann.

Dies scheint wie ein Huhn/Ei-Problem. Ist das lösbar?

(FWIW, ich lese das große Buch The Definitive ANTLR 4 Reference, die ich vor einiger Zeit gekauft, aber ich habe nicht eine Lösung noch nicht gefunden.)

Antwort

0

Sie immer die Lexer Regel tokenize den Mindestbetrag haben könnte und einige Parser Regeln, anstelle von Lexer-Regeln, um die Kombination von was auch immer Sie wollen darzustellen. Lassen Sie uns sagen:

my_desired_seq  : NON_WS_CRLF_DOT_SEQ DOT NON_WS_CRLF_DOT_SEQ ; 
NON_WS_CRLF_DOT_SEQ  : ~(' '|'\t'|'\r'|'\n'|'.')+; 

und anderen Teil der Grammatik, anstatt die Parser-Regel verwenden:

inner_second : ID COLON my_desired_seq; 
Verwandte Themen