Compiler construction 如何从BNF设计抽象语法树(AST)
我已经定义了我的语言的BNF,不知道如何用它来设计AST 例如,从我的BNF的前几行:Compiler construction 如何从BNF设计抽象语法树(AST),compiler-construction,translation,abstract-syntax-tree,bnf,Compiler Construction,Translation,Abstract Syntax Tree,Bnf,我已经定义了我的语言的BNF,不知道如何用它来设计AST 例如,从我的BNF的前几行: <program> ::= <import declarations>? <class declaration>? <import declarations> ::= <import declaration> | <import declarations> <import declaration> <class decl
<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;
};
typedef向量导入删除列表;
班级计划{
ImportDeclarationList importDeclarations;
类声明类声明;
};
类导入声明{
类型名类型名;
};
类声明{
标识符标识符;
类体类体;
};
我需要在这些类中添加一些继承吗
有一些关于如何从BNF设计AST的书吗?您只需要实现一个树数据结构。这意味着您将需要某个类,例如节点,AST的所有其他可能元素都必须从该类继承。然后可以使用成员指针(节点*)。如果子对象的数量可能不同,则可以将它们存储在std::vector中。 对于一个非常简单的产品(假设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);
}
};
假设您是手工实现的,您可以在解析器代码的接受函数中将节点添加到根节点(在本例中为类型添加*)
实际上,您可能希望为每个节点使用generate
函数。或者,这可能是一个更好的主意,您将需要访问器和树遍历器来生成代码
有很多关于解析器的书,其中一本是经典的“龙之书”,尽管这里的重点实际上是编译器。节点需要包含一个“抽象”语法类别(通常接近许多规则的LHS)。有关AST与CST的讨论,以及为什么您可能希望节点包含具体的语法类别(例如,确切地说是规则的LHS,或叶子的具体名称),请参见。
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);
}
};