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 +