我如何确定ANTLR 4用来解析表达式的规则?

问题描述 投票:0回答:1

我正在尝试创建Java类,从ANTLR 4创建的解析树中建立AST(在我的自定义类层次结构中的抽象语法树)。 我正在为一阶逻辑语言做这件事。https:/github.comantlrgrammars-v4blobmasterfolfol.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有一个或多个方法包含一个或多个公式,那么有2个方法 - 一个返回 FormulaContext 和其他回返 ArrayList<FormulaContext>. 没有更有价值的方法。

假设我有 FormulaContext 例如,我想进一步检查它。我应该怎么做呢? 我的期望是知道这个实例的规则。FormulaContext 的构造,然后我就知道哪些方法(比如说 formula(0); bin_connective(); formula(1); 我知道哪些方法(例如第一条规则)可以调用,而且我可以安全地调用这些方法。

问题是--我找不到决定用于构造的规则的方法,这是非终结性的吗?当然,我可以尝试为每条规则创建测试方法(例如testRule1, testRule2, ...),它调用上述方法并检查公式、NOT、bin_connective和所有这些子项的可用性,然后可以推断出使用的是哪条规则,然后相应地进一步消化考虑中的实例。

但这样的测试方法是否正确呢?我不相信这些都是如此粗糙的。此外,这样的测试方法可以由ANTLR 4自动生成,有所有的信息,但还是--ANTLR没有这样的功能。

那么--对于Non Terminal类,最好的做法是什么?

java antlr antlr4 abstract-syntax-tree
1个回答
3
投票

你可以 标明你的替代品 使用 # 像这样的操作符。

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

这样就可以创建班级 NegationContext 等继承自 FormulaContext. 因此,你可以根据你得到的类来判断选择了哪种选择。在访问者和监听者中,你现在可以过载 visitNegation(NegationContext) 等来访问该特定类型的配方。

© www.soinside.com 2019 - 2024. All rights reserved.