我的语法中的一些关键字(字符串常量)包含大写字母 例如
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语法中是否有使用此类关键字的示例?
答案 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"
成为下一个字符(不存在)。