如何在C#中为抽象语法树编写访问者模式?
我必须写一个访问者模式来导航AST。 任何人都可以告诉我更多我将如何开始写它? 据我所知,AST中的每个节点都有visit()方法(?),它会以某种方式被调用(从哪里?)。 这总结了我的理解。 为了简化一切,假设我有节点Root,Expression,Number,Op,树看起来像这样:
Root | Op(+) / / Number(5) Op(*) / / / Number(2) Number(444)
模式访问者是一种设计模式,允许您在解析树上实现任意操作(实现为访问者)(例如,类型检查),而无需修改解析树的节点的实现。
它可以通过以下方式实现(我正在使用伪代码):
首先,您需要定义所有节点必须实现的树节点的基类。
abstract class VisitableNode { abstract void accept( Visitor v ); }
节点类必须实现的唯一方法是accept方法。
然后,您应该定义解析树的访问者节点的基类。
abstract class Visitor { abstract void visit( Root rootNode ); abstract void visit( Op opNode ); abstract void visit( Number number ); }
请注意,访问者的基类仅针对您的解析树,并且对于您在解析树中定义的每个节点类型都应该有一个访问方法。
然后,您应该让您的节点类实现以下列方式扩展VisitableNode类:
class Root : VisitableNode { [...] void accept( Visitor v ) { v.visit(this); } } class Op : VisitableNode { [...] void accept( Visitor v ) { v.visit(this); } } class Number : VisitableNode { [...] void accept( Visitor v ) { v.visit(this); } }
现在你的解析树结构不应该改变,你可以自由地实现任意数量的访问者(操作)。
为了进行类型检查,您必须将Number类中的类型与您的值一起存储,否则为您支持的每种类型都有一个Number类:NumberFloat,NumberInteger,NumberDouble等。
例如,假设您有一种方法可以从Number类中推断出值的静态类型。
我还假设您可以通过方法getChild(int childIndex)访问节点的子节点。
最后,我将使用一个类Type,它通常表示您想要支持的静态类型(如Float,Integer等…)。
class TypeCheckVisitor : Visitor { // Field used to save resulting type of a visit Type resultType; void visit( Root rootNode ) { rootNode.getChild(0).accept( this ); } void visit( Op opNode ) { opNode.getChild(0).accept( this ); Type type1 = resultType; opNode.getChild(1).accept( this ); Type type2 = resultType; // Type check if( !type1.isCompatible( type2 ) ){ // Produce type error } // Saves the return type of this OP (ex. Int + Int would return Int) resultType = typeTableLookup( opNode.getOperator(), type1, type2 ); } void visit( Number number ) { // Saves the type of this number as result resultType = number.getType(); } }
然后,您可以以类似于以下的方式将Type类实现为枚举:
enum Type { Double, Float, Integer; boolean isCompatible(Type type1, Type type2){ // Lookup some type table to determine types compatibility } }
最后,您只需要实现类型表和运算符表。
编辑:在访问递归中,使用您想要重复的节点的accept方法重复实际上是正确的。
至于用法,您可以通过以下方式对解析树的根节点执行类型检查(并同时确定表达式的类型):
TypeCheckVisitor v = new TypeCheckVisitor(); rootNode.accept( v ); print( "Root type is: " + v.resultType );
您也可以以相同的方式键入 – 检查与根不同的解析树的任意节点。
上述就是C#学习教程:如何在C#中为抽象语法树编写访问者模式?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1000959.html