在ANTLR语法中使用不同的大小写关键字

时间:2012-01-13 20:11:43

标签: antlr

我的语法中的一些关键字(字符串常量)包含大写字母 例如

PREV_VALUE : 'PreviousValue';

这会导致奇怪的解析行为:包含相同大写字母('P','V')的其他令牌被错误地解析。

这是词法分析器语法的简化版本:

lexer grammar ExpressionLexer;

COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
PREV_VALUE : 'PreviousValue';
fragment DIGIT : ('0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z'|'_');
fragment TAB : ('\t') ;
fragment NEWLINE : ('\r'|'\n') ;
fragment SPACE : (' ') ;

当我尝试解析这样的表达式时:

var expression = "P"; //Capital 'P' which included to the keyword 'PreviousValue'
var stringReader = new StringReader(expression);
var input = new ANTLRReaderStream(stringReader);
var expressionLexer = new ExpressionLexer(input);
var tokens = new CommonTokenStream(expressionLexer);

tokens._tokens集合包含一个值

[0] = {[@0,1:1='<EOF>',<-1>,1:1]}

这是不正确的。

如果我将expression更改为'p'(小写字母) tokens._tokens集合包含两个值

[0] = {[@0,0:0='p',<0>,1:0]}
[1] = {[@1,1:1='<EOF>',<-1>,1:1]}

没错。

从语法中删除字符串PREV_VALUE : 'PreviousValue';时,两个表达式都被正确解析。

是否可以在关键字中使用不同的案例? 在ANTLR语法中是否有使用此类关键字的示例?

1 个答案:

答案 0 :(得分:1)

我发现很难相信根据您发布的语法创建p令牌。在其前面有fragment的Lexer规则不会生成令牌:这些规则仅供其他词法分析器规则使用。

一个简单的演示显示:

lexer grammar ExpressionLexer;

@lexer::members {
  public static void main(String[] args) throws Exception {
    ExpressionLexer lexer = new ExpressionLexer(new ANTLRStringStream(args[0]));
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    tokens.fill(); // remove this line when using ANTLR 3.2 or an older version
    System.out.println(tokens);
  }
}

COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
PREV_VALUE : 'PreviousValue';
fragment DIGIT : ('0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z'|'_');
fragment TAB : ('\t') ;
fragment NEWLINE : ('\r'|'\n') ;
fragment SPACE : (' ') ;

现在生成词法分析器并编译.java源文件:

java -cp antlr-3.3.jar org.antlr.Tool ExpressionLexer.g 
javac -cp antlr-3.3.jar *.java

并进行一些测试:

java -cp .:antlr-3.3.jar ExpressionLexer p
line 1:0 no viable alternative at character 'p'

这是正确的,因为没有(非片段)规则以"p"开头或匹配。

java -cp .:antlr-3.3.jar ExpressionLexer P
line 1:1 mismatched character '' expecting 'r'

这是正确的,因为以"P"开头的唯一(非片段)规则要求"r"成为下一个字符(不存在)。