我想使用訪問者模式來執行我的編譯器的AST的操作,但我似乎無法弄清楚將正常工作的實現。訪問者模式爲AST
AST類摘錄:
class AstNode
{
public:
AstNode() {}
};
class Program : public AstNode
{
public:
std::vector<std::shared_ptr<Class>> classes;
Program(const std::vector<std::shared_ptr<Class>>&);
void accept(AstNodeVisitor& visitor) const { visitor.visit(*this); }
};
class Expression : public AstNode
{
public:
Expression() {}
};
class Method : public Feature
{
public:
Symbol name;
Symbol return_type;
std::vector<std::shared_ptr<Formal>> params;
std::shared_ptr<Expression> body;
Method(const Symbol&, const Symbol&, const std::vector<std::shared_ptr<Formal>>&,
const std::shared_ptr<Expression>&);
feature_type get_type() const;
};
class Class : public AstNode
{
public:
Symbol name;
Symbol parent;
Symbol filename;
std::vector<std::shared_ptr<Feature>> features;
Class(const Symbol&, const Symbol&, const Symbol&,
const std::vector<std::shared_ptr<Feature>>&);
};
class Assign : public Expression
{
public:
Symbol name;
std::shared_ptr<Expression> rhs;
Assign(const Symbol&, const std::shared_ptr<Expression>&);
};
遊客(部分實現):
class AstNodeVisitor
{
public:
virtual void visit(const Program&) = 0;
virtual void visit(const Class&) = 0;
virtual void visit(const Attribute&) = 0;
virtual void visit(const Formal&) = 0;
virtual void visit(const Method&) = 0;
};
class AstNodePrintVisitor : public AstNodeVisitor
{
private:
size_t depth;
public:
void visit(const Program& node) {
for (auto cs : node.classes)
visit(*cs);
}
void visit(const Class&);
void visit(const Attribute&);
void visit(const Formal&);
void visit(const Method&);
};
我如何使用它:
AstNodePrintVisitor print;
ast_root->accept(print); // ast_root is a shared_ptr<Program>
問題:
的方法節點包含一個bo類型Expression的dy成員 - 這是一個基類。我將如何訪問它?
我想也許我可以簡單地爲每個AST節點編寫一個接受方法,然後進行遍歷。 (即,不是在訪問者中調用visit(),而是在可訪問的調用訪問(* this)中調用accept(),以便調用將是多態的,訪問者的正確訪問方法將被調用。但是,如果我這樣做,我將無法選擇自頂向下(操作然後遞歸)或自下而上(遞歸操作),因爲我必須僅選擇一個。因此,我的意思是一個PrintVisitor例如需要一個AST自頂向下遍歷,但TypeCheck需要自下而上的方法。
有沒有辦法解決這個問題?或者我過度設計了一些東西?現在我認爲最快的方法就是實現方法在節點本身。
或者只是使用野牛。 – 2012-07-13 05:55:21
@ H2CO3是的,我使用Bison進行解析,這就是AST的創建過程。我目前正在執行語義分析(類型檢查,範圍,..),並且需要考慮代碼gen。 – 2012-07-13 06:02:58
哦OK :)順便說一句,你不能使用自頂向下的方法進行類型檢查嗎? – 2012-07-13 06:08:30