parsing - 如何避免带有可选右手操作数的规则中的歧义?
问题描述
众所周知,ANTLR4 会自动进行左递归优化。但是当最后一个操作数是可选的时如何避免歧义呢?
以下面的简化语法为例:
grammar Example;
root: expression EOF;
expression: binaryExpression;
binaryExpression
: binaryExpression 'and' binaryExpression
| binaryExpression 'or' binaryExpression
| 'no' ID 'in' ID ('satisfies' expression)?
| '(' expression ')'
| OPERAND
;
OPERAND: 'true' | 'false';
ID: [a-z]+;
WS: (' ' | '\r' | '\t')+ -> channel(HIDDEN);
此文法接受表达式no x in y
和no x in y satisfies condition
。('satisfies' expression)?
但是,在左重构期间不考虑可选子规则。结果,输入no x in y satisfies true and false
被报告为歧义输入:
解析器假设有两棵可行的树no x in y satisfies (true and false)
和(no x in y satisfies true) and false
,但只有第一棵树应该被认为是可行的解释。
有人可能会争辩说我可以重写语法如下:
binaryExpression
: binaryExpression 'and' binaryExpression
| binaryExpression 'or' binaryExpression
| 'no' ID 'in' ID 'satisfies' expression
| 'no' ID 'in' ID
| '(' expression ')'
| OPERAND
;
ID
尽管它“有效”,但除了对性能的影响之外,错误报告不再有用,因为在解析器到达令牌之前无法推断接下来会发生什么。
有没有办法重构语法以明确指定量词的 RHS 中的表达式应始终优先?
解决方案
推荐阅读
- php - 多类型模板的诗篇注释
- kubernetes - Kubernetes containerd - 无法从私有注册表中提取图像
- jquery - (index):49 Uncaught SyntaxError: missing ) 在参数列表之后
- java - 如何将此 for 循环转换为正确的 while 循环?
- c# - 无法从 GUIGridView 读取所有行。34 行后变为空白
- python - 是否可以将使用 plt.show() 获得的窗口保存为可导航格式而不是简单的图像?
- swiftui - SwiftUI 中途恢复导航流程
- flurry - Flurry Analytics 在中国的访问
- python - 如何在 Kubernetes 的单个 pod 中为单个容器提供唯一的主机名?
- eclipse - Eclipse 重新启动时删除了 Eclipse 首选项