私は 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 に関する情報が必要です。この問題を解決する方法はありますか?それとも、すべてを 1 つのヘッダーに保持する必要がありますか?