我已经定义了我的语言的BNF,并且不知道如何从它设计一个AST。
例如,从我的BNF的前几行:
<program> ::= <import declarations>? <class declaration>?
<import declarations> ::= <import declaration> | <import declarations> <import declaration>
<class declaration> ::= class <identifier> <class body>
<import declaration> ::= import <type name> ';'我如何从我的AST中表达出来呢?我应该这样设计它吗?
typedef vector<ImportDeclaration*> ImportDeclarationList;
class Program {
ImportDeclarationList importDeclarations;
ClassDeclaration classDeclaration;
};
class ImportDeclaration {
TypeName typeName;
};
class ClassDeclaration {
Identifier identifer;
ClassBody classbody;
};我需要在thess类之间添加一些继承吗?
有没有一些关于如何从BNF设计AST的书?
发布于 2012-10-27 20:02:02
您只需实现一个树数据结构。这意味着您将需要某个类,比如Node,AST的所有其他可能元素都必须从这些类继承。然后,您可以使用成员指针(Node*)。如果子代的数量可能不同,您可以将它们存储在std::vector中。例如:对于一个非常简单的产品(假设IntLiteral是一个终端):
Addition := IntLiteral + IntLiteral可以为AST编写以下代码:
struct Node {
virtual Node* clone() { return new Node(*this);};
virtual ~Node() {}
};
class IntLiteral : Node {
int value;
public:
IntLiteral(int v) : value(v) {}
virtual IntLiteral* clone()
{
return new IntLiteral(*this);
}
};
class Addition : Node {
Node* left;
Node* right;
public:
Addition(Node* l, Node* r)
: Node(), left(l->clone()), right(r->clone()) {}
virtual Addition* clone()
{
return new Addition(*this);
}
};假设您是手动实现的,您可以在解析器代码的接受函数中将节点添加到根节点(在本例中为add *)。
实际上,您可能希望每个节点都有一个generate函数。或者,这可能是一个更好的想法,您将需要访问器和树遍历器来生成代码。
有相当多的关于解析器的书,其中之一是经典的“龙书”,尽管那里的重点实际上是编译器。
https://stackoverflow.com/questions/13008347
复制相似问题