antlr4可以';t将文本提取到标记中

antlr4可以';t将文本提取到标记中,antlr4,lexer,Antlr4,Lexer,我有下面的语法,我正试着慢慢地开始,努力移动复杂的参数 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 D

我有下面的语法,我正试着慢慢地开始,努力移动复杂的参数

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';
我希望(目前)能像这样解析文件:

cmd1
cmd3 -a
如果我通过grun运行该输入,我会得到一个错误:

$ java org.antlr.v4.gui.TestRig Command commands -tree
...
`line 3:6 mismatched input 'a' expecting LOWER`
似乎LOWER应该匹配“a”。如果我将arg定义更改为注释掉的行,它可以正常工作,并将“-a”作为arg。使用LOWER和显式使用a有什么区别

一旦出现“不匹配”错误,将
-tokens
添加到grun以显示标记,这有助于发现您认为lexer将执行的操作与它实际执行的操作之间的差异。用你的语法:

$ 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
在某些情况下可能会导致问题。我更喜欢显式地添加
后缀,表示零次或一次。因此,我的解决方案是:

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 ;
执行:

$ 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
$grun命令命令-令牌-诊断t.text
[@0,0:3='cmd1',1:0]
[@1,4:4='\n',1:4]
[@2,5:8='cmd3',2:0]
[@3,10:10='-',,2:5]
[@4,11:11='a',2:6]
[@5,12:12='\n',2:7]
[@6,13:12='',,3:0]
问题最后更新1829

请参阅有趣的。谢谢你写这篇文章(+1)。我最终得到了ARG:[-][a-zA-Z0-9];这是规则,但你的另一篇文章将有助于你前进。谢谢
$ 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