我有一个巨大的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)
。
set的规则之一,将其减少为expr。语法中还有许多其他类似的规则可以减少到expr。这里出现了问题,因为set和expr中的一些规则是相似的。但由于某些规则不同,我无法将它们合并在一起。
即使规则MULTIPLY set
的优先级高于set PLUS set
,设置也会设置为MUTIPLY set
规则。
有没有办法解决这个问题?
编辑:
添加一个工作示例:
语法:
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
答案 0 :(得分:0)
我无法重现这一点。
鉴于语法:
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)))