为什么在ANTLR4规则中标记外部备选方案会阻止访问者/侦听器中的此规则可用?
问题描述:
对于像下面这样的规则:为什么在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。
答
如上所述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)
在您的处置,以达到相同的。
至少对我来说,这似乎是一个错误。它应该是可配置的。在当我解析的代码仅部分有效。我的情况下,父上下文将被确认(例如在解析树可视化显示),而不是替代品 - 这意味着他们的回调将永远在听者/参观者被击中,但父母的规则是,但它不能被访问。令人难以置信的令人沮丧的是,因为解析器确实能够完全识别你想要的内容,但它只是逗你玩笑,几乎嘲弄你。 – predi
无论规则alt是否被标记,如果解析器都没有匹配,那么规则节点将不会被添加到分析树中。根本没有规则或标记的上下文访问。即使在分解规则示例中,如果'lastParamVarargs'和'lastParamBasic'规则都不匹配,那么'lastFormalParameter'规则将不匹配。解析器因此不会在解析树中生成'LastFormalParameterContext'节点 - 访问者将无法访问。 – GRosenberg