首页 > 解决方案 > ANTLR:不能链接子规则方法调用

问题描述

我试图在使用 ANTLR 访问者时找到某个标记的第一个字符的列位置。这是我的规则(为演示而简化):

expExpr : PLUS expExprTail ;
expExprTail : EXP expExpr       #expExprTailOpLabel
  | /* epsilon */               #expExprTailEpsLabel
  ;

(请注意,我正在为 中的两个规则使用标签expExprTail

我想在规则中找到给定标记的位置expExpr是我确定发生错误的时候)。但是令牌是expExpr通过规则访问的规则中的第一个令牌expExprTail

我的想法是(在访问者中)可以像这样访问它:

  @Override public void visitExpExpr(LangParser.ExpExprContext ctx) { 
    ExpExprContext expExprContext = ctx.expExprTail().expExpr();
  }

但是,此代码不会编译,并且 ANTLR 报告它在类上找不到expExpr()方法。ExpExprTailContext怎么可能,规则中何时expExpr引用了expExprTail规则?

标签: antlrantlr4

解决方案


给定解析器规则foo

foo
 : A
 | B
 ;

生成以下方法:

T visitFoo(TParser.FooContext ctx)

但是当向这个解析器规则添加标记的替代项时:

foo
 : A  #altFooA
 | B  #altFooB
 ;

visitFoo不再可用(也不再可用TParser.FooContext!),并将被以下规则取代:

T visitAltFooA(TParser.AltFooAContext ctx)

T visitAltFooB(TParser.AltFooBContext ctx) 

如果您想直接访问exprExpr类似 的规则ctx.expExprTail().expExpr(),则必须删除 alt 标签:

expExpr : PLUS expExprTail ;
expExprTail : EXP expExpr
  | /* epsilon */
  ;

推荐阅读