有没有办法解决像

时间:2017-10-28 02:06:19

标签: c++ oop linker-errors cyclic-dependency

我正在编写C编译器,我正在进行语法分析。我有一个语法树节点的层次结构。我想重构代码,但我不能解决这样的依赖。

例如,这是一个包含所有预先声明的类和抽象Node类的标题:

#ifndef TINY_C_COMPILER_NODE_H
#define TINY_C_COMPILER_NODE_H

#include "../token.h"
#include <ostream>

class PostfixExprNode;
class IdNode;
class ConstNode;
class StringLiteralNode;
class FloatConstNode;
class IntConstNode;
class PostfixIncrementNode;
class PostfixDecrementNode;
class StructureOrUnionMemberAccessNode;
class StructureOrUnionMemberAccessByPointerNode;
class ArrayAccess;

class Node
{
public:
    virtual void Print(std::ostream &os, int depth) = 0;
};

#endif //TINY_C_COMPILER_NODE_H 

primary_expr.h:

#ifndef TINY_C_COMPILER_PRIMARY_EXPR_H
#define TINY_C_COMPILER_PRIMARY_EXPR_H

#include "node.h"

// primary-expr ::= id | constant | string-literal | (expr)

class PrimaryExprNode: public PostfixExprNode
{
public:
    void Print(std::ostream &os, int depth) override = 0;
};

class IdNode: public PrimaryExprNode
{
public:
    explicit IdNode(Token *token);
    void Print(std::ostream &os, int depth) override;
private:
    Token *token;
};

class ConstNode: public PrimaryExprNode
{
public:
    explicit ConstNode(Token *token): token(token) {}
    void Print(std::ostream &os, int depth) override = 0;
protected:
    Token *token;
};

class IntConstNode: public ConstNode
{
public:
    explicit IntConstNode(Token *token);
    void Print(std::ostream &os, int depth) override;
};

class FloatConstNode: public ConstNode
{
public:
    explicit FloatConstNode(Token *token);
    void Print(std::ostream &os, int depth) override;
};

class StringLiteralNode: public PrimaryExprNode
{
public:
    explicit StringLiteralNode(Token *token);
    void Print(std::ostream &os, int depth) override;
private:
    Token *token;
};


#endif //TINY_C_COMPILER_PRIMARY_EXPR_H

postfix_expr.h:

#ifndef TINY_C_COMPILER_POSTFIX_EXPR_H
#define TINY_C_COMPILER_POSTFIX_EXPR_H

#include "node.h"

//
//postfix-expr ::= primary-expr | postfix-expr [expr] | postfix-expr (`argument-expr-list)
//                | postfix-expr . id | postfix-expr -> id | postfix-expr ++ | postfix-expr --
//                | (type-name) {initializer-list} | (type-name) {initializer-list, }

class PostfixExprNode: public Node
{
public:
    virtual void Print(std::ostream &os, int depth) = 0;
};

class PostfixIncrementNode: public PostfixExprNode
{
public:
    explicit PostfixIncrementNode(PostfixExprNode *node): node(node) {}
    virtual void Print(std::ostream &os, int depth);
private:
    PostfixExprNode *node;
};

class PostfixDecrementNode: public PostfixExprNode
{
public:
    explicit PostfixDecrementNode(PostfixExprNode *node): node(node) {}
    virtual void Print(std::ostream &os, int depth);
private:
    PostfixExprNode *node;
};


class StructureOrUnionMemberAccessNode: public PostfixExprNode
{
public:
    StructureOrUnionMemberAccessNode(PostfixExprNode *structureOrUnion, IdNode *member): member(member),
                                                                                         structureOrUnion(structureOrUnion) {}

    void Print(std::ostream &os, int depth) override;
private:
    PostfixExprNode *structureOrUnion;
    IdNode *member;
};

class StructureOrUnionMemberAccessByPointerNode: public PostfixExprNode
{
public:
    StructureOrUnionMemberAccessByPointerNode(PostfixExprNode *structureOrUnion, IdNode *member): member(member),
                                                                                                  structureOrUnion(structureOrUnion) {}

    void Print(std::ostream &os, int depth) override;
private:
    PostfixExprNode *structureOrUnion;
    IdNode *member;
};

class ArrayAccess: public PostfixExprNode
{
public:
    ArrayAccess(PostfixExprNode *left, PostfixExprNode *inBrackets): left(left), inBrackets(inBrackets) {}
    void Print(std::ostream &os, int depth) override;
private:
    PostfixExprNode *left, *inBrackets;
};

#endif //TINY_C_COMPILER_POSTFIX_EXPR_H

问题是PrimaryExprNode及其继承者需要完整声明PostfixExprNode,因此需要包含primary_expr.h。另一方面,StructureOrUnionMemberAccessNode需要有关Print函数中IdNode的信息。那么有什么方法可以解决这个问题吗?或者我只需将所有内容保存在一个标题中?

0 个答案:

没有答案