ANTLR lexer规则即使不匹配也会使用字符?

ANTLR lexer规则即使不匹配也会使用字符?,antlr,antlr3,antlrworks,Antlr,Antlr3,Antlrworks,我有一个antlr lexer规则的奇怪的副作用,我创建了一个(几乎)最小的工作示例来演示它。 在这个例子中,我想匹配字符串[0..1]。但是当我调试语法时,到达解析器的令牌流只包含[…1]。第一个整数,不管它包含多少个数字,总是被消耗掉,我不知道这是怎么发生的。如果我删除FLOAT规则,一切都很好,所以我猜错误就出在该规则的某个地方。但由于它不应该与[0..1]中的任何内容匹配,我感到非常困惑 我会很高兴看到任何我可能出错的地方。这是我的例子: grammar min; options{ la

我有一个antlr lexer规则的奇怪的副作用,我创建了一个(几乎)最小的工作示例来演示它。 在这个例子中,我想匹配字符串
[0..1]
。但是当我调试语法时,到达解析器的令牌流只包含
[…1]
。第一个整数,不管它包含多少个数字,总是被消耗掉,我不知道这是怎么发生的。如果我删除
FLOAT
规则,一切都很好,所以我猜错误就出在该规则的某个地方。但由于它不应该与
[0..1]
中的任何内容匹配,我感到非常困惑

我会很高兴看到任何我可能出错的地方。这是我的例子:

grammar min;
options{
language = Java;
output = AST;
ASTLabelType=CommonTree;
backtrack = true;
}
tokens {
  DECLARATION;
}

declaration : LBRACEVAR a=INTEGER DDOTS b=INTEGER RBRACEVAR -> ^(DECLARATION $a $b);

EXP : 'e' | 'E';
LBRACEVAR: '[';
RBRACEVAR: ']';
DOT: '.';
DDOTS: '..';

FLOAT
    : INTEGER DOT POS_INTEGER
    | INTEGER DOT POS_INTEGER EXP INTEGER
    | INTEGER EXP INTEGER
    ;

INTEGER : POS_INTEGER | NEG_INTEGER;
fragment NEG_INTEGER : ('-') POS_INTEGER;
fragment POS_INTEGER : NUMBER+;
fragment NUMBER: ('0'..'9');

lexer丢弃
'0'
,并产生以下错误:

line 1:3 no viable alternative at character '.'
line 1:2 extraneous input '..' expecting INTEGER
这是因为当lexer遇到
'0.
时,它尝试创建
浮动
标记,但无法。由于没有其他规则可用于匹配
'0.
,因此它会生成错误,丢弃
'0'
,并创建一个
标记

这就是ANTLR的lexer的工作原理:它不会回溯以匹配
整数
后跟
DDOT
(注意
backtrack=true
仅适用于解析器规则!)

FLOAT
规则中,您必须确保当前面有一个双精度
时,您会生成一个
整数
标记。您可以通过添加一个语法谓词(
('..')=>
部分)来实现这一点,并且仅当单个
'.
后面跟一个数字(
('.'数字)=>
部分)时,才生成
浮点标记。请参见以下演示:

declaration
 : LBRACEVAR INTEGER DDOTS INTEGER RBRACEVAR
 ;

LBRACEVAR : '[';
RBRACEVAR : ']';
DOT       : '.';
DDOTS     : '..';

INTEGER
 : DIGIT+
 ;

FLOAT
 : DIGIT+ ( ('.' DIGIT)=> '.' DIGIT+ EXP? 
          | ('..')=>      {$type=INTEGER;} // change the token here
          |               EXP
          )
 ;

fragment EXP   : ('e' | 'E') DIGIT+;
fragment DIGIT : ('0'..'9');

现在这是一个(至少对我来说)意想不到的行为。感谢您提供了全面的示例,我现在已经全部启动并运行:-)@Lichtblitz,不客气,是的,标记化
(与INT-和FLOAT标记结合使用)很棘手!:)