Antlr4 ANTLR 4中的优先模糊性

Antlr4 ANTLR 4中的优先模糊性,antlr4,Antlr4,我有一个巨大的ANTLR语法,我正面临一个小问题。语法有两个规则expr和集合,定义如下: expr: id |(PLUS|MINUS|MULTIPLY|AND|NEGATION)expr | expr (MULTIPLY |DIVIDE| MODULO) | expr (PLUS | MINUS) expr ; set: EMPTY | MULTIPLY set | set PLUS set | UNION '(' set (COMMA se

我有一个巨大的ANTLR语法,我正面临一个小问题。语法有两个规则expr和集合,定义如下:

expr:
   id
  |(PLUS|MINUS|MULTIPLY|AND|NEGATION)expr
  | expr (MULTIPLY |DIVIDE| MODULO)
  | expr (PLUS | MINUS) expr
 ;

 set:
    EMPTY
   | MULTIPLY set 
   | set PLUS set
   | UNION '(' set (COMMA set)* ')'
   | INTER '(' set (COMMA set)* ')'
   | expr
  ;
这里的问题是,对于一组形式*s1+*s2,应减少如下:

set -> set PLUS set 
然后RHS中的每一组应减少到:

set -> MULTIPLY set
set -> expr
term -> id
但相反,它们正在减少:

set -> MULTIPLY set
set -> expr
expr -> expr PLUS expr 
因此,forn
*s1+*s2
的集合被解析为
*(s1+*s2)
,而不是
(*s1)+(*s2)

集合的规则之一,将其简化为expr。语法中还有许多其他类似的规则,可以简化为expr。这里出现的问题是因为set和expr中的一些规则是相似的。但由于某些规则不同,我无法将它们合并在一起

在集合中,即使规则
乘集
的优先级高于
集合加集合
,集合也会被
乘集
规则减少

有没有办法解决这个问题

编辑:

添加一个工作示例:

语法:

grammar T;

expr
 : ID
  | ( PLUS | MINUS | MULTIPLY | AND | NEGATION ) expr
  | expr ( MULTIPLY | DIVIDE | MODULO )
  | expr ( PLUS | MINUS ) expr
 ;

 set:
    EMPTY
    | MULTIPLY set 
    | set PLUS set
    | UNION '(' set (COMMA set)* ')'
    | INTER '(' set (COMMA set)* ')'
    | expr
  ;
 ID : [a-zA-Z] [a-zA-Z0-9]*;
 PLUS : '+';
 MINUS : '-';
 MULTIPLY : '*';
 AND : '&&';
 NEGATION : '!';
 DIVIDE : '/';
 MODULO : '%';
 COMMA : ',';
 EMPTY: '\\empty';
 UNION: '\\union';
 INTER: '\\inter';
 SPACES : [ \t\r\n] -> skip;
执行它的代码:

TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2"));
TParser parser = new TParser(new CommonTokenStream(lexer));
RuleContext tree  = parser.set();
tree.inspect(parser);
它生成的输出:

  set
  / \
 *  set
     |
    expr
    / | \
   /  |  \
 expr +  expr
  |       / \
  s1     *  expr
             |
             s2   

我不能复制这个

考虑到语法:

grammar T;

expr
 : ID
 | ( PLUS | MINUS | MULTIPLY | AND | NEGATION ) expr
 | expr ( MULTIPLY | DIVIDE | MODULO )
 | expr ( PLUS | MINUS ) expr
 ;

ID : [a-zA-Z] [a-zA-Z0-9]*;
PLUS : '+';
MINUS : '-';
MULTIPLY : '*';
AND : '&&';
NEGATION : '!';
DIVIDE : '/';
MODULO : '%';
SPACES : [ \t\r\n] -> skip;
您的输入
*s1+*s2
将被解析为:

     expr
    / | \
   /  |  \
 expr +  expr
 / \     / \
*  expr *  expr
    |       |
    s1      s2
或者,用普通代码:

TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2"));
TParser parser = new TParser(new CommonTokenStream(lexer));
System.out.println(parser.expr().toStringTree(parser));
将打印:

(expr (expr * (expr s1)) + (expr * (expr s2)))

既然我无法复制,你能提供一份这份报告吗?(见我的答案)@BartKiers,我添加了一个工作示例。很抱歉之前没有提供这个示例。当以“set”作为起点解析输入*s1+*s2时,我面临的问题就出现了。由于expr在语法中的许多其他规则中使用,所以我无法将集合合并到expr中。