java如何确定ANTLR 4解析表达式所使用的规则?
我试图创建一个Java类,该类从Antlr4创建的解析树中构建AST(自定义类层次结构中的抽象语法树)。我这样做是为了一阶逻辑语言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);
}
}
因此,我们可以看到:如果有规则,它包含NOT
,那么有方法TerminalNode NOT
,有一个或多个方法包含一个或多个公式,那么有两个方法-一个返回FormulaContext
,另一个返回ArrayList<FormulaContext>
。没有比这更有价值的方法了
假设我有FormulaContext
实例,我想进一步检查它我该怎么办我的期望是知道FormulaContext
的这个实例是根据什么规则构造的,然后我知道我可以调用哪些方法(第一个规则是e.t.formula(0); bin_connective(); formula(1);
),我可以安全地调用这些方法
问题是,我找不到确定用于构造的规则的方法,这是非终结的吗?当然,我可以尝试为每个规则创建测试方法(例如testRule1、testRule2等)调用上述方法并检查formula、NOT、bin_Connection和所有这些子术语的可用性,然后可以推断使用哪个规则,然后相应地进一步消化考虑中的实例
但这样的测试方法是正确的吗?我不能相信这一切都是如此粗鲁。此外,这些测试方法可以由ANTLR 4自动生成,它们有所有的信息,但ANTLR仍然没有这样的功能
那么,为非终结类推断规则的最佳实践是什么
# 1 楼答案
您可以像这样使用
#
操作符label your alternatives:这将创建从
FormulaContext
继承的类NegationContext
等。因此,你可以根据你得到的课程来判断选择了哪个选项。在访客和听众中,您现在可以重载visitNegation(NegationContext)
等来访问特定类型的公式