C++实现通用AST语法树结构

class ASTNode;
typedef std::map<std::string, std::string> PropertyContainer;
typedef std::vector<ASTNode> ChildContainer;
class ASTNode: PropertyContainer, ChildContainer
{
public:
    ASTNode(){}
    ASTNode(std::initializer_list<PropertyContainer::value_type> list)
        : PropertyContainer (list)
    {

    }

    ChildContainer::reference operator[](size_t index) _GLIBCXX_NOEXCEPT
    {
        return std::vector<ASTNode>::operator[](index);
    }

    ASTNode &operator << (const ASTNode &node) _GLIBCXX_NOEXCEPT
    {
        push_back(node); return *this;
    }

    size_t size() const _GLIBCXX_NOEXCEPT
    {
        return std::vector<ASTNode>::size();
    }

    template <typename Funct_>
    void recursionChilds(Funct_ f) const _GLIBCXX_NOEXCEPT {
        foreachChilds([=](ChildContainer::const_reference ref) {
            ref.recursionChilds(f);
        });
    }

    template <typename Funct_>
    void recursion(Funct_ f) const _GLIBCXX_NOEXCEPT {
        f(*this);
        recursionChilds(f);
    }

    template <typename Funct_>
    void recursion(Funct_ f, int &level) const _GLIBCXX_NOEXCEPT {
        f(*this);
        level ++;
        foreachChilds([&](ChildContainer::const_reference ref) {
            ref.recursion(f, level);
        });
        level --;
    }

    template <typename Funct_>
    void foreachChilds(Funct_ f) const _GLIBCXX_NOEXCEPT {
        std::for_each(ChildContainer::begin(), ChildContainer::end(), f);
    }

    template <typename Funct_>
    void foreachPropertys(Funct_ f) const _GLIBCXX_NOEXCEPT {
        std::for_each(PropertyContainer::begin(), PropertyContainer::end(), f);
    }

    PropertyContainer::mapped_type &operator[](const std::string &key) _GLIBCXX_NOEXCEPT
    {
        return PropertyContainer::operator[](key);
    }

    std::vector<PropertyContainer::key_type> keys() const _GLIBCXX_NOEXCEPT {
        std::vector<PropertyContainer::key_type> ret;
        auto itera = PropertyContainer::begin();
        while (itera != PropertyContainer::end()) {
            ret.push_back(itera->first);
            itera ++;
        }
        return ret;
    }

    std::vector<PropertyContainer::mapped_type> values() const _GLIBCXX_NOEXCEPT {
        std::vector<PropertyContainer::mapped_type> ret;
        auto itera = PropertyContainer::begin();
        while (itera != PropertyContainer::end()) {
            ret.push_back(itera->second);
            itera ++;
        }
        return ret;
    }

    size_t count() const _GLIBCXX_NOEXCEPT
    {
        return PropertyContainer::size();
    }

    void dump()
    {
        int level = 0;
        recursion([&](ChildContainer::const_reference ref){
            auto getHead = [=](int level) -> std::string {
                int c = 0; std::string ret;
                while (c < level) {
                    ret += " ";
                    c++;
                }
                return ret;
            };
            std::cout << getHead(level);
            ref.foreachPropertys([&](PropertyContainer::const_reference ref)
            {
                std::cout << ref.first << ":" << ref.second << " ";
            });
            std::cout << std::endl;
        }, level);
    }

    void dumpSave(const std::string &file)
    {
        std::ofstream ofstream;
        ofstream.open(file);

        int level = 0;
        recursion([&](ChildContainer::const_reference ref){
            auto getHead = [=](int level) -> std::string {
                int c = 0; std::string ret;
                while (c < level) {
                    ret += " ";
                    c++;
                }
                return ret;
            };
            ofstream << getHead(level);
            ref.foreachPropertys([&](PropertyContainer::const_reference ref)
            {
                ofstream << ref.first << ":" << ref.second << " ";
            });
            ofstream << std::endl;
        }, level);
    }

    void dumpLoad(const std::string &file)
    {

    }
};


ASTNode genRoot() {
    ASTNode root{{"name", "root"}};
    ASTNode one{{"name", "public"},{"start", "[0:0]"}};
    ASTNode two{{"name", "class"},{"start", "[0:7]"}};
    ASTNode three{{"name", "Hello"},{"start", "[0:13]"}};
    root << one << two << three;
    root[0] << one << two << three;
    root[0][0] << one << two << three;
    root[0][0][0] << one << two << three;
    root[1] << one << two << three;
    root[2] << one << two << three;
    return root;
}

int main(int argc, char *argv[])
{
    ASTNode root = genRoot();
    root.dump();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值