有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    您可以像这样使用#操作符label your alternatives

    formula
        : formula bin_connective formula #BinaryFormula
        | NOT formula                    #Negation
        | ...
        ;
    

    这将创建从FormulaContext继承的类NegationContext等。因此,你可以根据你得到的课程来判断选择了哪个选项。在访客和听众中,您现在可以重载visitNegation(NegationContext)等来访问特定类型的公式