当执行从用户程序流到从基类(HelloBaseVisitor(继承的重写访问者类(MyHelloVisitor(时,我正试图跟踪ANTLR访问者实现的执行路径。
据我所知,重写类(MyHelloVisitor(必须至少包含一个顶级语法规则的重写方法(在我的语法中称为"toprule"(。
Q1.重写类(MyHelloVisitor(是否必须始终包含语法起始规则的重写方法?
Q2.重写类(MyHelloVisitor(是否必须始终包含语法和基类中每个规则的重写方法?或者我有可能只覆盖一个感兴趣的方法吗?非常感谢。
以下是调用MyHelloVisitor(我的覆盖Visitor类(的用户程序的代码:
// create a visitor and walk the parse tree, collecting errors or results
var visitor = new MyHelloVisitor(); // inherits generic abstract n virtual methods
var ctx = Parser.toprule(); // this returns a context for the top rule
visitor.Visit(ctx);
当基类中的.Visit方法(如下所示(由MyHelloVisitor执行时,强制转换操作成功,并调用.VisitToprule方法。这就是为什么我认为重写类(MyHelloVisitor(必须至少包含语法中"Toprule"的重写方法。
public virtual Result Visit([NotNull] IParseTree tree) =>
tree.Accept<Result>((IParseTreeVisitor<Result>) this);
....
public partial class TopruleContext : ParserRuleContext {
public override TResult Accept<TResult>(IParseTreeVisitor<TResult> visitor) {
IHelloVisitor<TResult> typedVisitor = visitor as IHelloVisitor<TResult>;
if (typedVisitor != null) return typedVisitor.VisitToprule(this);
else return visitor.VisitChildren(this);
}
}
Q1。重写类(MyHelloVisitor(是否必须始终包含语法起始规则的重写方法?
不,您可以有一个空的自定义访问者来扩展(生成的(基本访问者。还要注意,开始规则(通常是语法中的第一个规则和/或以EOF
结尾的语法分析器规则(与语法中的另一个语法分析器规则之间没有实际区别。
Q2.重写类(MyHelloVisitor(是否必须始终为语法和基类中的每个规则包含一个重写方法?或者我有可能只覆盖一个感兴趣的方法吗?
不,您不需要覆盖每个规则。然而,访问者通常用于完成解析树的遍历并返回一些内容。这通常意味着所有访问方法都有一个自定义实现。如果你有选择地想";听";对于像进入或退出特定解析器规则/节点这样的事件,侦听器可能是您想要的:https://github.com/antlr/antlr4/blob/master/doc/listeners.md