Java ANTLR基本行为

Java ANTLR基本行为,java,antlr,Java,Antlr,我使用以下Java代码实例化使用ANTLR生成的解析器 package foo; public class Test1 { public static void main(String[] args) throws RecognitionException { CharStream stream = new ANTLRStringStream("foo "); BugLexer lexer = new BugLexer(stream); Comm

我使用以下Java代码实例化使用ANTLR生成的解析器

package foo;    
public class Test1 {
public static void main(String[] args) throws RecognitionException {
       CharStream stream = new ANTLRStringStream("foo ");
       BugLexer lexer = new BugLexer(stream);
       CommonTokenStream tokenStream = new CommonTokenStream(lexer);
       BugParser parser = new BugParser(tokenStream);
       parser.specification();
    }
}
我的语法:

grammar Bug;
options {
  language = Java;
}
@header {
  package foo;
}
@lexer::header {
  package foo;
}
specification : 
   'foo' EOF 
;  
WS 
   : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} 
;
SCOLON
   : (~ ';')+
;
我得到的错误是:
第1行:0不匹配的输入“foo”应为“foo”
我希望输入中的空格被忽略,但它不是。。eclipse中的antlr解释器说它很好,所以我想我的Java代码是错误的,但我就是看不出来。。。
注意:如果我删除了SCOLON的规则,那么输入就没有bug。

ANTLR的lexer会尽可能多地匹配每个令牌。因此,
“foo”
被标记为单个
SCOLON
标记,而不是
“foo”
-和
WS
标记

请注意您的
SCOLON
规则:

SCOLON
 : (~ ';')+
 ;
通过其名称表示只匹配一个分号,但实际上匹配一个或多个字符,而不是分号。也许应该是这样的:

SCOLON
 : ';'
 ;
?

编辑 海因里希·奥迪写道:

不知何故,我认为有一个优先级(由声明的顺序给出),标记ANTLR试图匹配输入。谢谢你的回复


这是正确的:每当两个(或更多)规则匹配相同数量的字符时,首先定义的规则将“获胜”。但是,如果最后定义的规则与最多字符匹配,它将“获胜”。

谢谢。实际上,我重新命名了规则,希望让我的最小示例更容易理解。不知何故,我认为有一个优先级(由声明的顺序给出),标记ANTLR试图匹配输入。感谢您的回复。所以您几乎永远无法在全局上下文中使用~(..)规则。它几乎总是必须是局部的(如果可能的话)或由某些语义上下文“封闭”的。。。我说得对吗?