2017-10-02 2 views
1

Ich habe die folgende Grammatik und versuche, langsam zu beginnen, um komplexe Argumente zu bewegen.antlr4 kann Literal nicht in Token extrahieren

grammar Command; 

commands : command+ EOF; 
command : NAME args NL; 
args : arg | ; 

arg : DASH LOWER | LOWER; 
//arg : DASH 'a' | 'x'; 

NAME : [_a-zA-Z0-9]+; 
NL : '\n'; 
WS : [ \t\r]+ -> skip ; // spaces, tabs, newlines 
DASH : '-'; 
LOWER: [a-z];//'a' .. 'z'; 

Ich habe gehofft, (vorerst) zu analysieren Dateien wie folgen aus:

cmd1 
cmd3 -a 

Wenn ich laufe, dass die Eingabe durch grun ich einen Fehler:

$ java org.antlr.v4.gui.TestRig Command commands -tree 
... 
`line 3:6 mismatched input 'a' expecting LOWER` 

Es scheint wie SENKEN sollte mit "a" übereinstimmen. Wenn ich die arg-Definition ändere, um die auskommentierte Zeile zu sein, funktioniert es gut und ich bekomme das '-a' als arg. Was ist der Unterschied zwischen der Verwendung von LOWER und der expliziten Verwendung von 'a'?

+1

See [hier] (https://stackoverflow.com/a/46267981/3764814) –

+0

Interessant. Danke, dass du das geschrieben hast (+1). Ich endete mit ARG: [-] [a-zA-Z0-9]; für die Regel, aber Ihr anderer Beitrag wird helfen, vorwärts zu gehen. Vielen Dank! –

Antwort

1

Sobald Sie einen "nicht übereinstimmenden" Fehler haben, fügen Sie -tokens grun hinzu, um die Tokens anzuzeigen, es hilft, die Diskrepanz zwischen dem zu finden, was der LEXER THUNK tut und was es tatsächlich tut. Mit Ihrer Grammatik:

$ alias grun='java org.antlr.v4.gui.TestRig' 
$ grun Command commands -tokens -diagnostics t.text 
[@0,0:3='cmd1',<NAME>,1:0] 
[@1,4:4='\n',<' 
'>,1:4] 
[@2,5:8='cmd3',<NAME>,2:0] 
[@3,10:10='-',<'-'>,2:5] 
[@4,11:11='a',<NAME>,2:6] 
[@5,12:12='\n',<' 
'>,2:7] 
[@6,13:12='<EOF>',<EOF>,3:0] 
line 2:6 mismatched input 'a' expecting LOWER 

Sie sofort sehen, dass der Brief a ein NAME und nicht die erwarteten LOWER.

Achten Sie auch Regeln mit einer leeren Alternative:

args 
    : arg 
    | 
    ; 

zu Problemen in einigen Fällen führen. Ich ziehe es vor, das Suffix ? explizit hinzuzufügen, das null oder einmal bedeutet. So wäre meine Lösung sein:

grammar Command; 

commands 
@init {System.out.println("Question last update 1829");} 
    : command+ EOF 
    ; 

command 
    : NAME args? NL 
    ; 

args 
    : arg 
    ; 

arg : DASH? LOWER ; 

LOWER : [a-z] ; 
NAME : [_a-zA-Z0-9]+; 
DASH : '-' ; 
NL : '\n' ; 
WS : [ \t\r]+ -> skip ; 

Ausführung:

$ grun Command commands -tokens -diagnostics t.text 
[@0,0:3='cmd1',<NAME>,1:0] 
[@1,4:4='\n',<' 
'>,1:4] 
[@2,5:8='cmd3',<NAME>,2:0] 
[@3,10:10='-',<'-'>,2:5] 
[@4,11:11='a',<LOWER>,2:6] 
[@5,12:12='\n',<' 
'>,2:7] 
[@6,13:12='<EOF>',<EOF>,3:0] 
Question last update 1829 
Verwandte Themen