【问题标题】:How to design an Abstract Syntax Tree (AST) from BNF如何从 BNF 设计抽象语法树 (AST)
【发布时间】:2012-10-22 09:24:34
【问题描述】:

我已经定义了我的语言的 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;
};

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

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

【问题讨论】:

  • 节点需要包含一个“抽象”语法类别(通常接近许多规则的 LHS)。请参阅 stackoverflow.com/a/1916687/120163 了解 AST 与 CST 的讨论,以及为什么您可能希望节点包含具体的语法类别(例如,规则的 LHS 或叶子的具体名称)。

标签: compiler-construction translation abstract-syntax-tree bnf


【解决方案1】:

你只需要实现一个树形数据结构。这意味着您将需要某个类,例如 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);
    }
};

假设您是手动实现,您可以在解析器代码的接受函数中将节点添加到根节点(在本例中为 Addition* 类型)。

实际上,您可能希望每个节点都有一个generate 函数。或者,这可能是一个更好的主意,您将需要访问器和树遍历器来生成代码。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    相关资源
    最近更新 更多