annotate DEPENDENCIES/generic/include/boost/spirit/home/classic/dynamic/if.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2002-2003 Joel de Guzman
Chris@16 3 Copyright (c) 2002 Juan Carlos Arevalo-Baeza
Chris@16 4 Copyright (c) 2002-2003 Martin Wille
Chris@16 5 http://spirit.sourceforge.net/
Chris@16 6
Chris@16 7 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 =============================================================================*/
Chris@16 10 #ifndef BOOST_SPIRIT_IF_HPP
Chris@16 11 #define BOOST_SPIRIT_IF_HPP
Chris@16 12
Chris@16 13 #include <boost/spirit/home/classic/namespace.hpp>
Chris@16 14 #include <boost/spirit/home/classic/core/parser.hpp>
Chris@16 15 #include <boost/spirit/home/classic/core/composite/composite.hpp>
Chris@16 16 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
Chris@16 17
Chris@16 18 namespace boost { namespace spirit {
Chris@16 19
Chris@16 20 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
Chris@16 21
Chris@16 22 namespace impl {
Chris@16 23
Chris@16 24 //////////////////////////////////
Chris@16 25 // if-else-parser, holds two alternative parsers and a conditional functor
Chris@16 26 // that selects between them.
Chris@16 27 template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
Chris@16 28 struct if_else_parser
Chris@16 29 : public condition_evaluator<typename as_parser<CondT>::type>
Chris@16 30 , public binary
Chris@16 31 <
Chris@16 32 typename as_parser<ParsableTrueT>::type,
Chris@16 33 typename as_parser<ParsableFalseT>::type,
Chris@16 34 parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
Chris@16 35 >
Chris@16 36 {
Chris@16 37 typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT> self_t;
Chris@16 38
Chris@16 39 typedef as_parser<ParsableTrueT> as_parser_true_t;
Chris@16 40 typedef as_parser<ParsableFalseT> as_parser_false_t;
Chris@16 41 typedef typename as_parser_true_t::type parser_true_t;
Chris@16 42 typedef typename as_parser_false_t::type parser_false_t;
Chris@16 43 typedef as_parser<CondT> cond_as_parser_t;
Chris@16 44 typedef typename cond_as_parser_t::type condition_t;
Chris@16 45
Chris@16 46 typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
Chris@16 47 typedef condition_evaluator<condition_t> eval_t;
Chris@16 48
Chris@16 49 if_else_parser
Chris@16 50 (
Chris@16 51 ParsableTrueT const& p_true,
Chris@16 52 ParsableFalseT const& p_false,
Chris@16 53 CondT const& cond_
Chris@16 54 )
Chris@16 55 : eval_t(cond_as_parser_t::convert(cond_))
Chris@16 56 , base_t
Chris@16 57 (
Chris@16 58 as_parser_true_t::convert(p_true),
Chris@16 59 as_parser_false_t::convert(p_false)
Chris@16 60 )
Chris@16 61 { }
Chris@16 62
Chris@16 63 template <typename ScannerT>
Chris@16 64 struct result
Chris@16 65 {
Chris@16 66 typedef typename match_result<ScannerT, nil_t>::type type;
Chris@16 67 };
Chris@16 68
Chris@16 69 template <typename ScannerT>
Chris@16 70 typename parser_result<self_t, ScannerT>::type
Chris@16 71 parse(ScannerT const& scan) const
Chris@16 72 {
Chris@16 73 typedef typename parser_result
Chris@16 74 <parser_true_t, ScannerT>::type then_result_t;
Chris@16 75 typedef typename parser_result
Chris@16 76 <parser_false_t, ScannerT>::type else_result_t;
Chris@16 77
Chris@16 78 typename ScannerT::iterator_t const save(scan.first);
Chris@16 79
Chris@16 80 std::ptrdiff_t length = this->evaluate(scan);
Chris@16 81 if (length >= 0)
Chris@16 82 {
Chris@16 83 then_result_t then_result(this->left().parse(scan));
Chris@16 84 if (then_result)
Chris@16 85 {
Chris@16 86 length += then_result.length();
Chris@16 87 return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
Chris@16 88 }
Chris@16 89 }
Chris@16 90 else
Chris@16 91 {
Chris@16 92 else_result_t else_result(this->right().parse(scan));
Chris@16 93 if (else_result)
Chris@16 94 {
Chris@16 95 length = else_result.length();
Chris@16 96 return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
Chris@16 97 }
Chris@16 98 }
Chris@16 99 return scan.no_match();
Chris@16 100 }
Chris@16 101 };
Chris@16 102
Chris@16 103 //////////////////////////////////
Chris@16 104 // if-else-parser generator, takes the false-parser in brackets
Chris@16 105 // and returns the if-else-parser.
Chris@16 106 template <typename ParsableTrueT, typename CondT>
Chris@16 107 struct if_else_parser_gen
Chris@16 108 {
Chris@16 109 if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
Chris@16 110 : p_true(p_true_)
Chris@16 111 , cond(cond_) {}
Chris@16 112
Chris@16 113 template <typename ParsableFalseT>
Chris@16 114 if_else_parser
Chris@16 115 <
Chris@16 116 ParsableTrueT,
Chris@16 117 ParsableFalseT,
Chris@16 118 CondT
Chris@16 119 >
Chris@16 120 operator[](ParsableFalseT const& p_false) const
Chris@16 121 {
Chris@16 122 return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
Chris@16 123 (
Chris@16 124 p_true,
Chris@16 125 p_false,
Chris@16 126 cond
Chris@16 127 );
Chris@16 128 }
Chris@16 129
Chris@16 130 ParsableTrueT const &p_true;
Chris@16 131 CondT const &cond;
Chris@16 132 };
Chris@16 133
Chris@16 134 //////////////////////////////////
Chris@16 135 // if-parser, conditionally runs a parser is a functor condition is true.
Chris@16 136 // If the condition is fales, it fails the parse.
Chris@16 137 // It can optionally become an if-else-parser through the member else_p.
Chris@16 138 template <typename ParsableT, typename CondT>
Chris@16 139 struct if_parser
Chris@16 140 : public condition_evaluator<typename as_parser<CondT>::type>
Chris@16 141 , public unary
Chris@16 142 <
Chris@16 143 typename as_parser<ParsableT>::type,
Chris@16 144 parser<if_parser<ParsableT, CondT> > >
Chris@16 145 {
Chris@16 146 typedef if_parser<ParsableT, CondT> self_t;
Chris@16 147 typedef as_parser<ParsableT> as_parser_t;
Chris@16 148 typedef typename as_parser_t::type parser_t;
Chris@16 149
Chris@16 150 typedef as_parser<CondT> cond_as_parser_t;
Chris@16 151 typedef typename cond_as_parser_t::type condition_t;
Chris@16 152 typedef condition_evaluator<condition_t> eval_t;
Chris@16 153 typedef unary<parser_t, parser<self_t> > base_t;
Chris@16 154
Chris@16 155 if_parser(ParsableT const& p, CondT const& cond_)
Chris@16 156 : eval_t(cond_as_parser_t::convert(cond_))
Chris@16 157 , base_t(as_parser_t::convert(p))
Chris@16 158 , else_p(p, cond_)
Chris@16 159 {}
Chris@16 160
Chris@16 161 template <typename ScannerT>
Chris@16 162 struct result
Chris@16 163 {
Chris@16 164 typedef typename match_result<ScannerT, nil_t>::type type;
Chris@16 165 };
Chris@16 166
Chris@16 167 template <typename ScannerT>
Chris@16 168 typename parser_result<self_t, ScannerT>::type
Chris@16 169 parse(ScannerT const& scan) const
Chris@16 170 {
Chris@16 171 typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
Chris@16 172 typename ScannerT::iterator_t const save(scan.first);
Chris@16 173
Chris@16 174 std::ptrdiff_t length = this->evaluate(scan);
Chris@16 175 if (length >= 0)
Chris@16 176 {
Chris@16 177 t_result_t then_result(this->subject().parse(scan));
Chris@16 178 if (then_result)
Chris@16 179 {
Chris@16 180 length += then_result.length();
Chris@16 181 return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
Chris@16 182 }
Chris@16 183 return scan.no_match();
Chris@16 184 }
Chris@16 185 return scan.empty_match();
Chris@16 186 }
Chris@16 187
Chris@16 188 if_else_parser_gen<ParsableT, CondT> else_p;
Chris@16 189 };
Chris@16 190
Chris@16 191 //////////////////////////////////
Chris@16 192 // if-parser generator, takes the true-parser in brackets and returns the
Chris@16 193 // if-parser.
Chris@16 194 template <typename CondT>
Chris@16 195 struct if_parser_gen
Chris@16 196 {
Chris@16 197 if_parser_gen(CondT const& cond_) : cond(cond_) {}
Chris@16 198
Chris@16 199 template <typename ParsableT>
Chris@16 200 if_parser
Chris@16 201 <
Chris@16 202 ParsableT,
Chris@16 203 CondT
Chris@16 204 >
Chris@16 205 operator[](ParsableT const& subject) const
Chris@16 206 {
Chris@16 207 return if_parser<ParsableT, CondT>(subject, cond);
Chris@16 208 }
Chris@16 209
Chris@16 210 CondT const &cond;
Chris@16 211 };
Chris@16 212
Chris@16 213 } // namespace impl
Chris@16 214
Chris@16 215 //////////////////////////////////
Chris@16 216 // if_p function, returns "if" parser generator
Chris@16 217
Chris@16 218 template <typename CondT>
Chris@16 219 impl::if_parser_gen<CondT>
Chris@16 220 if_p(CondT const& cond)
Chris@16 221 {
Chris@16 222 return impl::if_parser_gen<CondT>(cond);
Chris@16 223 }
Chris@16 224
Chris@16 225 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
Chris@16 226
Chris@16 227 }} // namespace BOOST_SPIRIT_CLASSIC_NS
Chris@16 228
Chris@16 229 #endif // BOOST_SPIRIT_IF_HPP