File indexing completed on 2025-12-16 10:09:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_SPIRIT_WHILE_HPP
0010 #define BOOST_SPIRIT_WHILE_HPP
0011
0012 #include <boost/spirit/home/classic/namespace.hpp>
0013 #include <boost/spirit/home/classic/core/parser.hpp>
0014 #include <boost/spirit/home/classic/core/composite/composite.hpp>
0015 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
0016
0017
0018 namespace boost { namespace spirit {
0019
0020 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0021
0022 namespace impl {
0023
0024
0025
0026
0027 template <typename ParsableT, typename CondT, bool is_do_parser>
0028 struct while_parser
0029 : public condition_evaluator< typename as_parser<CondT>::type >
0030 , public unary
0031 <
0032 typename as_parser<ParsableT>::type,
0033 parser<while_parser<ParsableT, CondT, is_do_parser> >
0034 >
0035 {
0036 typedef while_parser<ParsableT, CondT, is_do_parser> self_t;
0037
0038 typedef as_parser<ParsableT> as_parser_t;
0039 typedef typename as_parser_t::type parser_t;
0040 typedef as_parser<CondT> cond_as_parser_t;
0041 typedef typename cond_as_parser_t::type condition_t;
0042
0043 typedef unary<parser_t, parser<self_t> > base_t;
0044 typedef condition_evaluator<condition_t> eval_t;
0045
0046
0047
0048
0049 while_parser(ParsableT const &body, CondT const &cond)
0050 : eval_t(cond_as_parser_t::convert(cond))
0051 , base_t(as_parser_t::convert(body))
0052 {}
0053
0054
0055
0056 template <typename ScannerT>
0057 struct result
0058 {
0059 typedef typename match_result
0060 <ScannerT, nil_t>::type type;
0061 };
0062
0063
0064
0065 template <typename ScannerT>
0066 typename parser_result<self_t, ScannerT>::type
0067 parse(ScannerT const& scan) const
0068 {
0069 typedef typename parser_result<parser_t, ScannerT>::type sresult_t;
0070 typedef typename ScannerT::iterator_t iterator_t;
0071
0072 iterator_t save(scan.first);
0073 std::size_t length = 0;
0074 std::ptrdiff_t eval_length = 0;
0075
0076 bool dont_check_condition = is_do_parser;
0077
0078 while (dont_check_condition || (eval_length=this->evaluate(scan))>=0)
0079 {
0080 dont_check_condition = false;
0081 length += eval_length;
0082 sresult_t tmp(this->subject().parse(scan));
0083 if (tmp)
0084 {
0085 length+=tmp.length();
0086 }
0087 else
0088 {
0089 return scan.no_match();
0090 }
0091 }
0092 return scan.create_match(length, nil_t(), save, scan.first);
0093 }
0094 };
0095
0096
0097
0098
0099 template <typename CondT>
0100 struct while_parser_gen
0101 {
0102
0103
0104 while_parser_gen(CondT const& cond_) : cond(cond_) {}
0105
0106
0107
0108 template <typename ParsableT>
0109 while_parser<ParsableT, CondT, false>
0110 operator[](ParsableT const &subject) const
0111 {
0112 return while_parser<ParsableT, CondT, false>(subject, cond);
0113 }
0114 private:
0115
0116
0117
0118
0119
0120
0121
0122 CondT const &cond;
0123 };
0124
0125
0126
0127
0128
0129 template <typename ParsableT>
0130 struct do_while_parser_gen
0131 {
0132
0133
0134 explicit do_while_parser_gen(ParsableT const &body_parser)
0135 : body(body_parser)
0136 {}
0137
0138
0139
0140 template <typename CondT>
0141 while_parser<ParsableT, CondT, true>
0142 while_p(CondT cond) const
0143 {
0144 return while_parser<ParsableT, CondT, true>(body, cond);
0145 }
0146 private:
0147
0148
0149
0150
0151
0152
0153
0154 ParsableT const &body;
0155 };
0156
0157 struct do_parser_gen
0158 {
0159 inline do_parser_gen() {}
0160
0161 template <typename ParsableT>
0162 impl::do_while_parser_gen<ParsableT>
0163 operator[](ParsableT const& body) const
0164 {
0165 return impl::do_while_parser_gen<ParsableT>(body);
0166 }
0167 };
0168 }
0169
0170
0171
0172
0173 template <typename CondT>
0174 impl::while_parser_gen<CondT>
0175 while_p(CondT const& cond)
0176 {
0177 return impl::while_parser_gen<CondT>(cond);
0178 }
0179
0180
0181
0182
0183 impl::do_parser_gen const do_p = impl::do_parser_gen();
0184
0185 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0186
0187 }}
0188
0189 #endif