java - 如何确定 ANTLR 4 用于解析表达式的规则?
问题描述
我正在尝试从 ANTLR 4 创建的解析树创建构建 AST(我的自定义类层次结构中的抽象语法树)的 Java 类。我这样做是为了一阶逻辑https://github.com/antlr /grammars-v4/blob/master/fol/fol.g4
具体来说,我正在寻找以下规则formula
:
formula
: formula bin_connective formula
| NOT formula bin_connective formula
| NOT formula
| FORALL LPAREN variable RPAREN formula
| EXISTS LPAREN variable RPAREN formula
| pred_constant LPAREN term (separator term)* RPAREN
| term EQUAL term
;
ANTLR 4 生成了以下类formula
,我在这里仅部分介绍(为简洁起见,我删除了实现 - 它是标准的,由 ANTLR 4 生成,只是调用一些技术方法):
public static class FormulaContext extends ParserRuleContext {
public TerminalNode NOT() { ... }
public List<FormulaContext> formula() { ... }
public FormulaContext formula(int i) { ... }
public Bin_connectiveContext bin_connective() { ... }
public TerminalNode FORALL() { ... }
public TerminalNode LPAREN() { ... }
public VariableContext variable() { ... }
public TerminalNode RPAREN() { ... }
public TerminalNode EXISTS() { ... }
public Pred_constantContext pred_constant() { ... }
public List<TermContext> term() { ... }
public TermContext term(int i) { ... }
public List<SeparatorContext> separator() { ... }
public SeparatorContext separator(int i) { ... }
public TerminalNode EQUAL() { ... }
public FormulaContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_formula; }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof FOLListener ) ((FOLListener)listener).enterFormula(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof FOLListener ) ((FOLListener)listener).exitFormula(this);
}
}
所以 - 可以看到:如果有 rule, that contains NOT
,那么就有 method TerminalNode NOT
,是否有一个或多个方法包含一个或多个公式,那么有 2 个方法 - 一个 returnFormulaContext
和另一个 return ArrayList<FormulaContext>
。没有比这更有价值的方法了。
让我们假设我有FormulaContext
实例,我想进一步检查它。我应该怎么办?我的期望是知道构造这个实例所依据的规则,FormulaContext
然后我知道我可以调用哪些方法(formula(0); bin_connective(); formula(1);
第一个规则是等),我可以安全地调用这些方法。
问题是 - 我找不到确定用于构造的规则的方法是这个非终结符吗?当然,我可以尝试为每个规则(例如 testRule1、testRule2、...)创建测试方法,它调用上述方法并检查公式、NOT、bin_connective 和所有这些子术语的可用性,然后可以推断出哪个规则是使用,然后相应地进一步消化正在考虑的实例。
但是这样的测试方法是正确的方法吗?我不敢相信这一切都是那么粗暴。此外,这些测试方法可以由 ANTLR 4 自动生成,它们的所有信息都有,但仍然 - ANTLR 没有这样的功能。
那么-推断非终端类规则的最佳实践是什么?
解决方案
您可以使用这样的运算符标记您的替代方案#
:
formula
: formula bin_connective formula #BinaryFormula
| NOT formula #Negation
| ...
;
这将创建NegationContext
继承自FormulaContext
. 因此,您可以根据您获得的课程来判断选择了哪个替代方案。在访问者和听众中,您现在可以重载visitNegation(NegationContext)
等以访问该特定类型的公式。
推荐阅读
- c++ - 内置 log2(x) 函数和迭代除以 2 有什么区别?
- javascript - 如何获取“VEVENT”对象的所有属性?
- swift - 如何为 DateComponentsFormatter 制作真正的缩写单位样式?
- reactjs - Redux devtools 编码指南可以很好地配合时间旅行调试?
- css - 如何将引导水平形式转换为垂直形式?
- matlab - 如何在 Matlab 中正确设置多个 ODE 的求解?
- html - 独特按钮形状的边框样式
- r - 在 R 中交换字符串的大小写
- java - 在Android中将txt文件数据与输入字符串进行比较
- angular - 尽管从服务器获取图像,但无法显示图像。没有任何要调试的相关错误