1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/spirit/dynamic/switch.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,255 @@
1.4 +/*=============================================================================
1.5 + Copyright (c) 2003 Hartmut Kaiser
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_SWITCH_HPP
1.13 +#define BOOST_SPIRIT_SWITCH_HPP
1.14 +
1.15 +///////////////////////////////////////////////////////////////////////////////
1.16 +//
1.17 +// The default_p parser generator template uses the following magic number
1.18 +// as the corresponding case label value inside the generated switch()
1.19 +// statements. If this number conflicts with your code, please pick a
1.20 +// different one.
1.21 +//
1.22 +///////////////////////////////////////////////////////////////////////////////
1.23 +#if !defined(BOOST_SPIRIT_DEFAULTCASE_MAGIC)
1.24 +#define BOOST_SPIRIT_DEFAULTCASE_MAGIC 0x15F97A7
1.25 +#endif
1.26 +
1.27 +///////////////////////////////////////////////////////////////////////////////
1.28 +//
1.29 +// Spirit predefined maximum number of possible case_p/default_p case branch
1.30 +// parsers.
1.31 +//
1.32 +///////////////////////////////////////////////////////////////////////////////
1.33 +#if !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)
1.34 +#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 3
1.35 +#endif // !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)
1.36 +
1.37 +///////////////////////////////////////////////////////////////////////////////
1.38 +#include <boost/static_assert.hpp>
1.39 +
1.40 +///////////////////////////////////////////////////////////////////////////////
1.41 +//
1.42 +// Ensure BOOST_SPIRIT_SELECT_LIMIT > 0
1.43 +//
1.44 +///////////////////////////////////////////////////////////////////////////////
1.45 +BOOST_STATIC_ASSERT(BOOST_SPIRIT_SWITCH_CASE_LIMIT > 0);
1.46 +
1.47 +#include <boost/spirit/core/config.hpp>
1.48 +#include <boost/type_traits/is_same.hpp>
1.49 +#include <boost/spirit/core/parser.hpp>
1.50 +#include <boost/spirit/core/composite/epsilon.hpp>
1.51 +#include <boost/spirit/dynamic/impl/switch.ipp>
1.52 +
1.53 +///////////////////////////////////////////////////////////////////////////////
1.54 +namespace boost { namespace spirit {
1.55 +
1.56 +///////////////////////////////////////////////////////////////////////////////
1.57 +//
1.58 +// The switch_parser allows to build switch like parsing constructs, which
1.59 +// will have much better perfomance as comparable straight solutions.
1.60 +//
1.61 +// Input stream driven syntax:
1.62 +//
1.63 +// switch_p
1.64 +// [
1.65 +// case_p<'a'>
1.66 +// (...parser to use, if the next character is 'a'...),
1.67 +// case_p<'b'>
1.68 +// (...parser to use, if the next character is 'b'...),
1.69 +// default_p
1.70 +// (...parser to use, if nothing was matched before...)
1.71 +// ]
1.72 +//
1.73 +// General syntax:
1.74 +//
1.75 +// switch_p(...lazy expression returning the switch condition value...)
1.76 +// [
1.77 +// case_p<1>
1.78 +// (...parser to use, if the switch condition value is 1...),
1.79 +// case_p<2>
1.80 +// (...parser to use, if the switch condition value is 2...),
1.81 +// default_p
1.82 +// (...parser to use, if nothing was matched before...)
1.83 +// ]
1.84 +//
1.85 +// The maximum number of possible case_p branches is defined by the p constant
1.86 +// BOOST_SPIRIT_SWITCH_CASE_LIMIT (this value defaults to 3 if not otherwise
1.87 +// defined).
1.88 +//
1.89 +///////////////////////////////////////////////////////////////////////////////
1.90 +template <typename CaseT, typename CondT = impl::get_next_token_cond>
1.91 +struct switch_parser
1.92 +: public unary<CaseT, parser<switch_parser<CaseT, CondT> > >
1.93 +{
1.94 + typedef switch_parser<CaseT, CondT> self_t;
1.95 + typedef unary_parser_category parser_category_t;
1.96 + typedef unary<CaseT, parser<self_t> > base_t;
1.97 +
1.98 + switch_parser(CaseT const &case_)
1.99 + : base_t(case_), cond(CondT())
1.100 + {}
1.101 +
1.102 + switch_parser(CaseT const &case_, CondT const &cond_)
1.103 + : base_t(case_), cond(cond_)
1.104 + {}
1.105 +
1.106 + template <typename ScannerT>
1.107 + struct result
1.108 + {
1.109 + typedef typename match_result<ScannerT, nil_t>::type type;
1.110 + };
1.111 +
1.112 + template <typename ScannerT>
1.113 + typename parser_result<self_t, ScannerT>::type
1.114 + parse(ScannerT const& scan) const
1.115 + {
1.116 + return this->subject().parse(scan,
1.117 + impl::make_cond_functor<CondT>::do_(cond));
1.118 + }
1.119 +
1.120 + CondT cond;
1.121 +};
1.122 +
1.123 +///////////////////////////////////////////////////////////////////////////////
1.124 +template <typename CondT>
1.125 +struct switch_cond_parser
1.126 +{
1.127 + switch_cond_parser(CondT const &cond_)
1.128 + : cond(cond_)
1.129 + {}
1.130 +
1.131 + template <typename ParserT>
1.132 + switch_parser<ParserT, CondT>
1.133 + operator[](parser<ParserT> const &p) const
1.134 + {
1.135 + return switch_parser<ParserT, CondT>(p.derived(), cond);
1.136 + }
1.137 +
1.138 + CondT const &cond;
1.139 +};
1.140 +
1.141 +///////////////////////////////////////////////////////////////////////////////
1.142 +template <int N, typename ParserT, bool IsDefault>
1.143 +struct case_parser
1.144 +: public unary<ParserT, parser<case_parser<N, ParserT, IsDefault> > >
1.145 +{
1.146 + typedef case_parser<N, ParserT, IsDefault> self_t;
1.147 + typedef unary_parser_category parser_category_t;
1.148 + typedef unary<ParserT, parser<self_t> > base_t;
1.149 +
1.150 + typedef typename base_t::subject_t self_subject_t;
1.151 +
1.152 + BOOST_STATIC_CONSTANT(int, value = N);
1.153 + BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
1.154 + BOOST_STATIC_CONSTANT(bool, is_simple = true);
1.155 + BOOST_STATIC_CONSTANT(bool, is_epsilon = (
1.156 + is_default && boost::is_same<self_subject_t, epsilon_parser>::value
1.157 + ));
1.158 +
1.159 + case_parser(parser<ParserT> const &p)
1.160 + : base_t(p.derived())
1.161 + {}
1.162 +
1.163 + template <typename ScannerT>
1.164 + struct result
1.165 + {
1.166 + typedef typename match_result<ScannerT, nil_t>::type type;
1.167 + };
1.168 +
1.169 + template <typename ScannerT, typename CondT>
1.170 + typename parser_result<self_t, ScannerT>::type
1.171 + parse(ScannerT const& scan, CondT const &cond) const
1.172 + {
1.173 + typedef impl::default_case<self_t> default_t;
1.174 +
1.175 + if (!scan.at_end()) {
1.176 + typedef impl::default_delegate_parse<
1.177 + value, is_default, default_t::value> default_parse_t;
1.178 +
1.179 + typename ScannerT::iterator_t const save(scan.first);
1.180 + return default_parse_t::parse(cond(scan), *this,
1.181 + *this, scan, save);
1.182 + }
1.183 +
1.184 + return default_t::is_epsilon ? scan.empty_match() : scan.no_match();
1.185 + }
1.186 +
1.187 + template <int N1, typename ParserT1, bool IsDefault1>
1.188 + impl::compound_case_parser<
1.189 + self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
1.190 + >
1.191 + operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
1.192 + {
1.193 + // If the following compile time assertion fires, you've probably used
1.194 + // more than one default_p case inside the switch_p parser construct.
1.195 + BOOST_STATIC_ASSERT(!is_default || !IsDefault1);
1.196 +
1.197 + typedef case_parser<N1, ParserT1, IsDefault1> right_t;
1.198 + return impl::compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
1.199 + }
1.200 +};
1.201 +
1.202 +///////////////////////////////////////////////////////////////////////////////
1.203 +struct switch_parser_gen {
1.204 +
1.205 +// This generates a switch parser, which is driven by the condition value
1.206 +// returned by the lazy parameter expression 'cond'. This may be a parser,
1.207 +// which result is used or a phoenix actor, which will be dereferenced to
1.208 +// obtain the switch condition value.
1.209 + template <typename CondT>
1.210 + switch_cond_parser<CondT>
1.211 + operator()(CondT const &cond) const
1.212 + {
1.213 + return switch_cond_parser<CondT>(cond);
1.214 + }
1.215 +
1.216 +// This generates a switch parser, which is driven by the next character/token
1.217 +// found in the input stream.
1.218 + template <typename CaseT>
1.219 + switch_parser<CaseT>
1.220 + operator[](parser<CaseT> const &p) const
1.221 + {
1.222 + return switch_parser<CaseT>(p.derived());
1.223 + }
1.224 +};
1.225 +
1.226 +switch_parser_gen const switch_p = switch_parser_gen();
1.227 +
1.228 +///////////////////////////////////////////////////////////////////////////////
1.229 +template <int N, typename ParserT>
1.230 +inline case_parser<N, ParserT, false>
1.231 +case_p(parser<ParserT> const &p)
1.232 +{
1.233 + return case_parser<N, ParserT, false>(p);
1.234 +}
1.235 +
1.236 +///////////////////////////////////////////////////////////////////////////////
1.237 +struct default_parser_gen
1.238 +: public case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>
1.239 +{
1.240 + default_parser_gen()
1.241 + : case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>
1.242 + (epsilon_p)
1.243 + {}
1.244 +
1.245 + template <typename ParserT>
1.246 + case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>
1.247 + operator()(parser<ParserT> const &p) const
1.248 + {
1.249 + return case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>(p);
1.250 + }
1.251 +};
1.252 +
1.253 +default_parser_gen const default_p = default_parser_gen();
1.254 +
1.255 +///////////////////////////////////////////////////////////////////////////////
1.256 +}} // namespace boost::spirit
1.257 +
1.258 +#endif // BOOST_SPIRIT_SWITCH_HPP