Antlr4 ANTLR 4中的优先模糊性
我有一个巨大的ANTLR语法,我正面临一个小问题。语法有两个规则expr和集合,定义如下: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
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中。