common.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,588 行 · 第 1/3 页

HPP
1,588
字号
        swap(t1, t2);    }}//////////////////////////////////template <typename IteratorT, typename NodeFactoryT, typename T>class tree_match : public match<T>{public:    typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t;    typedef typename node_factory_t::node_t parse_node_t;    typedef tree_node<parse_node_t> node_t;    typedef typename node_t::children_t container_t;    typedef typename container_t::iterator tree_iterator;    typedef typename container_t::const_iterator const_tree_iterator;    typedef T attr_t;    typedef typename boost::call_traits<T>::param_type      param_type;    typedef typename boost::call_traits<T>::reference       reference;    typedef typename boost::call_traits<T>::const_reference const_reference;    tree_match()    : match<T>(), trees()    {}    explicit    tree_match(std::size_t length)    : match<T>(length), trees()    {}    tree_match(std::size_t length, parse_node_t const& n)    : match<T>(length), trees()    {         trees.push_back(node_t(n));     }    tree_match(std::size_t length, param_type val, parse_node_t const& n)    : match<T>(length, val), trees()    {#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)        trees.reserve(10); // this is more or less an arbitrary number...#endif        trees.push_back(node_t(n));    }    // attention, these constructors will change the second parameter!    tree_match(std::size_t length, container_t& c)    : match<T>(length), trees()    {         impl::cp_swap(trees, c);    }    tree_match(std::size_t length, param_type val, container_t& c)    : match<T>(length, val), trees()    {        impl::cp_swap(trees, c);    }    template <typename T2>    tree_match(match<T2> const& other)    : match<T>(other), trees()    {}    template <typename T2, typename T3, typename T4>    tree_match(tree_match<T2, T3, T4> const& other)    : match<T>(other), trees()    { impl::cp_swap(trees, other.trees); }    template <typename T2>    tree_match&    operator=(match<T2> const& other)    {        match<T>::operator=(other);        return *this;    }    template <typename T2, typename T3, typename T4>    tree_match&    operator=(tree_match<T2, T3, T4> const& other)    {        match<T>::operator=(other);        impl::cp_swap(trees, other.trees);        return *this;    }    tree_match(tree_match const& x)    : match<T>(x), trees()    {        // use auto_ptr like ownership for the trees data member        impl::cp_swap(trees, x.trees);    }    tree_match& operator=(tree_match const& x)    {        tree_match tmp(x);        this->swap(tmp);        return *this;    }    void swap(tree_match& x)    {        match<T>::swap(x);        impl::cp_swap(trees, x.trees);    }    mutable container_t trees;};#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)template <typename IteratorT, typename NodeFactoryT, typename T>inline std::ostream&operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m){    typedef        typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator        iterator;    o << "(length = " << (int)m.length();    int c = 0;    for (iterator i = m.trees.begin(); i != m.trees.end(); ++i)    {        o << " trees[" << c++ << "] = " << *i;    }    o << "\n)";    return o;}#endif//////////////////////////////////struct tree_policy{    template <typename FunctorT, typename MatchT>    static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/)    {}    template <typename MatchT, typename Iterator1T, typename Iterator2T>    static void group_match(MatchT& /*m*/, parser_id const& /*id*/,            Iterator1T const& /*first*/, Iterator2T const& /*last*/)    {}    template <typename MatchT>    static void concat(MatchT& /*a*/, MatchT const& /*b*/)    {}};//////////////////////////////////template <    typename MatchPolicyT,    typename IteratorT,    typename NodeFactoryT,    typename TreePolicyT,     typename T>struct common_tree_match_policy : public match_policy{    common_tree_match_policy()    {    }    template <typename PolicyT>    common_tree_match_policy(PolicyT const & policies)        : match_policy((match_policy const &)policies)    {    }    template <typename U>    struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; };    typedef tree_match<IteratorT, NodeFactoryT, T> match_t;    typedef IteratorT iterator_t;    typedef TreePolicyT tree_policy_t;    typedef NodeFactoryT factory_t;    static const match_t no_match() { return match_t(); }    static const match_t empty_match()    { return match_t(0, tree_policy_t::empty_node()); }    template <typename AttrT, typename Iterator1T, typename Iterator2T>    static tree_match<IteratorT, NodeFactoryT, AttrT> create_match(        std::size_t length,        AttrT const& val,        Iterator1T const& first,        Iterator2T const& last)    {#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)        BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n"             "creating node text: \"";        for (Iterator1T it = first; it != last; ++it)            impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);        BOOST_SPIRIT_DEBUG_OUT << "\"\n";        BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n"; #endif        return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val,            tree_policy_t::create_node(length, first, last, true));    }    template <typename Match1T, typename Match2T>    static void concat_match(Match1T& a, Match2T const& b)    {#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)        BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n";        BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n";        BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n";        BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n";#endif        BOOST_SPIRIT_ASSERT(a && b);        if (a.length() == 0)        {            a = b;            return;        }        else if (b.length() == 0#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING            && !b.trees.begin()->value.id().to_long()#endif            )        {            return;        }        a.concat(b);        tree_policy_t::concat(a, b);    }    template <typename MatchT, typename IteratorT2>    void    group_match(        MatchT&             m,        parser_id const&    id,        IteratorT2 const&   first,        IteratorT2 const&   last) const    {        if (!m) return;        #if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES)        BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n"            "new node(" << id << ") \"";        for (IteratorT2 it = first; it != last; ++it)            impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);        BOOST_SPIRIT_DEBUG_OUT << "\"\n";        BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n";        tree_policy_t::group_match(m, id, first, last);        BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n";        BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n";#else        tree_policy_t::group_match(m, id, first, last);#endif    }};//////////////////////////////////template <typename MatchPolicyT, typename NodeFactoryT>struct common_tree_tree_policy{    typedef typename MatchPolicyT::iterator_t iterator_t;    typedef typename MatchPolicyT::match_t match_t;    typedef typename NodeFactoryT::template factory<iterator_t> factory_t;    typedef typename factory_t::node_t node_t;    template <typename Iterator1T, typename Iterator2T>        static node_t        create_node(std::size_t /*length*/, Iterator1T const& first,            Iterator2T const& last, bool leaf_node)    {        return factory_t::create_node(first, last, leaf_node);    }    static node_t        empty_node()    {        return factory_t::empty_node();    }    template <typename FunctorT>        static void apply_op_to_match(FunctorT const& op, match_t& m)    {        op(m);    }};//////////////////////////////////// directives to modify how the parse tree is generatedstruct no_tree_gen_node_parser_gen;template <typename T>struct no_tree_gen_node_parser:   public unary<T, parser<no_tree_gen_node_parser<T> > >{    typedef no_tree_gen_node_parser<T> self_t;    typedef no_tree_gen_node_parser_gen parser_generator_t;    typedef unary_parser_category parser_category_t;    no_tree_gen_node_parser(T const& a)    : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {}    template <typename ScannerT>    typename parser_result<self_t, ScannerT>::type    parse(ScannerT const& scanner) const    {        typedef typename ScannerT::iteration_policy_t iteration_policy_t;        typedef match_policy match_policy_t;        typedef typename ScannerT::action_policy_t action_policy_t;        typedef scanner_policies<            iteration_policy_t,            match_policy_t,            action_policy_t        > policies_t;        return this->subject().parse(scanner.change_policies(policies_t(scanner)));    }};struct no_tree_gen_node_parser_gen{    template <typename T>    struct result {        typedef no_tree_gen_node_parser<T> type;    };    template <typename T>    static no_tree_gen_node_parser<T>    generate(parser<T> const& s)    {        return no_tree_gen_node_parser<T>(s.derived());    }    template <typename T>    no_tree_gen_node_parser<T>    operator[](parser<T> const& s) const    {        return no_tree_gen_node_parser<T>(s.derived());    }};const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen();//////////////////////////////////struct leaf_node_parser_gen;template<typename T>struct leaf_node_parser:   public unary<T, parser<leaf_node_parser<T> > >{    typedef leaf_node_parser<T> self_t;    typedef leaf_node_parser_gen parser_generator_t;    typedef unary_parser_category parser_category_t;    leaf_node_parser(T const& a)    : unary<T, parser<leaf_node_parser<T> > >(a) {}    template <typename ScannerT>    typename parser_result<self_t, ScannerT>::type    parse(ScannerT const& scanner) const    {        typedef scanner_policies< typename ScannerT::iteration_policy_t,            match_policy, typename ScannerT::action_policy_t > policies_t;        typedef typename ScannerT::iterator_t iterator_t;        typedef typename parser_result<self_t, ScannerT>::type result_t;        typedef typename result_t::node_factory_t factory_t;        iterator_t from = scanner.first;        result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(),            scanner.change_policies(policies_t(scanner,match_policy(),scanner)),            scanner);        if (hit)            return result_t(hit.length(),                 factory_t::create_node(from, scanner.first, true));        else            return result_t(hit.length());    }};struct leaf_node_parser_gen{    template <typename T>    struct result {        typedef leaf_node_parser<T> type;    };    template <typename T>    static leaf_node_parser<T>    generate(parser<T> const& s)    {        return leaf_node_parser<T>(s.derived());    }    template <typename T>    leaf_node_parser<T>    operator[](parser<T> const& s) const    {        return leaf_node_parser<T>(s.derived());    }};const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen();const leaf_node_parser_gen token_node_d = leaf_node_parser_gen();//////////////////////////////////namespace impl {    template <typename MatchPolicyT>    struct tree_policy_selector    {        typedef tree_policy type;    };} // namespace impl//////////////////////////////////template <typename NodeParserT>struct node_parser_gen;template <typename T, typename NodeParserT>struct node_parser:   public unary<T, parser<node_parser<T, NodeParserT> > >{    typedef node_parser<T, NodeParserT> self_t;    typedef node_parser_gen<NodeParserT> parser_generator_t;    typedef unary_parser_category parser_category_t;    node_parser(T const& a)    : unary<T, parser<node_parser<T, NodeParserT> > >(a) {}    template <typename ScannerT>    struct result    {        typedef typename parser_result<T, ScannerT>::type type;    };    template <typename ScannerT>    typename parser_result<self_t, ScannerT>::type    parse(ScannerT const& scanner) const    {        typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner);        if (hit)        {            impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit);        }        return hit;    }};template <typename NodeParserT>struct node_parser_gen{    template <typename T>    struct result {        typedef node_parser<T, NodeParserT> type;    };    template <typename T>    static node_parser<T, NodeParserT>    generate(parser<T> const& s)    {        return node_parser<T, NodeParserT>(s.derived());    }    template <typename T>    node_parser<T, NodeParserT>    operator[](parser<T> const& s) const    {        return node_parser<T, NodeParserT>(s.derived());    }};//////////////////////////////////struct reduced_node_op{    template <typename MatchT>    void operator()(MatchT& m) const    {        if (m.trees.size() == 1)        {            m.trees.begin()->children.clear();        }        else if (m.trees.size() > 1)        {            typedef typename MatchT::node_factory_t node_factory_t;            m = MatchT(m.length(), node_factory_t::group_nodes(m.trees));        }    }};const node_parser_gen<reduced_node_op> reduced_node_d =    node_parser_gen<reduced_node_op>();struct discard_node_op{    template <typename MatchT>    void operator()(MatchT& m) const    {        m.trees.clear();    }};const node_parser_gen<discard_node_op> discard_node_d =    node_parser_gen<discard_node_op>();struct infix_node_op{    template <typename MatchT>    void operator()(MatchT& m) const    {        typedef typename MatchT::container_t container_t;        typedef typename MatchT::container_t::iterator iter_t;        typedef typename MatchT::container_t::value_type value_t;        using std::swap;        using boost::swap;        using BOOST_SPIRIT_CLASSIC_NS::swap;        // copying the tree nodes is expensive, since it may copy a whole        // tree.  swapping them is cheap, so swap the nodes we want into        // a new container of children.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?