Antlr 防止语法歧义

Antlr 防止语法歧义,antlr,antlr4,Antlr,Antlr4,按照以下语法: expr : r1 EOF | r2 EOF ; r1 : '1' L1 'x' ; r2 : '1' L2 'y' ; L1: 'a' ; L2: 'a' ; 当我解析表达式时 1ay 我希望解析器创建适当的解析树,但是我得到以下错误: 第1行:2不匹配的输入“y”应为“x” 为什么不能正确解析它?我可以指示它这样做吗 解析代码: private static void parse(String str) { ANTLRInputStrea

按照以下语法:

expr : r1 EOF
     | r2 EOF
     ;

r1 : '1' L1 'x' ;
r2 : '1' L2 'y' ;

L1: 'a' ;
L2: 'a' ;
当我解析表达式时

1ay
我希望解析器创建适当的解析树,但是我得到以下错误:

第1行:2不匹配的输入“y”应为“x”

为什么不能正确解析它?我可以指示它这样做吗

解析代码:

private static void parse(String str) 
{
    ANTLRInputStream input = new ANTLRInputStream(str);
    AmbLexer lexer = new AmbLexer(input); 
    CommonTokenStream tokens = new CommonTokenStream(lexer); 
    AmbParser parser = new AmbParser(tokens);
    ParseTree tree = parser.expr();
    System.err.println(tree.toStringTree(parser));
}

解析的第一步是基于lexer规则创建令牌流。令牌是使用将首先匹配的规则创建的。所以在你的例子中,每个‘a’都是L1。由于r1是唯一包含L1的解析器规则,它无法匹配输入,因为规则“r1”应为“x”,而不是“y”

因此,必须对lexer规则进行排序,以便在更模糊的规则之前先对其进行特殊和更具体的排序。规则作为字符串,数字将在最后,但“func”、“class”等规则将在它们之前

要解决此问题,请将L1和L2合并为一个规则,并在两个解析器规则中使用它