为什么在ANTLR4规则中标记外部替代项会阻止此规则在访问者/监听者中可用?

时间:2017-06-14 18:55:58

标签: java antlr4

对于以下规则:

lastFormalParameter
        :       variableModifier* unannType annotation* ELLIPSIS variableDeclaratorId #LastParamVarargs
        |       formalParameter #LastParamBasic
        ;

替代品标有(#),为什么生成的访问者/听众不会包含visitLastFormalParameter / enterLastFormalParameter / exitLastFormalParameter方法来覆盖用户代码?只能覆盖外部替代标签的方法。有没有办法让工具生成缺失的方法,而不是用实际规则替换标记的替代方法(下面)?

lastFormalParameter
        :       lastParamVarargs
        |       lastParamBasic
        ;
lastParamVarargs
        :       variableModifier* unannType annotation* ELLIPSIS variableDeclaratorId
        ;
lastParamBasic
        :       formalParameter 
        ;

这是4.7。

2 个答案:

答案 0 :(得分:0)

我在2天前在another SO question解释了这一点。这里带标签的要点是规则上下文被替换为每个alt的单独上下文。

答案 1 :(得分:0)

here和@ MikeLischke所述,这是正常的。

您仍然可以访问或侦听通过实施通用回调并委托给"假冒"删除的规则。一,如果你需要实现所有替代方案共有的功能。

例如,在访问者中,您将覆盖为每个规则调用的visit(ParseTree),然后检查它是否代表目标父规则。它仍然是解析树的一部分,但是作为实际命中规则的超类(标记的备选方案之一)。

@Override
public Object visit(ParseTree tree) {
    if (tree instanceof LastFormalParameterContext) {
        return visitLastFormalParameterContext((LastFormalParameterContext) tree);
    }
    return super.visit(tree);
}

private Object visitLastFormalParameterContext(LastFormalParameterContext ctx) {
    // ...
    return null;
}

在听众中,您可以使用enterEveryRule(ParserRuleContext)exitEveryRule(ParserRuleContext)来实现相同目标。