ast.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 388 行

HPP
388
字号
/*=============================================================================    Copyright (c) 2001-2003 Daniel Nuffer    Copyright (c) 2001-2007 Hartmut Kaiser    http://spirit.sourceforge.net/  Distributed under the Boost Software License, Version 1.0. (See accompanying  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#ifndef BOOST_SPIRIT_TREE_AST_HPP#define BOOST_SPIRIT_TREE_AST_HPP#include <boost/spirit/home/classic/namespace.hpp>#include <boost/spirit/home/classic/tree/common.hpp>#include <boost/spirit/home/classic/core/scanner/scanner.hpp>#include <boost/spirit/home/classic/tree/ast_fwd.hpp>///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit {BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN////////////////////////////////////  ast_match_policy is simply an id so the correct specialization of//  tree_policy can be found.template <    typename IteratorT,    typename NodeFactoryT,    typename T>struct ast_match_policy :    public common_tree_match_policy<        ast_match_policy<IteratorT, NodeFactoryT, T>,        IteratorT,        NodeFactoryT,        ast_tree_policy<            ast_match_policy<IteratorT, NodeFactoryT, T>,            NodeFactoryT,            T        >,        T    >{    typedef        common_tree_match_policy<            ast_match_policy<IteratorT, NodeFactoryT, T>,            IteratorT,            NodeFactoryT,            ast_tree_policy<                ast_match_policy<IteratorT, NodeFactoryT, T>,                NodeFactoryT,                T            >,            T        >    common_tree_match_policy_;        ast_match_policy()    {    }    template <typename PolicyT>    ast_match_policy(PolicyT const & policies)        : common_tree_match_policy_(policies)    {    }};//////////////////////////////////template <typename MatchPolicyT, typename NodeFactoryT, typename T>struct ast_tree_policy :    public common_tree_tree_policy<MatchPolicyT, NodeFactoryT>{    typedef typename MatchPolicyT::match_t match_t;    typedef typename MatchPolicyT::iterator_t iterator_t;    template<typename MatchAT, typename MatchBT>    static void concat(MatchAT& a, MatchBT const& b)    {        BOOST_SPIRIT_ASSERT(a && b);#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)        BOOST_SPIRIT_DEBUG_OUT << "\n>>>AST concat. a = " << a <<            "\n\tb = " << b << "<<<\n";#endif        typedef typename tree_match<iterator_t, NodeFactoryT, T>::container_t            container_t;        // test for size() is nessecary, because no_tree_gen_node leaves a.trees        // and/or b.trees empty        if (0 != b.trees.size() && b.trees.begin()->value.is_root())        {            BOOST_SPIRIT_ASSERT(b.trees.size() == 1);            container_t tmp;            std::swap(a.trees, tmp); // save a into tmp            std::swap(b.trees, a.trees); // make b.trees[0] be new root (a.trees[0])            container_t* pnon_root_trees = &a.trees;            while (pnon_root_trees->size() > 0 &&                    pnon_root_trees->begin()->value.is_root())            {                pnon_root_trees = & pnon_root_trees->begin()->children;            }            pnon_root_trees->insert(pnon_root_trees->begin(),                    tmp.begin(), tmp.end());        }        else if (0 != a.trees.size() && a.trees.begin()->value.is_root())        {            BOOST_SPIRIT_ASSERT(a.trees.size() == 1);#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)            a.trees.begin()->children.reserve(a.trees.begin()->children.size() + b.trees.size());#endif            std::copy(b.trees.begin(),                 b.trees.end(),                 std::back_insert_iterator<container_t>(                     a.trees.begin()->children));        }        else        {#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)            a.trees.reserve(a.trees.size() + b.trees.size());#endif            std::copy(b.trees.begin(),                 b.trees.end(),                 std::back_insert_iterator<container_t>(a.trees));        }#if defined(BOOST_SPIRIT_DEBUG) && \    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)        BOOST_SPIRIT_DEBUG_OUT << ">>>after AST concat. a = " << a << "<<<\n\n";#endif        return;    }    template <typename MatchT, typename Iterator1T, typename Iterator2T>    static void group_match(MatchT& m, parser_id const& id,            Iterator1T const& first, Iterator2T const& last)    {        if (!m)            return;        typedef typename tree_match<iterator_t, NodeFactoryT, T>::container_t            container_t;        typedef typename container_t::iterator cont_iterator_t;        typedef typename NodeFactoryT::template factory<iterator_t> factory_t;        if (m.trees.size() == 1#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING            && !(id.to_long() && m.trees.begin()->value.id().to_long())#endif            )        {            // set rule_id's.  There may have been multiple nodes created.            // Because of root_node[] they may be left-most children of the top            // node.            container_t* punset_id = &m.trees;            while (punset_id->size() > 0 &&                    punset_id->begin()->value.id() == 0)            {                punset_id->begin()->value.id(id);                punset_id = &punset_id->begin()->children;            }            m.trees.begin()->value.is_root(false);        }        else        {            match_t newmatch(m.length(),                m.trees.empty() ?                     factory_t::empty_node() :                     factory_t::create_node(first, last, false));            std::swap(newmatch.trees.begin()->children, m.trees);            // set this node and all it's unset children's rule_id            newmatch.trees.begin()->value.id(id);            for (cont_iterator_t i = newmatch.trees.begin();                 i != newmatch.trees.end();                 ++i)            {                if (i->value.id() == 0)                    i->value.id(id);            }            m = newmatch;        }    }    template <typename FunctorT, typename MatchT>    static void apply_op_to_match(FunctorT const& op, MatchT& m)    {        op(m);    }};namespace impl {    template <typename IteratorT, typename NodeFactoryT, typename T>    struct tree_policy_selector<ast_match_policy<IteratorT, NodeFactoryT, T> >    {        typedef ast_tree_policy<            ast_match_policy<IteratorT, NodeFactoryT, T>,             NodeFactoryT,             T        > type;    };} // namespace impl//////////////////////////////////struct gen_ast_node_parser_gen;template <typename T>struct gen_ast_node_parser:   public unary<T, parser<gen_ast_node_parser<T> > >{    typedef gen_ast_node_parser<T> self_t;    typedef gen_ast_node_parser_gen parser_generator_t;    typedef unary_parser_category parser_category_t;    gen_ast_node_parser(T const& a)    : unary<T, parser<gen_ast_node_parser<T> > >(a) {}    template <typename ScannerT>    typename parser_result<self_t, ScannerT>::type    parse(ScannerT const& scan) const    {        typedef typename ScannerT::iteration_policy_t iteration_policy_t;        typedef typename ScannerT::match_policy_t::iterator_t iterator_t;        typedef typename ScannerT::match_policy_t::factory_t factory_t;        typedef ast_match_policy<iterator_t, factory_t> 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(scan.change_policies(policies_t(scan)));    }};//////////////////////////////////struct gen_ast_node_parser_gen{    template <typename T>    struct result {        typedef gen_ast_node_parser<T> type;    };    template <typename T>    static gen_ast_node_parser<T>    generate(parser<T> const& s)    {        return gen_ast_node_parser<T>(s.derived());    }    template <typename T>    gen_ast_node_parser<T>    operator[](parser<T> const& s) const    {        return gen_ast_node_parser<T>(s.derived());    }};//////////////////////////////////const gen_ast_node_parser_gen gen_ast_node_d = gen_ast_node_parser_gen();//////////////////////////////////struct root_node_op{    template <typename MatchT>    void operator()(MatchT& m) const    {        BOOST_SPIRIT_ASSERT(m.trees.size() > 0);        m.trees.begin()->value.is_root(true);    }};const node_parser_gen<root_node_op> root_node_d =    node_parser_gen<root_node_op>();///////////////////////////////////////////////////////////////////////////////////  Parse functions for ASTs/////////////////////////////////////////////////////////////////////////////////template <    typename AstFactoryT, typename IteratorT, typename ParserT,     typename SkipT>inline tree_parse_info<IteratorT, AstFactoryT>ast_parse(    IteratorT const&        first_,    IteratorT const&        last_,    parser<ParserT> const&  parser,    SkipT const&            skip_,    AstFactoryT const &   /*dummy_*/ = AstFactoryT()){    typedef skip_parser_iteration_policy<SkipT> iter_policy_t;    typedef ast_match_policy<IteratorT, AstFactoryT> ast_match_policy_t;    typedef        scanner_policies<iter_policy_t, ast_match_policy_t>        scanner_policies_t;    typedef scanner<IteratorT, scanner_policies_t> scanner_t;    iter_policy_t iter_policy(skip_);    scanner_policies_t policies(iter_policy);    IteratorT first = first_;    scanner_t scan(first, last_, policies);    tree_match<IteratorT, AstFactoryT> hit = parser.derived().parse(scan);    return tree_parse_info<IteratorT, AstFactoryT>(        first, hit, hit && (first == last_), hit.length(), hit.trees);}//////////////////////////////////template <typename IteratorT, typename ParserT, typename SkipT>inline tree_parse_info<IteratorT>ast_parse(    IteratorT const&        first_,    IteratorT const&        last_,    parser<ParserT> const&  parser,    SkipT const&            skip_){    typedef node_val_data_factory<nil_t> default_factory_t;    return ast_parse(first_, last_, parser, skip_, default_factory_t());}  //////////////////////////////////template <typename IteratorT, typename ParserT>inline tree_parse_info<IteratorT>ast_parse(    IteratorT const&        first_,    IteratorT const&        last,    parser<ParserT> const&  parser){    typedef ast_match_policy<IteratorT> ast_match_policy_t;    IteratorT first = first_;    scanner<        IteratorT,        scanner_policies<iteration_policy, ast_match_policy_t>    > scan(first, last);    tree_match<IteratorT> hit = parser.derived().parse(scan);    return tree_parse_info<IteratorT>(        first, hit, hit && (first == last), hit.length(), hit.trees);}//////////////////////////////////template <typename CharT, typename ParserT, typename SkipT>inline tree_parse_info<CharT const*>ast_parse(    CharT const*            str,    parser<ParserT> const&  parser,    SkipT const&            skip){    CharT const* last = str;    while (*last)        last++;    return ast_parse(str, last, parser, skip);}//////////////////////////////////template <typename CharT, typename ParserT>inline tree_parse_info<CharT const*>ast_parse(    CharT const*            str,    parser<ParserT> const&  parser){    CharT const* last = str;    while (*last)    {        last++;    }    return ast_parse(str, last, parser);}///////////////////////////////////////////////////////////////////////////////BOOST_SPIRIT_CLASSIC_NAMESPACE_END}} // namespace BOOST_SPIRIT_CLASSIC_NS#endif

⌨️ 快捷键说明

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