os/ossrv/ossrv_pub/boost_apis/boost/spirit/tree/ast.hpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/spirit/tree/ast.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,378 @@
     1.4 +/*=============================================================================
     1.5 +    Copyright (c) 2001-2003 Daniel Nuffer
     1.6 +    http://spirit.sourceforge.net/
     1.7 +
     1.8 +    Use, modification and distribution is subject to the Boost Software
     1.9 +    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    1.10 +    http://www.boost.org/LICENSE_1_0.txt)
    1.11 +=============================================================================*/
    1.12 +#ifndef BOOST_SPIRIT_TREE_AST_HPP
    1.13 +#define BOOST_SPIRIT_TREE_AST_HPP
    1.14 +
    1.15 +#include <boost/spirit/tree/common.hpp>
    1.16 +#include <boost/spirit/core/scanner/scanner.hpp>
    1.17 +
    1.18 +#include <boost/spirit/tree/ast_fwd.hpp>
    1.19 +
    1.20 +///////////////////////////////////////////////////////////////////////////////
    1.21 +namespace boost { namespace spirit {
    1.22 +
    1.23 +
    1.24 +//////////////////////////////////
    1.25 +//  ast_match_policy is simply an id so the correct specialization of
    1.26 +//  tree_policy can be found.
    1.27 +template <
    1.28 +    typename IteratorT,
    1.29 +    typename NodeFactoryT
    1.30 +>
    1.31 +struct ast_match_policy :
    1.32 +    public common_tree_match_policy<
    1.33 +        ast_match_policy<IteratorT, NodeFactoryT>,
    1.34 +        IteratorT,
    1.35 +        NodeFactoryT,
    1.36 +        ast_tree_policy<
    1.37 +            ast_match_policy<IteratorT, NodeFactoryT>,
    1.38 +            NodeFactoryT
    1.39 +        >
    1.40 +    >
    1.41 +{
    1.42 +    typedef
    1.43 +        common_tree_match_policy<
    1.44 +            ast_match_policy<IteratorT, NodeFactoryT>,
    1.45 +            IteratorT,
    1.46 +            NodeFactoryT,
    1.47 +            ast_tree_policy<
    1.48 +                ast_match_policy<IteratorT, NodeFactoryT>,
    1.49 +                NodeFactoryT
    1.50 +            >
    1.51 +        >
    1.52 +    common_tree_match_policy_;
    1.53 +
    1.54 +    ast_match_policy()
    1.55 +    {
    1.56 +    }
    1.57 +
    1.58 +    template <typename PolicyT>
    1.59 +    ast_match_policy(PolicyT const & policies)
    1.60 +        : common_tree_match_policy_(policies)
    1.61 +    {
    1.62 +    }
    1.63 +};
    1.64 +
    1.65 +//////////////////////////////////
    1.66 +template <typename MatchPolicyT, typename NodeFactoryT>
    1.67 +struct ast_tree_policy :
    1.68 +    public common_tree_tree_policy<MatchPolicyT, NodeFactoryT>
    1.69 +{
    1.70 +    typedef
    1.71 +        typename common_tree_tree_policy<MatchPolicyT, NodeFactoryT>::match_t
    1.72 +        match_t;
    1.73 +    typedef typename MatchPolicyT::iterator_t iterator_t;
    1.74 +
    1.75 +    static void concat(match_t& a, match_t const& b)
    1.76 +    {
    1.77 +        BOOST_SPIRIT_ASSERT(a && b);
    1.78 +
    1.79 +#if defined(BOOST_SPIRIT_DEBUG) && \
    1.80 +    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
    1.81 +        BOOST_SPIRIT_DEBUG_OUT << "\n>>>AST concat. a = " << a <<
    1.82 +            "\n\tb = " << b << "<<<\n";
    1.83 +#endif
    1.84 +        typedef typename tree_match<iterator_t, NodeFactoryT>::container_t
    1.85 +            container_t;
    1.86 +
    1.87 +        // test for size() is nessecary, because no_tree_gen_node leaves a.trees
    1.88 +        // and/or b.trees empty
    1.89 +        if (0 != b.trees.size() && b.trees.begin()->value.is_root())
    1.90 +        {
    1.91 +            BOOST_SPIRIT_ASSERT(b.trees.size() == 1);
    1.92 +
    1.93 +            container_t tmp;
    1.94 +            std::swap(a.trees, tmp); // save a into tmp
    1.95 +            std::swap(b.trees, a.trees); // make b.trees[0] be new root (a.trees[0])
    1.96 +            container_t* pnon_root_trees = &a.trees;
    1.97 +            while (pnon_root_trees->size() > 0 &&
    1.98 +                    pnon_root_trees->begin()->value.is_root())
    1.99 +            {
   1.100 +                pnon_root_trees = & pnon_root_trees->begin()->children;
   1.101 +            }
   1.102 +            pnon_root_trees->insert(pnon_root_trees->begin(),
   1.103 +                    tmp.begin(), tmp.end());
   1.104 +        }
   1.105 +        else if (0 != a.trees.size() && a.trees.begin()->value.is_root())
   1.106 +        {
   1.107 +            BOOST_SPIRIT_ASSERT(a.trees.size() == 1);
   1.108 +
   1.109 +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
   1.110 +            a.trees.begin()->children.reserve(a.trees.begin()->children.size() + b.trees.size());
   1.111 +#endif
   1.112 +            std::copy(b.trees.begin(),
   1.113 +                 b.trees.end(),
   1.114 +                 std::back_insert_iterator<container_t>(
   1.115 +                     a.trees.begin()->children));
   1.116 +        }
   1.117 +        else
   1.118 +        {
   1.119 +#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
   1.120 +            a.trees.reserve(a.trees.size() + b.trees.size());
   1.121 +#endif
   1.122 +            std::copy(b.trees.begin(),
   1.123 +                 b.trees.end(),
   1.124 +                 std::back_insert_iterator<container_t>(a.trees));
   1.125 +        }
   1.126 +
   1.127 +#if defined(BOOST_SPIRIT_DEBUG) && \
   1.128 +    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
   1.129 +        BOOST_SPIRIT_DEBUG_OUT << ">>>after AST concat. a = " << a << "<<<\n\n";
   1.130 +#endif
   1.131 +
   1.132 +        return;
   1.133 +    }
   1.134 +
   1.135 +    template <typename MatchT, typename Iterator1T, typename Iterator2T>
   1.136 +    static void group_match(MatchT& m, parser_id const& id,
   1.137 +            Iterator1T const& first, Iterator2T const& last)
   1.138 +    {
   1.139 +        if (!m)
   1.140 +            return;
   1.141 +
   1.142 +        typedef typename tree_match<iterator_t, NodeFactoryT>::container_t
   1.143 +            container_t;
   1.144 +        typedef typename container_t::iterator cont_iterator_t;
   1.145 +        typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
   1.146 +
   1.147 +        if (m.trees.size() == 1
   1.148 +#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING
   1.149 +            && !(id.to_long() && m.trees.begin()->value.id().to_long())
   1.150 +#endif
   1.151 +            )
   1.152 +        {
   1.153 +            // set rule_id's.  There may have been multiple nodes created.
   1.154 +            // Because of root_node[] they may be left-most children of the top
   1.155 +            // node.
   1.156 +            container_t* punset_id = &m.trees;
   1.157 +            while (punset_id->size() > 0 &&
   1.158 +                    punset_id->begin()->value.id() == 0)
   1.159 +            {
   1.160 +                punset_id->begin()->value.id(id);
   1.161 +                punset_id = &punset_id->begin()->children;
   1.162 +            }
   1.163 +
   1.164 +            m.trees.begin()->value.is_root(false);
   1.165 +        }
   1.166 +        else
   1.167 +        {
   1.168 +            match_t newmatch(m.length(),
   1.169 +                m.trees.empty() ? 
   1.170 +                    factory_t::empty_node() : 
   1.171 +                    factory_t::create_node(first, last, false));
   1.172 +
   1.173 +            std::swap(newmatch.trees.begin()->children, m.trees);
   1.174 +            // set this node and all it's unset children's rule_id
   1.175 +            newmatch.trees.begin()->value.id(id);
   1.176 +            for (cont_iterator_t i = newmatch.trees.begin();
   1.177 +                 i != newmatch.trees.end();
   1.178 +                 ++i)
   1.179 +            {
   1.180 +                if (i->value.id() == 0)
   1.181 +                    i->value.id(id);
   1.182 +            }
   1.183 +            m = newmatch;
   1.184 +        }
   1.185 +    }
   1.186 +
   1.187 +    template <typename FunctorT>
   1.188 +    static void apply_op_to_match(FunctorT const& op, match_t& m)
   1.189 +    {
   1.190 +        op(m);
   1.191 +    }
   1.192 +};
   1.193 +
   1.194 +namespace impl {
   1.195 +
   1.196 +    template <typename IteratorT, typename NodeFactoryT>
   1.197 +    struct tree_policy_selector<ast_match_policy<IteratorT, NodeFactoryT> >
   1.198 +    {
   1.199 +        typedef ast_tree_policy<
   1.200 +            ast_match_policy<IteratorT, NodeFactoryT>, NodeFactoryT> type;
   1.201 +    };
   1.202 +
   1.203 +} // namespace impl
   1.204 +
   1.205 +
   1.206 +//////////////////////////////////
   1.207 +struct gen_ast_node_parser_gen;
   1.208 +
   1.209 +template <typename T>
   1.210 +struct gen_ast_node_parser
   1.211 +:   public unary<T, parser<gen_ast_node_parser<T> > >
   1.212 +{
   1.213 +    typedef gen_ast_node_parser<T> self_t;
   1.214 +    typedef gen_ast_node_parser_gen parser_generator_t;
   1.215 +    typedef unary_parser_category parser_category_t;
   1.216 +//    typedef gen_ast_node_parser<T> const &embed_t;
   1.217 +
   1.218 +    gen_ast_node_parser(T const& a)
   1.219 +    : unary<T, parser<gen_ast_node_parser<T> > >(a) {}
   1.220 +
   1.221 +    template <typename ScannerT>
   1.222 +    typename parser_result<self_t, ScannerT>::type
   1.223 +    parse(ScannerT const& scan) const
   1.224 +    {
   1.225 +        typedef typename ScannerT::iteration_policy_t iteration_policy_t;
   1.226 +        typedef typename ScannerT::match_policy_t::iterator_t iterator_t;
   1.227 +        typedef typename ScannerT::match_policy_t::factory_t factory_t;
   1.228 +        typedef ast_match_policy<iterator_t, factory_t> match_policy_t;
   1.229 +        typedef typename ScannerT::action_policy_t action_policy_t;
   1.230 +        typedef scanner_policies<
   1.231 +            iteration_policy_t,
   1.232 +            match_policy_t,
   1.233 +            action_policy_t
   1.234 +        > policies_t;
   1.235 +
   1.236 +        return this->subject().parse(scan.change_policies(policies_t(scan)));
   1.237 +    }
   1.238 +};
   1.239 +
   1.240 +//////////////////////////////////
   1.241 +struct gen_ast_node_parser_gen
   1.242 +{
   1.243 +    template <typename T>
   1.244 +    struct result {
   1.245 +
   1.246 +        typedef gen_ast_node_parser<T> type;
   1.247 +    };
   1.248 +
   1.249 +    template <typename T>
   1.250 +    static gen_ast_node_parser<T>
   1.251 +    generate(parser<T> const& s)
   1.252 +    {
   1.253 +        return gen_ast_node_parser<T>(s.derived());
   1.254 +    }
   1.255 +
   1.256 +    template <typename T>
   1.257 +    gen_ast_node_parser<T>
   1.258 +    operator[](parser<T> const& s) const
   1.259 +    {
   1.260 +        return gen_ast_node_parser<T>(s.derived());
   1.261 +    }
   1.262 +};
   1.263 +
   1.264 +//////////////////////////////////
   1.265 +const gen_ast_node_parser_gen gen_ast_node_d = gen_ast_node_parser_gen();
   1.266 +
   1.267 +
   1.268 +//////////////////////////////////
   1.269 +struct root_node_op
   1.270 +{
   1.271 +    template <typename MatchT>
   1.272 +    void operator()(MatchT& m) const
   1.273 +    {
   1.274 +        BOOST_SPIRIT_ASSERT(m.trees.size() > 0);
   1.275 +        m.trees.begin()->value.is_root(true);
   1.276 +    }
   1.277 +};
   1.278 +
   1.279 +const node_parser_gen<root_node_op> root_node_d =
   1.280 +    node_parser_gen<root_node_op>();
   1.281 +
   1.282 +///////////////////////////////////////////////////////////////////////////////
   1.283 +//
   1.284 +//  Parse functions for ASTs
   1.285 +//
   1.286 +///////////////////////////////////////////////////////////////////////////////
   1.287 +template <
   1.288 +    typename AstFactoryT, typename IteratorT, typename ParserT, 
   1.289 +    typename SkipT
   1.290 +>
   1.291 +inline tree_parse_info<IteratorT, AstFactoryT>
   1.292 +ast_parse(
   1.293 +    IteratorT const&        first_,
   1.294 +    IteratorT const&        last_,
   1.295 +    parser<ParserT> const&  parser,
   1.296 +    SkipT const&            skip_,
   1.297 +    AstFactoryT const &   /*dummy_*/ = AstFactoryT())
   1.298 +{
   1.299 +    typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
   1.300 +    typedef ast_match_policy<IteratorT, AstFactoryT> ast_match_policy_t;
   1.301 +    typedef
   1.302 +        scanner_policies<iter_policy_t, ast_match_policy_t>
   1.303 +        scanner_policies_t;
   1.304 +    typedef scanner<IteratorT, scanner_policies_t> scanner_t;
   1.305 +
   1.306 +    iter_policy_t iter_policy(skip_);
   1.307 +    scanner_policies_t policies(iter_policy);
   1.308 +    IteratorT first = first_;
   1.309 +    scanner_t scan(first, last_, policies);
   1.310 +    tree_match<IteratorT, AstFactoryT> hit = parser.derived().parse(scan);
   1.311 +    scan.skip(scan);
   1.312 +    return tree_parse_info<IteratorT, AstFactoryT>(
   1.313 +        first, hit, hit && (first == last_), hit.length(), hit.trees);
   1.314 +}
   1.315 +
   1.316 +//////////////////////////////////
   1.317 +template <typename IteratorT, typename ParserT, typename SkipT>
   1.318 +inline tree_parse_info<IteratorT>
   1.319 +ast_parse(
   1.320 +    IteratorT const&        first_,
   1.321 +    IteratorT const&        last_,
   1.322 +    parser<ParserT> const&  parser,
   1.323 +    SkipT const&            skip_)
   1.324 +{
   1.325 +    typedef node_val_data_factory<nil_t> default_factory_t;
   1.326 +    return ast_parse(first_, last_, parser, skip_, default_factory_t());
   1.327 +}
   1.328 +  
   1.329 +//////////////////////////////////
   1.330 +template <typename IteratorT, typename ParserT>
   1.331 +inline tree_parse_info<IteratorT>
   1.332 +ast_parse(
   1.333 +    IteratorT const&        first_,
   1.334 +    IteratorT const&        last,
   1.335 +    parser<ParserT> const&  parser)
   1.336 +{
   1.337 +    typedef ast_match_policy<IteratorT> ast_match_policy_t;
   1.338 +    IteratorT first = first_;
   1.339 +    scanner<
   1.340 +        IteratorT,
   1.341 +        scanner_policies<iteration_policy, ast_match_policy_t>
   1.342 +    > scan(first, last);
   1.343 +    tree_match<IteratorT> hit = parser.derived().parse(scan);
   1.344 +    return tree_parse_info<IteratorT>(
   1.345 +        first, hit, hit && (first == last), hit.length(), hit.trees);
   1.346 +}
   1.347 +
   1.348 +//////////////////////////////////
   1.349 +template <typename CharT, typename ParserT, typename SkipT>
   1.350 +inline tree_parse_info<CharT const*>
   1.351 +ast_parse(
   1.352 +    CharT const*            str,
   1.353 +    parser<ParserT> const&  parser,
   1.354 +    SkipT const&            skip)
   1.355 +{
   1.356 +    CharT const* last = str;
   1.357 +    while (*last)
   1.358 +        last++;
   1.359 +    return ast_parse(str, last, parser, skip);
   1.360 +}
   1.361 +
   1.362 +//////////////////////////////////
   1.363 +template <typename CharT, typename ParserT>
   1.364 +inline tree_parse_info<CharT const*>
   1.365 +ast_parse(
   1.366 +    CharT const*            str,
   1.367 +    parser<ParserT> const&  parser)
   1.368 +{
   1.369 +    CharT const* last = str;
   1.370 +    while (*last)
   1.371 +    {
   1.372 +        last++;
   1.373 +    }
   1.374 +    return ast_parse(str, last, parser);
   1.375 +}
   1.376 +
   1.377 +///////////////////////////////////////////////////////////////////////////////
   1.378 +}} // namespace boost::spirit
   1.379 +
   1.380 +#endif
   1.381 +