首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从BNF设计抽象语法树(AST)

如何从BNF设计抽象语法树(AST)
EN

Stack Overflow用户
提问于 2012-10-22 17:24:34
回答 1查看 2.8K关注 0票数 3

我已经定义了我的语言的BNF,并且不知道如何从它设计一个AST。

例如,从我的BNF的前几行:

代码语言:javascript
复制
<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中表达出来呢?我应该这样设计它吗?

代码语言:javascript
复制
typedef vector<ImportDeclaration*> ImportDeclarationList;

class Program {
    ImportDeclarationList importDeclarations;
    ClassDeclaration classDeclaration;
};

class ImportDeclaration {
    TypeName typeName;
};

class ClassDeclaration {
    Identifier identifer;
    ClassBody classbody;
};

我需要在thess类之间添加一些继承吗?

有没有一些关于如何从BNF设计AST的书?

EN

回答 1

Stack Overflow用户

发布于 2012-10-27 20:02:02

您只需实现一个树数据结构。这意味着您将需要某个类,比如Node,AST的所有其他可能元素都必须从这些类继承。然后,您可以使用成员指针(Node*)。如果子代的数量可能不同,您可以将它们存储在std::vector中。例如:对于一个非常简单的产品(假设IntLiteral是一个终端):

代码语言:javascript
复制
Addition := IntLiteral + IntLiteral

可以为AST编写以下代码:

代码语言:javascript
复制
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函数。或者,这可能是一个更好的想法,您将需要访问器和树遍历器来生成代码。

有相当多的关于解析器的书,其中之一是经典的“龙书”,尽管那里的重点实际上是编译器。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13008347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档