我有一个巨大的ANTLR语法,我面临着一个小问题。语法有两个规则expr和set,定义如下:
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的规则之一,将其简化为exr。语法中还有许多其他类似的规则也简化为exr。这里出现的问题是因为set和exr中的一些规则是相似的。但是因为有些规则不同,我不能将它们合并在一起。
在集合中,即使规则乘法集合
的优先级高于集合加集合
,集合也会被多重集合
规则减少。
有没有办法解决这个问题?
编辑:
添加一个工作示例:
语法:
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)))
我在这里开发了一个小语法,我有一个问题: 为什么解析器没有在解析树的顶部看到(->)规则?这是优先级问题吗?
标准的TestCase之一是,lexer应该从中生成令牌流。不幸的是,由于ANTLR优先匹配较长的令牌,它生成令牌流,这将导致解析器引发错误。 是否可以先让ANTLR4 lexer尝试使用较短的令牌进行匹配?向添加lookahead-type规则并不是一个很好的解决方案,因为我需要考虑各种潜在的词法冲突(例如,被命名为,而不是,等等)。 编辑: 但这并不是一个真正的可扩展或可维护的解决方案,而且还
Casbin支持参考优先级加载策略。 通过隐式优先级加载策略 这非常简单,顺序决定了策略的优先级,策略出现的越早优先级就越高。 model.conf: [policy_effect] e = priority(p.eft) || deny 通过显式优先级加载策略 另见: casbin#550 策略的第一个要素一定是优先级,并且优先级值较小的将具有较高的优先地位。 如果优先级有非数字字符,它将是被
我需要一个优先级队列,它首先获得具有最高优先级值的项目。我当前正在使用队列库中的PriorityQueue类。但是,这个函数只先返回值最小的项。我尝试了一些很难看的解决方案,比如(sys.maxint-priority)作为优先级,但我只是想知道是否存在更优雅的解决方案。
根据优先表,一元后缀递增和递减运算符比关系运算符有更多的优先级,那么为什么在这样的表达式(x++>=10)中,关系运算符首先计算,然后变量递增呢?
问题内容: 我正在尝试使ThreadPoolExecutor具有优先权。所以我定义一个 因此,关键是现在的队列引用。但是当我声明: 编译器在第一行给出错误: 构造函数ThreadPoolExecutor(int,int,int,TimeUnit,PriorityBlockingQueue,FileAccess.mThreadFactory)是未定义的 ,只有一个快速修复程序: 将’queue’的类