diff --git a/boost/boost/spirit/core/assert.hpp b/boost/boost/spirit/core/assert.hpp new file mode 100644 index 0000000000..498315df6a --- /dev/null +++ b/boost/boost/spirit/core/assert.hpp @@ -0,0 +1,38 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ASSERT_HPP) +#define BOOST_SPIRIT_ASSERT_HPP + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// +// BOOST_SPIRIT_ASSERT is used throughout the framework. It can be +// overridden by the user. If BOOST_SPIRIT_ASSERT_EXCEPTION is defined, +// then that will be thrown, otherwise, BOOST_SPIRIT_ASSERT simply turns +// into a plain assert() +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_ASSERT) +#if defined(NDEBUG) + #define BOOST_SPIRIT_ASSERT(x) +#elif defined (BOOST_SPIRIT_ASSERT_EXCEPTION) + #define BOOST_SPIRIT_ASSERT_AUX(f, l, x) \ + do{ if (!(x)) boost::throw_exception( \ + BOOST_SPIRIT_ASSERT_EXCEPTION(f "(" #l "): " #x)); } while(0) + #define BOOST_SPIRIT_ASSERT(x) BOOST_SPIRIT_ASSERT_AUX(__FILE__, __LINE__, x) +#else + #include + #define BOOST_SPIRIT_ASSERT(x) assert(x) +#endif +#endif // !defined(BOOST_SPIRIT_ASSERT) + +#endif // BOOST_SPIRIT_ASSERT_HPP diff --git a/boost/boost/spirit/core/composite/actions.hpp b/boost/boost/spirit/core/composite/actions.hpp new file mode 100644 index 0000000000..543faedc01 --- /dev/null +++ b/boost/boost/spirit/core/composite/actions.hpp @@ -0,0 +1,123 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_ACTIONS_HPP +#define BOOST_SPIRIT_ACTIONS_HPP + +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // action class + // + // The action class binds a parser with a user defined semantic + // action. Instances of action are never created manually. Instead, + // action objects are typically created indirectly through + // expression templates of the form: + // + // p[f] + // + // where p is a parser and f is a function or functor. The semantic + // action may be a function or a functor. When the parser is + // successful, the actor calls the scanner's action_policy policy + // (see scanner.hpp): + // + // scan.do_action(actor, attribute, first, last); + // + // passing in these information: + // + // actor: The action's function or functor + // attribute: The match (returned by the parser) object's + // attribute (see match.hpp) + // first: Iterator pointing to the start of the matching + // portion of the input + // last: Iterator pointing to one past the end of the + // matching portion of the input + // + // It is the responsibility of the scanner's action_policy policy to + // dispatch the function or functor as it sees fit. The expected + // function or functor signature depends on the parser being + // wrapped. In general, if the attribute type of the parser being + // wrapped is a nil_t, the function or functor expect the signature: + // + // void func(Iterator first, Iterator last); // functions + // + // struct ftor // functors + // { + // void func(Iterator first, Iterator last) const; + // }; + // + // where Iterator is the type of the iterator that is being used and + // first and last are the iterators pointing to the matching portion + // of the input. + // + // If the attribute type of the parser being wrapped is not a nil_t, + // the function or functor usually expect the signature: + // + // void func(T val); // functions + // + // struct ftor // functors + // { + // void func(T val) const; + // }; + // + // where T is the attribute type and val is the attribute value + // returned by the parser being wrapped. + // + /////////////////////////////////////////////////////////////////////////// + template + class action : public unary > > + { + public: + + typedef action self_t; + typedef action_parser_category parser_category_t; + typedef unary > base_t; + typedef ActionT predicate_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + action(ParserT const& p, ActionT const& a) + : base_t(p) + , actor(a) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename ScannerT::iterator_t iterator_t; + typedef typename parser_result::type result_t; + + scan.at_end(); // allow skipper to take effect + iterator_t save = scan.first; + result_t hit = this->subject().parse(scan); + if (hit) + { + typename result_t::return_t val = hit.value(); + scan.do_action(actor, val, save, scan.first); + } + return hit; + } + + ActionT const& predicate() const { return actor; } + + private: + + ActionT actor; + }; + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/alternative.hpp b/boost/boost/spirit/core/composite/alternative.hpp new file mode 100644 index 0000000000..a587c20f2f --- /dev/null +++ b/boost/boost/spirit/core/composite/alternative.hpp @@ -0,0 +1,134 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ALTERNATIVE_HPP) +#define BOOST_SPIRIT_ALTERNATIVE_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // alternative class + // + // Handles expressions of the form: + // + // a | b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a or b. One (not both) of the operands may + // be a literal char, wchar_t or a primitive string char const*, + // wchar_t const*. + // + // The expression is short circuit evaluated. b is never touched + // when a is returns a successful match. + // + /////////////////////////////////////////////////////////////////////////// + struct alternative_parser_gen; + + template + struct alternative + : public binary > > + { + typedef alternative self_t; + typedef binary_parser_category parser_category_t; + typedef alternative_parser_gen parser_generator_t; + typedef binary > base_t; + + alternative(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + { // scope for save + iterator_t save = scan.first; + if (result_t hit = this->left().parse(scan)) + return hit; + scan.first = save; + } + return this->right().parse(scan); + } + }; + + struct alternative_parser_gen + { + template + struct result + { + typedef + alternative< + typename as_parser::type + , typename as_parser::type + > + type; + }; + + template + static alternative< + typename as_parser::type + , typename as_parser::type + > + generate(A const& a, B const& b) + { + return alternative::type, + BOOST_DEDUCED_TYPENAME as_parser::type> + (as_parser::convert(a), as_parser::convert(b)); + } + }; + + template + alternative + operator|(parser const& a, parser const& b); + + template + alternative > + operator|(parser const& a, char b); + + template + alternative, B> + operator|(char a, parser const& b); + + template + alternative > + operator|(parser const& a, char const* b); + + template + alternative, B> + operator|(char const* a, parser const& b); + + template + alternative > + operator|(parser const& a, wchar_t b); + + template + alternative, B> + operator|(wchar_t a, parser const& b); + + template + alternative > + operator|(parser const& a, wchar_t const* b); + + template + alternative, B> + operator|(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/composite.hpp b/boost/boost/spirit/core/composite/composite.hpp new file mode 100644 index 0000000000..8e5ae3d26d --- /dev/null +++ b/boost/boost/spirit/core/composite/composite.hpp @@ -0,0 +1,138 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_COMPOSITE_HPP) +#define BOOST_SPIRIT_COMPOSITE_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // unary class. + // + // Composite class composed of a single subject. This template class + // is parameterized by the subject type S and a base class to + // inherit from, BaseT. The unary class is meant to be a base class + // to inherit from. The inheritance structure, given the BaseT + // template parameter places the unary class in the middle of a + // linear, single parent hierarchy. For instance, given a class S + // and a base class B, a class D can derive from unary: + // + // struct D : public unary {...}; + // + // The inheritance structure is thus: + // + // B + // | + // unary (has S) + // | + // D + // + // The subject can be accessed from the derived class D as: + // this->subject(); + // + // Typically, the subject S is specified as typename S::embed_t. + // embed_t specifies how the subject is embedded in the composite + // (See parser.hpp for details). + // + /////////////////////////////////////////////////////////////////////////// + template + class unary : public BaseT + { + public: + + typedef BaseT base_t; + typedef typename boost::call_traits::param_type param_t; + typedef typename boost::call_traits::const_reference return_t; + typedef S subject_t; + typedef typename S::embed_t subject_embed_t; + + unary(param_t subj_) + : base_t(), subj(subj_) {} + + unary(BaseT const& base, param_t subj_) + : base_t(base), subj(subj_) {} + + return_t + subject() const + { return subj; } + + private: + + subject_embed_t subj; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // binary class. + // + // Composite class composed of a pair (left and right). This + // template class is parameterized by the left and right subject + // types A and B and a base class to inherit from, BaseT. The binary + // class is meant to be a base class to inherit from. The + // inheritance structure, given the BaseT template parameter places + // the binary class in the middle of a linear, single parent + // hierarchy. For instance, given classes X and Y and a base class + // B, a class D can derive from binary: + // + // struct D : public binary {...}; + // + // The inheritance structure is thus: + // + // B + // | + // binary (has X and Y) + // | + // D + // + // The left and right subjects can be accessed from the derived + // class D as: this->left(); and this->right(); + // + // Typically, the pairs X and Y are specified as typename X::embed_t + // and typename Y::embed_t. embed_t specifies how the subject is + // embedded in the composite (See parser.hpp for details). + // + /////////////////////////////////////////////////////////////////////////////// + template + class binary : public BaseT + { + public: + + typedef BaseT base_t; + typedef typename boost::call_traits::param_type left_param_t; + typedef typename boost::call_traits::const_reference left_return_t; + typedef typename boost::call_traits::param_type right_param_t; + typedef typename boost::call_traits::const_reference right_return_t; + typedef A left_t; + typedef typename A::embed_t left_embed_t; + typedef B right_t; + typedef typename B::embed_t right_embed_t; + + binary(left_param_t a, right_param_t b) + : base_t(), subj(a, b) {} + + left_return_t + left() const + { return subj.first(); } + + right_return_t + right() const + { return subj.second(); } + + private: + + boost::compressed_pair subj; + }; + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/difference.hpp b/boost/boost/spirit/core/composite/difference.hpp new file mode 100644 index 0000000000..51ad9e3c14 --- /dev/null +++ b/boost/boost/spirit/core/composite/difference.hpp @@ -0,0 +1,137 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIFFERENCE_HPP) +#define BOOST_SPIRIT_DIFFERENCE_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // difference: a - b; Matches a but not b + // + // Handles expressions of the form: + // + // a - b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a but not b. One (not both) of the operands + // may be a literal char, wchar_t or a primitive string char const*, + // wchar_t const*. + // + /////////////////////////////////////////////////////////////////////////// + struct difference_parser_gen; + + template + struct difference + : public binary > > + { + typedef difference self_t; + typedef binary_parser_category parser_category_t; + typedef difference_parser_gen parser_generator_t; + typedef binary > base_t; + + difference(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (result_t hl = this->left().parse(scan)) + { + std::swap(save, scan.first); + result_t hr = this->right().parse(scan); + if (!hr || (hr.length() < hl.length())) + { + scan.first = save; + return hl; + } + } + + return scan.no_match(); + } + }; + + struct difference_parser_gen + { + template + struct result + { + typedef + difference< + typename as_parser::type + , typename as_parser::type + > + type; + }; + + template + static difference< + typename as_parser::type + , typename as_parser::type + > + generate(A const& a, B const& b) + { + return difference::type, + BOOST_DEDUCED_TYPENAME as_parser::type> + (as_parser::convert(a), as_parser::convert(b)); + } + }; + + template + difference + operator-(parser const& a, parser const& b); + + template + difference > + operator-(parser const& a, char b); + + template + difference, B> + operator-(char a, parser const& b); + + template + difference > + operator-(parser const& a, char const* b); + + template + difference, B> + operator-(char const* a, parser const& b); + + template + difference > + operator-(parser const& a, wchar_t b); + + template + difference, B> + operator-(wchar_t a, parser const& b); + + template + difference > + operator-(parser const& a, wchar_t const* b); + + template + difference, B> + operator-(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/directives.hpp b/boost/boost/spirit/core/composite/directives.hpp new file mode 100644 index 0000000000..232100933d --- /dev/null +++ b/boost/boost/spirit/core/composite/directives.hpp @@ -0,0 +1,624 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIRECTIVES_HPP) +#define BOOST_SPIRIT_DIRECTIVES_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // no_skipper_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + template + struct no_skipper_iteration_policy : public BaseT + { + typedef BaseT base_t; + + no_skipper_iteration_policy() + : BaseT() {} + + template + no_skipper_iteration_policy(PolicyT const& other) + : BaseT(other) {} + + template + void + skip(ScannerT const& /*scan*/) const {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // contiguous class + // + /////////////////////////////////////////////////////////////////////////// + struct lexeme_parser_gen; + + template + struct contiguous + : public unary > > + { + typedef contiguous self_t; + typedef unary_parser_category parser_category_t; + typedef lexeme_parser_gen parser_generator_t; + typedef unary > base_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + contiguous(ParserT const& p) + : base_t(p) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + return impl::contiguous_parser_parse + (this->subject(), scan, scan); + } + }; + + struct lexeme_parser_gen + { + template + struct result { + + typedef contiguous type; + }; + + template + static contiguous + generate(parser const& subject) + { + return contiguous(subject.derived()); + } + + template + contiguous + operator[](parser const& subject) const + { + return contiguous(subject.derived()); + } + }; + + ////////////////////////////////// + const lexeme_parser_gen lexeme_d = lexeme_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // lexeme_scanner + // + // Given a Scanner, return the correct scanner type that + // the lexeme_d uses. Scanner is assumed to be a phrase + // level scanner (see skipper.hpp) + // + /////////////////////////////////////////////////////////////////////////// + template + struct lexeme_scanner + { + typedef scanner_policies< + no_skipper_iteration_policy< + typename ScannerT::iteration_policy_t>, + typename ScannerT::match_policy_t, + typename ScannerT::action_policy_t + > policies_t; + + typedef typename + rebind_scanner_policies::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // inhibit_case_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + template + struct inhibit_case_iteration_policy : public BaseT + { + typedef BaseT base_t; + + inhibit_case_iteration_policy() + : BaseT() {} + + template + inhibit_case_iteration_policy(PolicyT const& other) + : BaseT(other) {} + + template + CharT filter(CharT ch) const + { return impl::tolower_(ch); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // inhibit_case class + // + /////////////////////////////////////////////////////////////////////////// + struct inhibit_case_parser_gen; + + template + struct inhibit_case + : public unary > > + { + typedef inhibit_case self_t; + typedef unary_parser_category parser_category_t; + typedef inhibit_case_parser_gen parser_generator_t; + typedef unary > base_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + inhibit_case(ParserT const& p) + : base_t(p) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + return impl::inhibit_case_parser_parse + (this->subject(), scan, scan); + } + }; + + template + struct inhibit_case_parser_gen_base + { + // This hack is needed to make borland happy. + // If these member operators were defined in the + // inhibit_case_parser_gen class, or if this class + // is non-templated, borland ICEs. + + static inhibit_case > + generate(char const* str) + { return inhibit_case >(str); } + + static inhibit_case > + generate(wchar_t const* str) + { return inhibit_case >(str); } + + static inhibit_case > + generate(char ch) + { return inhibit_case >(ch); } + + static inhibit_case > + generate(wchar_t ch) + { return inhibit_case >(ch); } + + template + static inhibit_case + generate(parser const& subject) + { return inhibit_case(subject.derived()); } + + inhibit_case > + operator[](char const* str) const + { return inhibit_case >(str); } + + inhibit_case > + operator[](wchar_t const* str) const + { return inhibit_case >(str); } + + inhibit_case > + operator[](char ch) const + { return inhibit_case >(ch); } + + inhibit_case > + operator[](wchar_t ch) const + { return inhibit_case >(ch); } + + template + inhibit_case + operator[](parser const& subject) const + { return inhibit_case(subject.derived()); } + }; + + ////////////////////////////////// + struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0> + { + inhibit_case_parser_gen() {} + }; + + ////////////////////////////////// + // Depracated + const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen(); + + // Preferred syntax + const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // as_lower_scanner + // + // Given a Scanner, return the correct scanner type that + // the as_lower_d uses. Scanner is assumed to be a scanner + // with an inhibit_case_iteration_policy. + // + /////////////////////////////////////////////////////////////////////////// + template + struct as_lower_scanner + { + typedef scanner_policies< + inhibit_case_iteration_policy< + typename ScannerT::iteration_policy_t>, + typename ScannerT::match_policy_t, + typename ScannerT::action_policy_t + > policies_t; + + typedef typename + rebind_scanner_policies::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // longest_alternative class + // + /////////////////////////////////////////////////////////////////////////// + struct longest_parser_gen; + + template + struct longest_alternative + : public binary > > + { + typedef longest_alternative self_t; + typedef binary_parser_category parser_category_t; + typedef longest_parser_gen parser_generator_t; + typedef binary > base_t; + + longest_alternative(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typename ScannerT::iterator_t save = scan.first; + result_t l = this->left().parse(scan); + std::swap(scan.first, save); + result_t r = this->right().parse(scan); + + if (l || r) + { + if (l.length() > r.length()) + { + scan.first = save; + return l; + } + return r; + } + + return scan.no_match(); + } + }; + + struct longest_parser_gen + { + template + struct result { + + typedef typename + impl::to_longest_alternative >::result_t + type; + }; + + template + static typename + impl::to_longest_alternative >::result_t + generate(alternative const& alt) + { + return impl::to_longest_alternative >:: + convert(alt); + } + + //'generate' for binary composite + template + static + longest_alternative + generate(A const &left, B const &right) + { + return longest_alternative(left, right); + } + + template + typename impl::to_longest_alternative >::result_t + operator[](alternative const& alt) const + { + return impl::to_longest_alternative >:: + convert(alt); + } + }; + + const longest_parser_gen longest_d = longest_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // shortest_alternative class + // + /////////////////////////////////////////////////////////////////////////// + struct shortest_parser_gen; + + template + struct shortest_alternative + : public binary > > + { + typedef shortest_alternative self_t; + typedef binary_parser_category parser_category_t; + typedef shortest_parser_gen parser_generator_t; + typedef binary > base_t; + + shortest_alternative(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typename ScannerT::iterator_t save = scan.first; + result_t l = this->left().parse(scan); + std::swap(scan.first, save); + result_t r = this->right().parse(scan); + + if (l || r) + { + if (l.length() < r.length() && l || !r) + { + scan.first = save; + return l; + } + return r; + } + + return scan.no_match(); + } + }; + + struct shortest_parser_gen + { + template + struct result { + + typedef typename + impl::to_shortest_alternative >::result_t + type; + }; + + template + static typename + impl::to_shortest_alternative >::result_t + generate(alternative const& alt) + { + return impl::to_shortest_alternative >:: + convert(alt); + } + + //'generate' for binary composite + template + static + shortest_alternative + generate(A const &left, B const &right) + { + return shortest_alternative(left, right); + } + + template + typename impl::to_shortest_alternative >::result_t + operator[](alternative const& alt) const + { + return impl::to_shortest_alternative >:: + convert(alt); + } + }; + + const shortest_parser_gen shortest_d = shortest_parser_gen(); + + /////////////////////////////////////////////////////////////////////////// + // + // min_bounded class + // + /////////////////////////////////////////////////////////////////////////// + template + struct min_bounded_gen; + + template + struct min_bounded + : public unary > > + { + typedef min_bounded self_t; + typedef unary_parser_category parser_category_t; + typedef min_bounded_gen parser_generator_t; + typedef unary > base_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + min_bounded(ParserT const& p, BoundsT const& min__) + : base_t(p) + , min_(min__) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + result_t hit = this->subject().parse(scan); + if (hit.has_valid_attribute() && hit.value() < min_) + return scan.no_match(); + return hit; + } + + BoundsT min_; + }; + + template + struct min_bounded_gen + { + min_bounded_gen(BoundsT const& min__) + : min_(min__) {} + + template + min_bounded + operator[](parser const& p) const + { return min_bounded(p.derived(), min_); } + + BoundsT min_; + }; + + template + inline min_bounded_gen + min_limit_d(BoundsT const& min_) + { return min_bounded_gen(min_); } + + /////////////////////////////////////////////////////////////////////////// + // + // max_bounded class + // + /////////////////////////////////////////////////////////////////////////// + template + struct max_bounded_gen; + + template + struct max_bounded + : public unary > > + { + typedef max_bounded self_t; + typedef unary_parser_category parser_category_t; + typedef max_bounded_gen parser_generator_t; + typedef unary > base_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + max_bounded(ParserT const& p, BoundsT const& max__) + : base_t(p) + , max_(max__) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + result_t hit = this->subject().parse(scan); + if (hit.has_valid_attribute() && hit.value() > max_) + return scan.no_match(); + return hit; + } + + BoundsT max_; + }; + + template + struct max_bounded_gen + { + max_bounded_gen(BoundsT const& max__) + : max_(max__) {} + + template + max_bounded + operator[](parser const& p) const + { return max_bounded(p.derived(), max_); } + + BoundsT max_; + }; + + ////////////////////////////////// + template + inline max_bounded_gen + max_limit_d(BoundsT const& max_) + { return max_bounded_gen(max_); } + + /////////////////////////////////////////////////////////////////////////// + // + // bounded class + // + /////////////////////////////////////////////////////////////////////////// + template + struct bounded_gen; + + template + struct bounded + : public unary > > + { + typedef bounded self_t; + typedef unary_parser_category parser_category_t; + typedef bounded_gen parser_generator_t; + typedef unary > base_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) + : base_t(p) + , min_(min__) + , max_(max__) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + result_t hit = this->subject().parse(scan); + if (hit.has_valid_attribute() && + (hit.value() < min_ || hit.value() > max_)) + return scan.no_match(); + return hit; + } + + BoundsT min_, max_; + }; + + template + struct bounded_gen + { + bounded_gen(BoundsT const& min__, BoundsT const& max__) + : min_(min__) + , max_(max__) {} + + template + bounded + operator[](parser const& p) const + { return bounded(p.derived(), min_, max_); } + + BoundsT min_, max_; + }; + + template + inline bounded_gen + limit_d(BoundsT const& min_, BoundsT const& max_) + { return bounded_gen(min_, max_); } + +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/composite/epsilon.hpp b/boost/boost/spirit/core/composite/epsilon.hpp new file mode 100644 index 0000000000..fcfb125e1c --- /dev/null +++ b/boost/boost/spirit/core/composite/epsilon.hpp @@ -0,0 +1,268 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_EPSILON_HPP +#define BOOST_SPIRIT_EPSILON_HPP + +//////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +/////////////////////////////////////////////////////////////////////////////// +// +// condition_parser class +// +// handles expresions of the form +// +// epsilon_p(cond) +// +// where cond is a function or a functor that returns a value suitable +// to be used in boolean context. The expression returns a parser that +// returns an empty match when the condition evaluates to true. +// +/////////////////////////////////////////////////////////////////////////////// + template + struct condition_parser : parser > + { + typedef condition_parser self_t; + + // not explicit! (needed for implementation of if_p et al.) + condition_parser(CondT const& cond_) : cond(cond_) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + if (positive_ == cond()) + return scan.empty_match(); + else + return scan.no_match(); + } + + condition_parser + negate() const + { return condition_parser(cond); } + + private: + + CondT cond; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) // VC 7.1 + template + inline condition_parser + operator~(condition_parser const& p) + { return p.negate(); } + + template + inline condition_parser + operator~(condition_parser const& p) + { return p.negate(); } +#else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) + template + inline condition_parser + operator~(condition_parser const& p) + { return p.negate(); } +#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) + +/////////////////////////////////////////////////////////////////////////////// +// +// empty_match_parser class +// +// handles expressions of the form +// epsilon_p(subject) +// where subject is a parser. The expresion returns a composite +// parser that returns an empty match if the subject parser matches. +// +/////////////////////////////////////////////////////////////////////////////// + struct empty_match_parser_gen; + struct negated_empty_match_parser_gen; + + template + struct negated_empty_match_parser; // Forward declaration + + template + struct empty_match_parser + : unary > > + { + typedef empty_match_parser self_t; + typedef unary > base_t; + typedef unary_parser_category parser_category_t; + typedef empty_match_parser_gen parser_genererator_t; + typedef self_t embed_t; + + explicit empty_match_parser(SubjectT const& p) : base_t(p) {} + + template + struct result + { typedef typename match_result::type type; }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typename ScannerT::iterator_t save(scan.first); + + typedef typename no_actions_scanner::policies_t + policies_t; + + bool matches = this->subject().parse( + scan.change_policies(policies_t(scan))); + if (matches) + { + scan.first = save; // reset the position + return scan.empty_match(); + } + else + { + return scan.no_match(); + } + } + + negated_empty_match_parser + negate() const + { return negated_empty_match_parser(this->subject()); } + }; + + template + struct negated_empty_match_parser + : public unary > > + { + typedef negated_empty_match_parser self_t; + typedef unary > base_t; + typedef unary_parser_category parser_category_t; + typedef negated_empty_match_parser_gen parser_genererator_t; + + explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {} + + template + struct result + { typedef typename match_result::type type; }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typename ScannerT::iterator_t save(scan.first); + + typedef typename no_actions_scanner::policies_t + policies_t; + + bool matches = this->subject().parse( + scan.change_policies(policies_t(scan))); + if (!matches) + { + scan.first = save; // reset the position + return scan.empty_match(); + } + else + { + return scan.no_match(); + } + } + + empty_match_parser + negate() const + { return empty_match_parser(this->subject()); } + }; + + struct empty_match_parser_gen + { + template + struct result + { typedef empty_match_parser type; }; + + template + static empty_match_parser + generate(parser const& subject) + { return empty_match_parser(subject.derived()); } + }; + + struct negated_empty_match_parser_gen + { + template + struct result + { typedef negated_empty_match_parser type; }; + + template + static negated_empty_match_parser + generate(parser const& subject) + { return negated_empty_match_parser(subject.derived()); } + }; + + ////////////////////////////// + template + inline negated_empty_match_parser + operator~(empty_match_parser const& p) + { return p.negate(); } + + template + inline empty_match_parser + operator~(negated_empty_match_parser const& p) + { return p.negate(); } + +/////////////////////////////////////////////////////////////////////////////// +// +// epsilon_ parser and parser generator class +// +// Operates as primitive parser that always matches an empty sequence. +// +// Also operates as a parser generator. According to the type of the +// argument an instance of empty_match_parser<> (when the argument is +// a parser) or condition_parser<> (when the argument is not a parser) +// is returned by operator(). +// +/////////////////////////////////////////////////////////////////////////////// + namespace impl + { + template + struct epsilon_selector + { + typedef typename as_parser::type subject_t; + typedef typename + mpl::if_< + is_parser + ,empty_match_parser + ,condition_parser + >::type type; + }; + } + + struct epsilon_parser : public parser + { + typedef epsilon_parser self_t; + + epsilon_parser() {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { return scan.empty_match(); } + + template + typename impl::epsilon_selector::type + operator()(SubjectT const& subject) const + { + typedef typename impl::epsilon_selector::type result_t; + return result_t(subject); + } + }; + + epsilon_parser const epsilon_p = epsilon_parser(); + epsilon_parser const eps_p = epsilon_parser(); + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/exclusive_or.hpp b/boost/boost/spirit/core/composite/exclusive_or.hpp new file mode 100644 index 0000000000..e7af4530d1 --- /dev/null +++ b/boost/boost/spirit/core/composite/exclusive_or.hpp @@ -0,0 +1,138 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_HPP) +#define BOOST_SPIRIT_EXCLUSIVE_OR_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // exclusive_or class + // + // Handles expressions of the form: + // + // a ^ b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a or b but not both. One (not both) of the + // operands may be a literal char, wchar_t or a primitive string + // char const*, wchar_t const*. + // + /////////////////////////////////////////////////////////////////////////// + struct exclusive_or_parser_gen; + + template + struct exclusive_or + : public binary > > + { + typedef exclusive_or self_t; + typedef binary_parser_category parser_category_t; + typedef exclusive_or_parser_gen parser_generator_t; + typedef binary > base_t; + + exclusive_or(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + + iterator_t save = scan.first; + result_t l = this->left().parse(scan); + std::swap(save, scan.first); + result_t r = this->right().parse(scan); + + if (l ? !bool(r) : bool(r)) + { + if (l) + scan.first = save; + return l ? l : r; + } + + return scan.no_match(); + } + }; + + struct exclusive_or_parser_gen + { + template + struct result + { + typedef + exclusive_or< + typename as_parser::type + , typename as_parser::type + > + type; + }; + + template + static exclusive_or< + typename as_parser::type + , typename as_parser::type + > + generate(A const& a, B const& b) + { + return exclusive_or::type, + BOOST_DEDUCED_TYPENAME as_parser::type> + (as_parser::convert(a), as_parser::convert(b)); + } + }; + + template + exclusive_or + operator^(parser const& a, parser const& b); + + template + exclusive_or > + operator^(parser const& a, char b); + + template + exclusive_or, B> + operator^(char a, parser const& b); + + template + exclusive_or > + operator^(parser const& a, char const* b); + + template + exclusive_or, B> + operator^(char const* a, parser const& b); + + template + exclusive_or > + operator^(parser const& a, wchar_t b); + + template + exclusive_or, B> + operator^(wchar_t a, parser const& b); + + template + exclusive_or > + operator^(parser const& a, wchar_t const* b); + + template + exclusive_or, B> + operator^(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/impl/alternative.ipp b/boost/boost/spirit/core/composite/impl/alternative.ipp new file mode 100644 index 0000000000..d03901cde2 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/alternative.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_ALTERNATIVE_IPP) +#define BOOST_SPIRIT_ALTERNATIVE_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // alternative class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline alternative + operator|(parser const& a, parser const& b) + { + return alternative(a.derived(), b.derived()); + } + + template + inline alternative > + operator|(parser const& a, char b) + { + return alternative >(a.derived(), b); + } + + template + inline alternative, B> + operator|(char a, parser const& b) + { + return alternative, B>(a, b.derived()); + } + + template + inline alternative > + operator|(parser const& a, char const* b) + { + return alternative >(a.derived(), b); + } + + template + inline alternative, B> + operator|(char const* a, parser const& b) + { + return alternative, B>(a, b.derived()); + } + + template + inline alternative > + operator|(parser const& a, wchar_t b) + { + return alternative >(a.derived(), b); + } + + template + inline alternative, B> + operator|(wchar_t a, parser const& b) + { + return alternative, B>(a, b.derived()); + } + + template + inline alternative > + operator|(parser const& a, wchar_t const* b) + { + return alternative >(a.derived(), b); + } + + template + inline alternative, B> + operator|(wchar_t const* a, parser const& b) + { + return alternative, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/difference.ipp b/boost/boost/spirit/core/composite/impl/difference.ipp new file mode 100644 index 0000000000..533ec343e5 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/difference.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIFFERENCE_IPP) +#define BOOST_SPIRIT_DIFFERENCE_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // difference class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline difference + operator-(parser const& a, parser const& b) + { + return difference(a.derived(), b.derived()); + } + + template + inline difference > + operator-(parser const& a, char b) + { + return difference >(a.derived(), b); + } + + template + inline difference, B> + operator-(char a, parser const& b) + { + return difference, B>(a, b.derived()); + } + + template + inline difference > + operator-(parser const& a, char const* b) + { + return difference >(a.derived(), b); + } + + template + inline difference, B> + operator-(char const* a, parser const& b) + { + return difference, B>(a, b.derived()); + } + + template + inline difference > + operator-(parser const& a, wchar_t b) + { + return difference >(a.derived(), b); + } + + template + inline difference, B> + operator-(wchar_t a, parser const& b) + { + return difference, B>(a, b.derived()); + } + + template + inline difference > + operator-(parser const& a, wchar_t const* b) + { + return difference >(a.derived(), b); + } + + template + inline difference, B> + operator-(wchar_t const* a, parser const& b) + { + return difference, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/directives.ipp b/boost/boost/spirit/core/composite/impl/directives.ipp new file mode 100644 index 0000000000..48cc1d10ed --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/directives.ipp @@ -0,0 +1,370 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2001 Bruce Florman + Copyright (c) 2002 Raghavendra Satish + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_DIRECTIVES_IPP) +#define BOOST_SPIRIT_DIRECTIVES_IPP + +/////////////////////////////////////////////////////////////////////////////// +#include + +namespace boost { namespace spirit { + + template + struct no_skipper_iteration_policy; + + template + struct inhibit_case_iteration_policy; + + template + struct alternative; + + template + struct longest_alternative; + + template + struct shortest_alternative; + + namespace impl + { + template + inline RT + contiguous_parser_parse( + ST const& s, + ScannerT const& scan, + skipper_iteration_policy const&) + { + typedef scanner_policies< + no_skipper_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + scan.skip(scan); + RT hit = s.parse(scan.change_policies(policies_t(scan))); + // We will not do a post skip!!! + return hit; + } + + template + inline RT + contiguous_parser_parse( + ST const& s, + ScannerT const& scan, + no_skipper_iteration_policy const&) + { + return s.parse(scan); + } + + template + inline RT + contiguous_parser_parse( + ST const& s, + ScannerT const& scan, + iteration_policy const&) + { + return s.parse(scan); + } + + template < + typename RT, + typename ParserT, + typename ScannerT, + typename BaseT> + inline RT + implicit_lexeme_parse( + ParserT const& p, + ScannerT const& scan, + skipper_iteration_policy const&) + { + typedef scanner_policies< + no_skipper_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + scan.skip(scan); + RT hit = p.parse_main(scan.change_policies(policies_t(scan))); + // We will not do a post skip!!! + return hit; + } + + template < + typename RT, + typename ParserT, + typename ScannerT, + typename BaseT> + inline RT + implicit_lexeme_parse( + ParserT const& p, + ScannerT const& scan, + no_skipper_iteration_policy const&) + { + return p.parse_main(scan); + } + + template + inline RT + implicit_lexeme_parse( + ParserT const& p, + ScannerT const& scan, + iteration_policy const&) + { + return p.parse_main(scan); + } + + template + inline RT + inhibit_case_parser_parse( + ST const& s, + ScannerT const& scan, + iteration_policy const&) + { + typedef scanner_policies< + inhibit_case_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + return s.parse(scan.change_policies(policies_t(scan))); + } + + template + inline RT + inhibit_case_parser_parse( + ST const& s, + ScannerT const& scan, + inhibit_case_iteration_policy const&) + { + return s.parse(scan); + } + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + /////////////////////////////////////////////////////////////////////// + // + // from spirit 1.1 (copyright (c) 2001 Bruce Florman) + // various workarounds to support longest and shortest directives + // + /////////////////////////////////////////////////////////////////////// + template + struct is_alternative + { + // Determine at compile time (without partial specialization) + // whether a given type is an instance of the alternative + + static T t(); + template + static char test_(alternative const&); // no implementation + static int test_(...); // no implementation + enum { r = sizeof(char) == sizeof(test_(t())) }; + typedef mpl::bool_ value; + }; + + template struct select_to_longest; + + template + struct to_longest_alternative + { + typedef typename select_to_longest::result_t result_t; + typedef typename select_to_longest::plain_t plain_t; + typedef typename select_to_longest::choose_t choose_t; + static result_t convert(T const& a); + }; + + template + struct to_longest_generic + { + typedef T const& result_t; + typedef T plain_t; + typedef mpl::false_ choose_t; + }; + + template + inline T const& + to_longest_convert(T const& a, mpl::false_) + { return a; } + + template + struct to_longest_recursive + { + typedef typename to_longest_alternative< + typename T::left_t>::plain_t a_t; + typedef typename to_longest_alternative< + typename T::right_t>::plain_t b_t; + + typedef longest_alternative result_t; + + typedef result_t plain_t; + typedef mpl::true_ choose_t; + }; + + template + inline typename to_longest_alternative >::result_t + to_longest_convert(alternative const& alt, mpl::true_) + { + typedef typename to_longest_alternative< + alternative >::result_t result_t; + return result_t( + to_longest_alternative::convert(alt.left()), + to_longest_alternative::convert(alt.right())); + } + + template + inline typename to_longest_alternative::result_t + to_longest_alternative::convert(T const& a) + { + return to_longest_convert( + a, to_longest_alternative::choose_t()); + } + + template + struct select_to_longest + { + typedef typename mpl::if_< + is_alternative // IF + , to_longest_recursive // THEN + , to_longest_generic // ELSE + >::type type; + + typedef typename select_to_longest::type::result_t result_t; + typedef typename select_to_longest::type::plain_t plain_t; + typedef typename select_to_longest::type::choose_t choose_t; + }; + + template struct select_to_shortest; + + template + struct to_shortest_alternative + { + typedef typename select_to_shortest::result_t result_t; + typedef typename select_to_shortest::plain_t plain_t; + typedef typename select_to_shortest::choose_t choose_t; + static result_t convert(T const& a); + }; + + template + struct to_shortest_generic + { + typedef T const& result_t; + typedef T plain_t; + typedef mpl::false_ choose_t; + }; + + template + inline T const& + to_shortest_convert(T const& a, mpl::false_) { return a; } + + template + struct to_shortest_recursive + { + typedef typename to_shortest_alternative< + typename T::left_t>::plain_t a_t; + typedef typename to_shortest_alternative< + typename T::right_t>::plain_t b_t; + + typedef shortest_alternative result_t; + + typedef result_t plain_t; + typedef mpl::true_ choose_t; + }; + + template + inline typename to_shortest_alternative >::result_t + to_shortest_convert(alternative const& alt, mpl::true_) + { + typedef typename to_shortest_alternative< + alternative >::result_t result_t; + return result_t( + to_shortest_alternative::convert(alt.left()), + to_shortest_alternative::convert(alt.right())); + } + + template + inline typename to_shortest_alternative::result_t + to_shortest_alternative::convert(T const& a) + { + return to_shortest_convert( + a, to_shortest_alternative::choose_t()); + } + + template + struct select_to_shortest + { + typedef typename mpl::if_< + is_alternative // IF + , to_shortest_recursive // THEN + , to_shortest_generic // ELSE + >::type type; + + typedef typename select_to_shortest::type::result_t result_t; + typedef typename select_to_shortest::type::plain_t plain_t; + typedef typename select_to_shortest::type::choose_t choose_t; + }; +#else + template + struct to_longest_alternative + { + typedef T result_t; + static result_t const& + convert(T const& a) // Special (end) case + { return a; } + }; + + template + struct to_longest_alternative > + { + typedef typename to_longest_alternative::result_t a_t; + typedef typename to_longest_alternative::result_t b_t; + typedef longest_alternative result_t; + + static result_t + convert(alternative const& alt) // Recursive case + { + return result_t( + to_longest_alternative::convert(alt.left()), + to_longest_alternative::convert(alt.right())); + } + }; + + template + struct to_shortest_alternative + { + typedef T result_t; + static result_t const& + convert(T const& a) // Special (end) case + { return a; } + }; + + template + struct to_shortest_alternative > + { + typedef typename to_shortest_alternative::result_t a_t; + typedef typename to_shortest_alternative::result_t b_t; + typedef shortest_alternative result_t; + + static result_t + convert(alternative const& alt) // Recursive case + { + return result_t( + to_shortest_alternative::convert(alt.left()), + to_shortest_alternative::convert(alt.right())); + } + }; +#endif + } + +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/composite/impl/exclusive_or.ipp b/boost/boost/spirit/core/composite/impl/exclusive_or.ipp new file mode 100644 index 0000000000..79a607dce1 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/exclusive_or.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_IPP) +#define BOOST_SPIRIT_EXCLUSIVE_OR_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // exclusive_or class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline exclusive_or + operator^(parser const& a, parser const& b) + { + return exclusive_or(a.derived(), b.derived()); + } + + template + inline exclusive_or > + operator^(parser const& a, char b) + { + return exclusive_or >(a.derived(), b); + } + + template + inline exclusive_or, B> + operator^(char a, parser const& b) + { + return exclusive_or, B>(a, b.derived()); + } + + template + inline exclusive_or > + operator^(parser const& a, char const* b) + { + return exclusive_or >(a.derived(), b); + } + + template + inline exclusive_or, B> + operator^(char const* a, parser const& b) + { + return exclusive_or, B>(a, b.derived()); + } + + template + inline exclusive_or > + operator^(parser const& a, wchar_t b) + { + return exclusive_or >(a.derived(), b); + } + + template + inline exclusive_or, B> + operator^(wchar_t a, parser const& b) + { + return exclusive_or, B>(a, b.derived()); + } + + template + inline exclusive_or > + operator^(parser const& a, wchar_t const* b) + { + return exclusive_or >(a.derived(), b); + } + + template + inline exclusive_or, B> + operator^(wchar_t const* a, parser const& b) + { + return exclusive_or, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/intersection.ipp b/boost/boost/spirit/core/composite/impl/intersection.ipp new file mode 100644 index 0000000000..5f1f51b283 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/intersection.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_INTERSECTION_IPP) +#define BOOST_SPIRIT_INTERSECTION_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // intersection class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline intersection + operator&(parser const& a, parser const& b) + { + return intersection(a.derived(), b.derived()); + } + + template + inline intersection > + operator&(parser const& a, char b) + { + return intersection >(a.derived(), b); + } + + template + inline intersection, B> + operator&(char a, parser const& b) + { + return intersection, B>(a, b.derived()); + } + + template + inline intersection > + operator&(parser const& a, char const* b) + { + return intersection >(a.derived(), b); + } + + template + inline intersection, B> + operator&(char const* a, parser const& b) + { + return intersection, B>(a, b.derived()); + } + + template + inline intersection > + operator&(parser const& a, wchar_t b) + { + return intersection >(a.derived(), b); + } + + template + inline intersection, B> + operator&(wchar_t a, parser const& b) + { + return intersection, B>(a, b.derived()); + } + + template + inline intersection > + operator&(parser const& a, wchar_t const* b) + { + return intersection >(a.derived(), b); + } + + template + inline intersection, B> + operator&(wchar_t const* a, parser const& b) + { + return intersection, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/kleene_star.ipp b/boost/boost/spirit/core/composite/impl/kleene_star.ipp new file mode 100644 index 0000000000..1ed639fb0c --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/kleene_star.ipp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_KLEENE_STAR_IPP) +#define BOOST_SPIRIT_KLEENE_STAR_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // kleene_star class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline kleene_star + operator*(parser const& a) + { + return kleene_star(a.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/list.ipp b/boost/boost/spirit/core/composite/impl/list.ipp new file mode 100644 index 0000000000..36ecbc56fe --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/list.ipp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_LIST_IPP) +#define BOOST_SPIRIT_LIST_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // operator% is defined as: + // a % b ---> a >> *(b >> a) + // + /////////////////////////////////////////////////////////////////////////// + template + inline sequence > > + operator%(parser const& a, parser const& b) + { + return a.derived() >> *(b.derived() >> a.derived()); + } + + template + inline sequence, A> > > + operator%(parser const& a, char b) + { + return a.derived() >> *(b >> a.derived()); + } + + template + inline sequence, kleene_star > > > + operator%(char a, parser const& b) + { + return a >> *(b.derived() >> a); + } + + template + inline sequence, A> > > + operator%(parser const& a, char const* b) + { + return a.derived() >> *(b >> a.derived()); + } + + template + inline sequence, + kleene_star > > > + operator%(char const* a, parser const& b) + { + return a >> *(b.derived() >> a); + } + + template + inline sequence, A> > > + operator%(parser const& a, wchar_t b) + { + return a.derived() >> *(b >> a.derived()); + } + + template + inline sequence, kleene_star > > > + operator%(wchar_t a, parser const& b) + { + return a >> *(b.derived() >> a); + } + + template + inline sequence, A> > > + operator%(parser const& a, wchar_t const* b) + { + return a.derived() >> *(b >> a.derived()); + } + + template + inline sequence, + kleene_star > > > + operator%(wchar_t const* a, parser const& b) + { + return a >> *(b.derived() >> a); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/optional.ipp b/boost/boost/spirit/core/composite/impl/optional.ipp new file mode 100644 index 0000000000..7bbe6b4065 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/optional.ipp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_OPTIONAL_IPP) +#define BOOST_SPIRIT_OPTIONAL_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // optional class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + optional + operator!(parser const& a) + { + return optional(a.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/positive.ipp b/boost/boost/spirit/core/composite/impl/positive.ipp new file mode 100644 index 0000000000..cce8dc9746 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/positive.ipp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_POSITIVE_IPP) +#define BOOST_SPIRIT_POSITIVE_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // positive class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline positive + operator+(parser const& a) + { + return positive(a.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/sequence.ipp b/boost/boost/spirit/core/composite/impl/sequence.ipp new file mode 100644 index 0000000000..041dff0888 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/sequence.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENCE_IPP) +#define BOOST_SPIRIT_SEQUENCE_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // sequence class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline sequence + operator>>(parser const& a, parser const& b) + { + return sequence(a.derived(), b.derived()); + } + + template + inline sequence > + operator>>(parser const& a, char b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator>>(char a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + + template + inline sequence > + operator>>(parser const& a, char const* b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator>>(char const* a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + + template + inline sequence > + operator>>(parser const& a, wchar_t b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator>>(wchar_t a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + + template + inline sequence > + operator>>(parser const& a, wchar_t const* b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator>>(wchar_t const* a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/sequential_and.ipp b/boost/boost/spirit/core/composite/impl/sequential_and.ipp new file mode 100644 index 0000000000..03b0904ed3 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/sequential_and.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_AND_IPP) +#define BOOST_SPIRIT_SEQUENTIAL_AND_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-and operators implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline sequence + operator&&(parser const& a, parser const& b) + { + return sequence(a.derived(), b.derived()); + } + + template + inline sequence > + operator&&(parser const& a, char b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator&&(char a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + + template + inline sequence > + operator&&(parser const& a, char const* b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator&&(char const* a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + + template + inline sequence > + operator&&(parser const& a, wchar_t b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator&&(wchar_t a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + + template + inline sequence > + operator&&(parser const& a, wchar_t const* b) + { + return sequence >(a.derived(), b); + } + + template + inline sequence, B> + operator&&(wchar_t const* a, parser const& b) + { + return sequence, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/impl/sequential_or.ipp b/boost/boost/spirit/core/composite/impl/sequential_or.ipp new file mode 100644 index 0000000000..f5a41f3d39 --- /dev/null +++ b/boost/boost/spirit/core/composite/impl/sequential_or.ipp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_OR_IPP) +#define BOOST_SPIRIT_SEQUENTIAL_OR_IPP + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-or class implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline sequential_or + operator||(parser const& a, parser const& b) + { + return sequential_or(a.derived(), b.derived()); + } + + template + inline sequential_or > + operator||(parser const& a, char b) + { + return sequential_or >(a.derived(), b); + } + + template + inline sequential_or, B> + operator||(char a, parser const& b) + { + return sequential_or, B>(a, b.derived()); + } + + template + inline sequential_or > + operator||(parser const& a, char const* b) + { + return sequential_or >(a.derived(), b); + } + + template + inline sequential_or, B> + operator||(char const* a, parser const& b) + { + return sequential_or, B>(a, b.derived()); + } + + template + inline sequential_or > + operator||(parser const& a, wchar_t b) + { + return sequential_or >(a.derived(), b); + } + + template + inline sequential_or, B> + operator||(wchar_t a, parser const& b) + { + return sequential_or, B>(a, b.derived()); + } + + template + inline sequential_or > + operator||(parser const& a, wchar_t const* b) + { + return sequential_or >(a.derived(), b); + } + + template + inline sequential_or, B> + operator||(wchar_t const* a, parser const& b) + { + return sequential_or, B>(a, b.derived()); + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/composite/intersection.hpp b/boost/boost/spirit/core/composite/intersection.hpp new file mode 100644 index 0000000000..51efa7032b --- /dev/null +++ b/boost/boost/spirit/core/composite/intersection.hpp @@ -0,0 +1,138 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_INTERSECTION_HPP) +#define BOOST_SPIRIT_INTERSECTION_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // intersection class + // + // Handles expressions of the form: + // + // a & b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a and b. One (not both) of the operands may + // be a literal char, wchar_t or a primitive string char const*, + // wchar_t const*. + // + // The expression is short circuit evaluated. b is never touched + // when a is returns a no-match. + // + /////////////////////////////////////////////////////////////////////////// + struct intersection_parser_gen; + + template + struct intersection + : public binary > > + { + typedef intersection self_t; + typedef binary_parser_category parser_category_t; + typedef intersection_parser_gen parser_generator_t; + typedef binary > base_t; + + intersection(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (result_t hl = this->left().parse(scan)) + { + ScannerT bscan(scan.first, scan.first); + scan.first = save; + result_t hr = this->right().parse(bscan); + if (hl.length() == hr.length()) + return hl; + } + + return scan.no_match(); + } + }; + + struct intersection_parser_gen + { + template + struct result + { + typedef + intersection< + typename as_parser::type + , typename as_parser::type + > + type; + }; + + template + static intersection< + typename as_parser::type + , typename as_parser::type + > + generate(A const& a, B const& b) + { + return intersection::type, + BOOST_DEDUCED_TYPENAME as_parser::type> + (as_parser::convert(a), as_parser::convert(b)); + } + }; + + template + intersection + operator&(parser const& a, parser const& b); + + template + intersection > + operator&(parser const& a, char b); + + template + intersection, B> + operator&(char a, parser const& b); + + template + intersection > + operator&(parser const& a, char const* b); + + template + intersection, B> + operator&(char const* a, parser const& b); + + template + intersection > + operator&(parser const& a, wchar_t b); + + template + intersection, B> + operator&(wchar_t a, parser const& b); + + template + intersection > + operator&(parser const& a, wchar_t const* b); + + template + intersection, B> + operator&(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/kleene_star.hpp b/boost/boost/spirit/core/composite/kleene_star.hpp new file mode 100644 index 0000000000..0dc3ac5a44 --- /dev/null +++ b/boost/boost/spirit/core/composite/kleene_star.hpp @@ -0,0 +1,96 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_KLEENE_STAR_HPP) +#define BOOST_SPIRIT_KLEENE_STAR_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // kleene_star class + // + // Handles expressions of the form: + // + // *a + // + // where a is a parser. The expression returns a composite + // parser that matches its subject zero (0) or more times. + // + /////////////////////////////////////////////////////////////////////////// + struct kleene_star_parser_gen; + + template + struct kleene_star + : public unary > > + { + typedef kleene_star self_t; + typedef unary_parser_category parser_category_t; + typedef kleene_star_parser_gen parser_generator_t; + typedef unary > base_t; + + kleene_star(S const& a) + : base_t(a) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + result_t hit = scan.empty_match(); + + for (;;) + { + iterator_t save = scan.first; + if (result_t next = this->subject().parse(scan)) + { + scan.concat_match(hit, next); + } + else + { + scan.first = save; + return hit; + } + } + } + }; + + struct kleene_star_parser_gen + { + template + struct result + { + typedef kleene_star type; + }; + + template + static kleene_star + generate(parser const& a) + { + return kleene_star(a.derived()); + } + }; + + ////////////////////////////////// + template + kleene_star + operator*(parser const& a); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/list.hpp b/boost/boost/spirit/core/composite/list.hpp new file mode 100644 index 0000000000..7e94ea0245 --- /dev/null +++ b/boost/boost/spirit/core/composite/list.hpp @@ -0,0 +1,69 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_LIST_HPP) +#define BOOST_SPIRIT_LIST_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // operator% is defined as: + // a % b ---> a >> *(b >> a) + // + /////////////////////////////////////////////////////////////////////////// + template + sequence > > + operator%(parser const& a, parser const& b); + + template + sequence, A> > > + operator%(parser const& a, char b); + + template + sequence, kleene_star > > > + operator%(char a, parser const& b); + + template + sequence, A> > > + operator%(parser const& a, char const* b); + + template + sequence, + kleene_star > > > + operator%(char const* a, parser const& b); + + template + sequence, A> > > + operator%(parser const& a, wchar_t b); + + template + sequence, kleene_star > > > + operator%(wchar_t a, parser const& b); + + template + sequence, A> > > + operator%(parser const& a, wchar_t const* b); + + template + sequence, + kleene_star > > > + operator%(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/no_actions.hpp b/boost/boost/spirit/core/composite/no_actions.hpp new file mode 100644 index 0000000000..32a766f4f6 --- /dev/null +++ b/boost/boost/spirit/core/composite/no_actions.hpp @@ -0,0 +1,147 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Vaclav Vesely + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_NO_ACTIONS_HPP) +#define BOOST_SPIRIT_NO_ACTIONS_HPP + +#include +#include +#include + +namespace boost { +namespace spirit { +//----------------------------------------------------------------------------- +// no_actions_action_policy + +template +struct no_actions_action_policy: + public BaseT +{ + typedef BaseT base_t; + + no_actions_action_policy(): + BaseT() + {} + + template + no_actions_action_policy(PolicyT const& other): + BaseT(other) + {} + + template + void + do_action( + ActorT const& actor, + AttrT& val, + IteratorT const& first, + IteratorT const& last) const + {} +}; + +//----------------------------------------------------------------------------- +// no_actions_scanner + +template > +struct no_actions_scanner +{ + typedef scanner_policies< + typename ScannerT::iteration_policy_t, + typename ScannerT::match_policy_t, + no_actions_action_policy + > policies_t; + + typedef typename + rebind_scanner_policies::type type; +}; + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + +template > +struct no_actions_scanner_list +{ + typedef + scanner_list< + ScannerT, + typename no_actions_scanner::type + > + type; +}; + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + +//----------------------------------------------------------------------------- +// no_actions_parser + +struct no_actions_parser_gen; + +template +struct no_actions_parser: + public unary > > +{ + typedef no_actions_parser self_t; + typedef unary_parser_category parser_category_t; + typedef no_actions_parser_gen parser_generator_t; + typedef unary > base_t; + + template + struct result + { + typedef typename parser_result::type type; + }; + + no_actions_parser(ParserT const& p) + : base_t(p) + {} + + template + typename result::type + parse(ScannerT const& scan) const + { + typedef typename no_actions_scanner::policies_t policies_t; + + return this->subject().parse(scan.change_policies(policies_t(scan))); + } +}; + +//----------------------------------------------------------------------------- +// no_actions_parser_gen + +struct no_actions_parser_gen +{ + template + struct result + { + typedef no_actions_parser type; + }; + + template + static no_actions_parser + generate(parser const& subject) + { + return no_actions_parser(subject.derived()); + } + + template + no_actions_parser + operator[](parser const& subject) const + { + return no_actions_parser(subject.derived()); + } +}; + +//----------------------------------------------------------------------------- +// no_actions_d + +const no_actions_parser_gen no_actions_d = no_actions_parser_gen(); + +//----------------------------------------------------------------------------- +} // namespace spirit +} // namespace boost + +#endif // !defined(BOOST_SPIRIT_NO_ACTIONS_HPP) diff --git a/boost/boost/spirit/core/composite/operators.hpp b/boost/boost/spirit/core/composite/operators.hpp new file mode 100644 index 0000000000..a6563fe8e5 --- /dev/null +++ b/boost/boost/spirit/core/composite/operators.hpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_OPERATORS_HPP) +#define BOOST_SPIRIT_OPERATORS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/boost/boost/spirit/core/composite/optional.hpp b/boost/boost/spirit/core/composite/optional.hpp new file mode 100644 index 0000000000..5018551a2e --- /dev/null +++ b/boost/boost/spirit/core/composite/optional.hpp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_OPTIONAL_HPP) +#define BOOST_SPIRIT_OPTIONAL_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // optional class + // + // Handles expressions of the form: + // + // !a + // + // where a is a parser. The expression returns a composite + // parser that matches its subject zero (0) or one (1) time. + // + /////////////////////////////////////////////////////////////////////////// + struct optional_parser_gen; + + template + struct optional + : public unary > > + { + typedef optional self_t; + typedef unary_parser_category parser_category_t; + typedef optional_parser_gen parser_generator_t; + typedef unary > base_t; + + optional(S const& a) + : base_t(a) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (result_t r = this->subject().parse(scan)) + { + return r; + } + else + { + scan.first = save; + return scan.empty_match(); + } + } + }; + + struct optional_parser_gen + { + template + struct result + { + typedef optional type; + }; + + template + static optional + generate(parser const& a) + { + return optional(a.derived()); + } + }; + + template + optional + operator!(parser const& a); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/positive.hpp b/boost/boost/spirit/core/composite/positive.hpp new file mode 100644 index 0000000000..f108037a1c --- /dev/null +++ b/boost/boost/spirit/core/composite/positive.hpp @@ -0,0 +1,99 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_POSITIVE_HPP) +#define BOOST_SPIRIT_POSITIVE_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // positive class + // + // Handles expressions of the form: + // + // +a + // + // where a is a parser. The expression returns a composite + // parser that matches its subject one (1) or more times. + // + /////////////////////////////////////////////////////////////////////////// + struct positive_parser_gen; + + template + struct positive + : public unary > > + { + typedef positive self_t; + typedef unary_parser_category parser_category_t; + typedef positive_parser_gen parser_generator_t; + typedef unary > base_t; + + positive(S const& a) + : base_t(a) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + result_t hit = this->subject().parse(scan); + + if (hit) + { + for (;;) + { + iterator_t save = scan.first; + if (result_t next = this->subject().parse(scan)) + { + scan.concat_match(hit, next); + } + else + { + scan.first = save; + break; + } + } + } + return hit; + } + }; + + struct positive_parser_gen + { + template + struct result + { + typedef positive type; + }; + + template + static positive + generate(parser const& a) + { + return positive(a.derived()); + } + }; + + template + inline positive + operator+(parser const& a); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/sequence.hpp b/boost/boost/spirit/core/composite/sequence.hpp new file mode 100644 index 0000000000..e600957c79 --- /dev/null +++ b/boost/boost/spirit/core/composite/sequence.hpp @@ -0,0 +1,129 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENCE_HPP) +#define BOOST_SPIRIT_SEQUENCE_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // sequence class + // + // Handles expressions of the form: + // + // a >> b + // + // where a and b are parsers. The expression returns a composite + // parser that matches a and b in sequence. One (not both) of the + // operands may be a literal char, wchar_t or a primitive string + // char const*, wchar_t const*. + // + ////////////////////////////////////////////////////////////////////////// + struct sequence_parser_gen; + + template + struct sequence : public binary > > + { + typedef sequence self_t; + typedef binary_parser_category parser_category_t; + typedef sequence_parser_gen parser_generator_t; + typedef binary > base_t; + + sequence(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + if (result_t ma = this->left().parse(scan)) + if (result_t mb = this->right().parse(scan)) + { + scan.concat_match(ma, mb); + return ma; + } + return scan.no_match(); + } + }; + + struct sequence_parser_gen + { + template + struct result + { + typedef + sequence< + typename as_parser::type + , typename as_parser::type + > + type; + }; + + template + static sequence< + typename as_parser::type + , typename as_parser::type + > + generate(A const& a, B const& b) + { + return sequence::type, + BOOST_DEDUCED_TYPENAME as_parser::type> + (as_parser::convert(a), as_parser::convert(b)); + } + }; + + template + sequence + operator>>(parser const& a, parser const& b); + + template + sequence > + operator>>(parser const& a, char b); + + template + sequence, B> + operator>>(char a, parser const& b); + + template + sequence > + operator>>(parser const& a, char const* b); + + template + sequence, B> + operator>>(char const* a, parser const& b); + + template + sequence > + operator>>(parser const& a, wchar_t b); + + template + sequence, B> + operator>>(wchar_t a, parser const& b); + + template + sequence > + operator>>(parser const& a, wchar_t const* b); + + template + sequence, B> + operator>>(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/sequential_and.hpp b/boost/boost/spirit/core/composite/sequential_and.hpp new file mode 100644 index 0000000000..aa900e00db --- /dev/null +++ b/boost/boost/spirit/core/composite/sequential_and.hpp @@ -0,0 +1,72 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_AND_HPP) +#define BOOST_SPIRIT_SEQUENTIAL_AND_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-and operators + // + // Handles expressions of the form: + // + // a && b + // + // Same as a >> b. + // + /////////////////////////////////////////////////////////////////////////// + template + sequence + operator&&(parser const& a, parser const& b); + + template + sequence > + operator&&(parser const& a, char b); + + template + sequence, B> + operator&&(char a, parser const& b); + + template + sequence > + operator&&(parser const& a, char const* b); + + template + sequence, B> + operator&&(char const* a, parser const& b); + + template + sequence > + operator&&(parser const& a, wchar_t b); + + template + sequence, B> + operator&&(wchar_t a, parser const& b); + + template + sequence > + operator&&(parser const& a, wchar_t const* b); + + template + sequence, B> + operator&&(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/composite/sequential_or.hpp b/boost/boost/spirit/core/composite/sequential_or.hpp new file mode 100644 index 0000000000..f4ba9f13d2 --- /dev/null +++ b/boost/boost/spirit/core/composite/sequential_or.hpp @@ -0,0 +1,150 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + Copyright (c) 2002 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SEQUENTIAL_OR_HPP) +#define BOOST_SPIRIT_SEQUENTIAL_OR_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // sequential-or class + // + // Handles expressions of the form: + // + // a || b + // + // Equivalent to + // + // a | b | a >> b; + // + // where a and b are parsers. The expression returns a composite + // parser that matches matches a or b in sequence. One (not both) of + // the operands may be a literal char, wchar_t or a primitive string + // char const*, wchar_t const*. + // + /////////////////////////////////////////////////////////////////////////// + struct sequential_or_parser_gen; + + template + struct sequential_or : public binary > > + { + typedef sequential_or self_t; + typedef binary_parser_category parser_category_t; + typedef sequential_or_parser_gen parser_generator_t; + typedef binary > base_t; + + sequential_or(A const& a, B const& b) + : base_t(a, b) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::iterator_t iterator_t; + { // scope for save + iterator_t save = scan.first; + if (result_t ma = this->left().parse(scan)) + { + save = scan.first; + if (result_t mb = this->right().parse(scan)) + { + // matched a b + scan.concat_match(ma, mb); + return ma; + } + else + { + // matched a + scan.first = save; + return ma; + } + } + scan.first = save; + } + + // matched b + return this->right().parse(scan); + } + }; + + struct sequential_or_parser_gen + { + template + struct result + { + typedef + sequential_or< + typename as_parser::type + , typename as_parser::type + > + type; + }; + + template + static sequential_or< + typename as_parser::type + , typename as_parser::type + > + generate(A const& a, B const& b) + { + return sequential_or::type, + BOOST_DEDUCED_TYPENAME as_parser::type> + (as_parser::convert(a), as_parser::convert(b)); + } + }; + + template + sequential_or + operator||(parser const& a, parser const& b); + + template + sequential_or > + operator||(parser const& a, char b); + + template + sequential_or, B> + operator||(char a, parser const& b); + + template + sequential_or > + operator||(parser const& a, char const* b); + + template + sequential_or, B> + operator||(char const* a, parser const& b); + + template + sequential_or > + operator||(parser const& a, wchar_t b); + + template + sequential_or, B> + operator||(wchar_t a, parser const& b); + + template + sequential_or > + operator||(parser const& a, wchar_t const* b); + + template + sequential_or, B> + operator||(wchar_t const* a, parser const& b); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/config.hpp b/boost/boost/spirit/core/config.hpp new file mode 100644 index 0000000000..62a98412e7 --- /dev/null +++ b/boost/boost/spirit/core/config.hpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_CONFIG_HPP) +#define BOOST_SPIRIT_CONFIG_HPP + +#include + +/////////////////////////////////////////////////////////////////////////////// +// +// Compiler check: +// +// Historically, Spirit supported a lot of compilers, including (to some +// extent) poorly conforming compilers such as VC6. Spirit v1.6.x will be +// the last release that will support older poorly conforming compilers. +// Starting from Spirit v1.8.0, ill conforming compilers will not be +// supported. If you are still using one of these older compilers, you can +// still use Spirit v1.6.x. +// +// The reason why Spirit v1.6.x worked on old non-conforming compilers is +// that the authors laboriously took the trouble of searching for +// workarounds to make these compilers happy. The process takes a lot of +// time and energy, especially when one encounters the dreaded ICE or +// "Internal Compiler Error". Sometimes searching for a single workaround +// takes days or even weeks. Sometimes, there are no known workarounds. This +// stifles progress a lot. And, as the library gets more progressive and +// takes on more advanced C++ techniques, the difficulty is escalated to +// even new heights. +// +// Spirit v1.6.x will still be supported. Maintenance and bug fixes will +// still be applied. There will still be active development for the back- +// porting of new features introduced in Spirit v1.8.0 (and Spirit 1.9.0) +// to lesser able compilers; hopefully, fueled by contributions from the +// community. For instance, there is already a working AST tree back-port +// for VC6 and VC7 by Peder Holt. +// +// If you got here somehow, your compiler is known to be poorly conforming +// WRT ANSI/ISO C++ standard. Library implementers get a bad reputation when +// someone attempts to compile the code on a non-conforming compiler. She'll +// be confronted with tons of compiler errors when she tries to compile the +// library. Such errors will somehow make less informed users conclude that +// the code is poorly written. It's better for the user to see a message +// "sorry, this code has not been ported to your compiler yet", than to see +// pages and pages of compiler error messages. +// +///////////////////////////////////////////////////////////////////////////////// +#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1310)) \ + || (defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)) \ + || (defined(__GNUC__) && (__GNUC__ < 3)) \ + || (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)) +# error "Compiler not supported. See note in " +#else +// Pass... Compiler supported. +#endif + +#endif + + diff --git a/boost/boost/spirit/core/impl/match.ipp b/boost/boost/spirit/core/impl/match.ipp new file mode 100644 index 0000000000..f30f9f83e9 --- /dev/null +++ b/boost/boost/spirit/core/impl/match.ipp @@ -0,0 +1,109 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MATCH_IPP) +#define BOOST_SPIRIT_MATCH_IPP +#include + +namespace boost { namespace spirit +{ + template + inline match::match() + : len(-1), val() {} + + template + inline match::match(std::size_t length) + : len(length), val() {} + + template + inline match::match(std::size_t length, ctor_param_t val_) + : len(length), val(val_) {} + + template + inline bool + match::operator!() const + { + return len < 0; + } + + template + inline std::ptrdiff_t + match::length() const + { + return len; + } + + template + inline bool + match::has_valid_attribute() const + { + return val.is_initialized(); + } + + template + inline typename match::return_t + match::value() const + { + BOOST_SPIRIT_ASSERT(val.is_initialized()); + return *val; + } + + template + inline void + match::swap(match& other) + { + std::swap(len, other.len); + std::swap(val, other.val); + } + + inline match::match() + : len(-1) {} + + inline match::match(std::size_t length) + : len(length) {} + + inline match::match(std::size_t length, nil_t) + : len(length) {} + + inline bool + match::operator!() const + { + return len < 0; + } + + inline bool + match::has_valid_attribute() const + { + return false; + } + + inline std::ptrdiff_t + match::length() const + { + return len; + } + + inline nil_t + match::value() const + { + return nil_t(); + } + + inline void + match::value(nil_t) {} + + inline void + match::swap(match& other) + { + std::swap(len, other.len); + } + +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/impl/match_attr_traits.ipp b/boost/boost/spirit/core/impl/match_attr_traits.ipp new file mode 100644 index 0000000000..bcaa0ef491 --- /dev/null +++ b/boost/boost/spirit/core/impl/match_attr_traits.ipp @@ -0,0 +1,72 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP) +#define BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP + +#include +#include + +namespace boost { namespace spirit { namespace impl +{ + template + struct match_attr_traits + { + typedef typename + boost::optional::reference_const_type + const_reference; + + // case where src *IS* convertible to T (dest) + static void + convert(boost::optional& dest, const_reference src) + { dest.reset(src); } + + // case where src *IS NOT* convertible to T (dest) + static void + convert(boost::optional& dest, .../*src*/) + { dest.reset(); } + + template + static void + copy(boost::optional& dest, OtherMatchT const& src) + { + if (src.has_valid_attribute()) + convert(dest, src.value()); + } + + template + static void + assign(boost::optional& dest, OtherMatchT const& src) + { + if (src.has_valid_attribute()) + convert(dest, src.value()); + else + dest.reset(); + } + + // T is not reference + template + static void + set_value(boost::optional& dest, ValueT const& val, mpl::false_) + { + dest.reset(val); + } + + // T is a reference + template + static void + set_value(boost::optional& dest, ValueT const& val, mpl::true_) + { + dest.get() = val; + } + }; + +}}} // namespace boost::spirit::impl + +#endif + diff --git a/boost/boost/spirit/core/impl/parser.ipp b/boost/boost/spirit/core/impl/parser.ipp new file mode 100644 index 0000000000..3f5a372243 --- /dev/null +++ b/boost/boost/spirit/core/impl/parser.ipp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_IPP) +#define BOOST_SPIRIT_PARSER_IPP + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // + // Generic parse function implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline parse_info + parse( + IteratorT const& first_ + , IteratorT const& last + , parser const& p) + { + IteratorT first = first_; + scanner > scan(first, last); + match hit = p.derived().parse(scan); + return parse_info( + first, hit, hit && (first == last), hit.length()); + } + + /////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings implementation + // + /////////////////////////////////////////////////////////////////////////// + template + inline parse_info + parse(CharT const* str, parser const& p) + { + CharT const* last = str; + while (*last) + last++; + return parse(str, last, p); + } + +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/match.hpp b/boost/boost/spirit/core/match.hpp new file mode 100644 index 0000000000..741cc025d4 --- /dev/null +++ b/boost/boost/spirit/core/match.hpp @@ -0,0 +1,181 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_MATCH_HPP) +#define BOOST_SPIRIT_MATCH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // + // match class + // + // The match holds the result of a parser. A match object evaluates + // to true when a successful match is found, otherwise false. The + // length of the match is the number of characters (or tokens) that + // is successfully matched. This can be queried through its length() + // member function. A negative value means that the match is + // unsucessful. + // + // Each parser may have an associated attribute. This attribute is + // also returned back to the client on a successful parse through + // the match object. The match's value() member function returns the + // match's attribute. + // + // A match attribute is valid: + // + // * on a successful match + // * when its value is set through the value(val) member function + // * if it is assigned or copied from a compatible match object + // (e.g. match from match) with a valid attribute. + // + // The match attribute is undefined: + // + // * on an unsuccessful match + // * when an attempt to copy or assign from another match object + // with an incompatible attribute type (e.g. match + // from match). + // + // The member function has_valid_attribute() can be queried to know if + // it is safe to get the match's attribute. The attribute may be set + // through the member function value(v) where v is the new attribute + // value. + // + /////////////////////////////////////////////////////////////////////////// + template + class match : public safe_bool > + { + + public: + + typedef typename boost::optional optional_type; + typedef typename optional_type::argument_type ctor_param_t; + typedef typename optional_type::reference_const_type return_t; + typedef T attr_t; + + match(); + explicit match(std::size_t length); + match(std::size_t length, ctor_param_t val); + + bool operator!() const; + std::ptrdiff_t length() const; + bool has_valid_attribute() const; + return_t value() const; + void swap(match& other); + + template + match(match const& other) + : len(other.length()), val() + { + impl::match_attr_traits::copy(val, other); + } + + template + match& + operator=(match const& other) + { + impl::match_attr_traits::assign(val, other); + len = other.length(); + return *this; + } + + template + void + concat(MatchT const& other) + { + BOOST_SPIRIT_ASSERT(*this && other); + len += other.length(); + } + + template + void + value(ValueT const& val_) + { + impl::match_attr_traits::set_value(val, val_, is_reference()); + } + + bool operator_bool() const + { + return len >= 0; + } + + private: + + std::ptrdiff_t len; + optional_type val; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // match class specialization for nil_t values + // + /////////////////////////////////////////////////////////////////////////// + template <> + class match : public safe_bool > + { + public: + + typedef nil_t attr_t; + typedef nil_t return_t; + + match(); + explicit match(std::size_t length); + match(std::size_t length, nil_t); + + bool operator!() const; + bool has_valid_attribute() const; + std::ptrdiff_t length() const; + nil_t value() const; + void value(nil_t); + void swap(match& other); + + template + match(match const& other) + : len(other.length()) {} + + template + match<>& + operator=(match const& other) + { + len = other.length(); + return *this; + } + + template + void + concat(match const& other) + { + BOOST_SPIRIT_ASSERT(*this && other); + len += other.length(); + } + + bool operator_bool() const + { + return len >= 0; + } + + private: + + std::ptrdiff_t len; + }; + +}} // namespace boost::spirit + +#endif +#include + diff --git a/boost/boost/spirit/core/nil.hpp b/boost/boost/spirit/core/nil.hpp new file mode 100644 index 0000000000..2b61851a15 --- /dev/null +++ b/boost/boost/spirit/core/nil.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_NIL_HPP) +#define BOOST_SPIRIT_NIL_HPP + +namespace boost { namespace spirit +{ + struct nil_t {}; +}} + +#endif + + diff --git a/boost/boost/spirit/core/non_terminal/grammar.hpp b/boost/boost/spirit/core/non_terminal/grammar.hpp new file mode 100644 index 0000000000..a43382d04d --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/grammar.hpp @@ -0,0 +1,81 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + Copyright (c) 2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_GRAMMAR_HPP) +#define BOOST_SPIRIT_GRAMMAR_HPP + +/////////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_SPIRIT_THREADSAFE) && defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#undef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE +#endif + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +/////////////////////////////////////////////////////////////////////////////// +// +// grammar class +// +/////////////////////////////////////////////////////////////////////////////// +template > +struct grammar + : public parser + , public ContextT::base_t + , public context_aux + BOOST_SPIRIT_GRAMMAR_ID +{ + typedef grammar self_t; + typedef DerivedT const& embed_t; + typedef typename ContextT::context_linker_t context_t; + typedef typename context_t::attr_t attr_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + grammar() {} + ~grammar() { impl::grammar_destruct(this); } + + template + typename parser_result::type + parse_main(ScannerT const& scan) const + { return impl::grammar_parser_parse<0>(this, scan); } + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef parser_scanner_linker scanner_t; + BOOST_SPIRIT_CONTEXT_PARSE(scan, *this, scanner_t, context_t, result_t) + } + + template + impl::entry_grammar + use_parser() const + { return impl::entry_grammar( this->derived()); } + + BOOST_SPIRIT_GRAMMAR_STATE +}; + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#undef BOOST_SPIRIT_GRAMMAR_ID +#undef BOOST_SPIRIT_GRAMMAR_ACCESS +#undef BOOST_SPIRIT_GRAMMAR_STATE +#endif + diff --git a/boost/boost/spirit/core/non_terminal/impl/grammar.ipp b/boost/boost/spirit/core/non_terminal/impl/grammar.ipp new file mode 100644 index 0000000000..51faf88bce --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/impl/grammar.ipp @@ -0,0 +1,388 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + Copyright (c) 2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined BOOST_SPIRIT_GRAMMAR_IPP +#define BOOST_SPIRIT_GRAMMAR_IPP + +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#include +#include +#include +#include // for std::auto_ptr +#include +#endif + +#ifdef BOOST_SPIRIT_THREADSAFE +#include +#include +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +template +struct grammar; + +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1200) + +BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER(grammar_definition_wrapper, definition); + +////////////////////////////////// +template +struct grammar_definition +{ + typedef typename impl::grammar_definition_wrapper + ::template result_::param_t type; +}; + +#else + +////////////////////////////////// +template +struct grammar_definition +{ + typedef typename GrammarT::template definition type; +}; + +#endif + + namespace impl + { + +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) + struct grammar_tag {}; + + ////////////////////////////////// + template + struct grammar_helper_base + { + virtual int undefine(GrammarT *) = 0; + virtual ~grammar_helper_base() {} + }; + + ////////////////////////////////// + template + struct grammar_helper_list + { + typedef GrammarT grammar_t; + typedef grammar_helper_base helper_t; + typedef std::vector vector_t; + + grammar_helper_list() {} + grammar_helper_list(grammar_helper_list const& /*x*/) + { // Does _not_ copy the helpers member ! + } + + grammar_helper_list& operator=(grammar_helper_list const& x) + { // Does _not_ copy the helpers member ! + return *this; + } + + void push_back(helper_t *helper) + { helpers.push_back(helper); } + + void pop_back() + { helpers.pop_back(); } + + typename vector_t::size_type + size() const + { return helpers.size(); } + + typename vector_t::reverse_iterator + rbegin() + { return helpers.rbegin(); } + + typename vector_t::reverse_iterator + rend() + { return helpers.rend(); } + +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex & mutex() + { return m; } +#endif + + private: + + vector_t helpers; +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex m; +#endif + }; + + ////////////////////////////////// + struct grammartract_helper_list; + +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) \ + && (!defined(__GNUC__) || (__GNUC__ > 2)) + + struct grammartract_helper_list + { + template + static grammar_helper_list& + do_(GrammarT const* g) + { + return g->helpers; + } + }; + +#endif + + ////////////////////////////////// + template + struct grammar_helper : private grammar_helper_base + { + typedef GrammarT grammar_t; + typedef ScannerT scanner_t; + typedef DerivedT derived_t; + typedef typename grammar_definition::type definition_t; + + typedef grammar_helper helper_t; + typedef boost::shared_ptr helper_ptr_t; + typedef boost::weak_ptr helper_weak_ptr_t; + + grammar_helper* + this_() { return this; } + + grammar_helper(helper_weak_ptr_t& p) + : definitions_cnt(0) + , self(this_()) + { p = self; } + + definition_t& + define(grammar_t const* target_grammar) + { + grammar_helper_list &helpers = +#if !defined(__GNUC__) || (__GNUC__ > 2) + grammartract_helper_list::do_(target_grammar); +#else + target_grammar->helpers; +#endif + typename grammar_t::object_id id = target_grammar->get_object_id(); + + if (definitions.size()<=id) + definitions.resize(id*3/2+1); + if (definitions[id]!=0) + return *definitions[id]; + + std::auto_ptr + result(new definition_t(target_grammar->derived())); + +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex::scoped_lock lock(helpers.mutex()); +#endif + helpers.push_back(this); + + ++definitions_cnt; + definitions[id] = result.get(); + return *(result.release()); + } + + int + undefine(grammar_t* target_grammar) + { + typename grammar_t::object_id id = target_grammar->get_object_id(); + + if (definitions.size()<=id) + return 0; + delete definitions[id]; + definitions[id] = 0; + if (--definitions_cnt==0) + self.reset(); + return 0; + } + + private: + + std::vector definitions; + unsigned long definitions_cnt; + helper_ptr_t self; + }; + +#endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */ + + template + inline typename DerivedT::template definition & + get_definition(grammar const* self) + { +#if defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) + + typedef typename DerivedT::template definition definition_t; + static definition_t def(self->derived()); + return def; +#else + typedef grammar self_t; + typedef impl::grammar_helper helper_t; + typedef typename helper_t::helper_weak_ptr_t ptr_t; + +# ifdef BOOST_SPIRIT_THREADSAFE + static boost::thread_specific_ptr tld_helper; + if (!tld_helper.get()) + tld_helper.reset(new ptr_t); + ptr_t &helper = *tld_helper; +# else + static ptr_t helper; +# endif + if (!boost::make_shared(helper).get()) + new helper_t(helper); + return boost::make_shared(helper)->define(self); +#endif + } + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template + struct call_helper { + + template + static void + do_ (RT &result, DefinitionT &def, ScannerT const &scan) + { + result = def.template get_start_parser()->parse(scan); + } + }; +#else + // The grammar_def stuff isn't supported for compilers, which do not + // support partial template specialization + template struct call_helper; +#endif + + template <> + struct call_helper<0> { + + template + static void + do_ (RT &result, DefinitionT &def, ScannerT const &scan) + { + result = def.start().parse(scan); + } + }; + + ////////////////////////////////// + template + inline typename parser_result, ScannerT>::type + grammar_parser_parse( + grammar const* self, + ScannerT const &scan) + { + typedef + typename parser_result, ScannerT>::type + result_t; + typedef typename DerivedT::template definition definition_t; + + result_t result; + definition_t &def = get_definition(self); + + call_helper::do_(result, def, scan); + return result; + } + + ////////////////////////////////// + template + inline void + grammar_destruct(GrammarT* self) + { +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) + typedef impl::grammar_helper_base helper_base_t; + typedef grammar_helper_list helper_list_t; + typedef typename helper_list_t::vector_t::reverse_iterator iterator_t; + + helper_list_t& helpers = +# if !defined(__GNUC__) || (__GNUC__ > 2) + grammartract_helper_list::do_(self); +# else + self->helpers; +# endif + +# if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) \ + || defined(BOOST_INTEL_CXX_VERSION) + for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i) + (*i)->undefine(self); +# else + std::for_each(helpers.rbegin(), helpers.rend(), + std::bind2nd(std::mem_fun(&helper_base_t::undefine), self)); +# endif + +#else + (void)self; +#endif + } + + /////////////////////////////////////////////////////////////////////////// + // + // entry_grammar class + // + /////////////////////////////////////////////////////////////////////////// + template + class entry_grammar + : public parser > + { + + public: + typedef entry_grammar self_t; + typedef DerivedT const& embed_t; + typedef typename ContextT::context_linker_t context_t; + typedef typename context_t::attr_t attr_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + entry_grammar(DerivedT const &p) : target_grammar(p) {} + + template + typename parser_result::type + parse_main(ScannerT const& scan) const + { return impl::grammar_parser_parse(&target_grammar, scan); } + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef parser_scanner_linker scanner_t; + BOOST_SPIRIT_CONTEXT_PARSE(scan, *this, scanner_t, context_t, + result_t) + } + + private: + DerivedT const &target_grammar; + }; + + } // namespace impl + +/////////////////////////////////////// +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#define BOOST_SPIRIT_GRAMMAR_ID , public impl::object_with_id +#else +#define BOOST_SPIRIT_GRAMMAR_ID +#endif + +/////////////////////////////////////// +#if !defined(__GNUC__) || (__GNUC__ > 2) +#define BOOST_SPIRIT_GRAMMAR_ACCESS private: +#else +#define BOOST_SPIRIT_GRAMMAR_ACCESS +#endif + +/////////////////////////////////////// +#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) +#define BOOST_SPIRIT_GRAMMAR_STATE \ + BOOST_SPIRIT_GRAMMAR_ACCESS \ + friend struct impl::grammartract_helper_list; \ + mutable impl::grammar_helper_list helpers; +#else +#define BOOST_SPIRIT_GRAMMAR_STATE +#endif + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/non_terminal/impl/object_with_id.ipp b/boost/boost/spirit/core/non_terminal/impl/object_with_id.ipp new file mode 100644 index 0000000000..057c886c2f --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/impl/object_with_id.ipp @@ -0,0 +1,157 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Martin Wille + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined BOOST_SPIRIT_OBJECT_WITH_ID_IPP +#define BOOST_SPIRIT_OBJECT_WITH_ID_IPP + +#include +#include + +#ifdef BOOST_SPIRIT_THREADSAFE +#include +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + + namespace impl { + + ////////////////////////////////// + template + struct object_with_id_base_supply + { + typedef IdT object_id; + typedef std::vector id_vector; + + object_with_id_base_supply() : max_id(object_id()) {} + +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex mutex; +#endif + object_id max_id; + id_vector free_ids; + + object_id acquire(); + void release(object_id); + }; + + ////////////////////////////////// + template + struct object_with_id_base + { + typedef TagT tag_t; + typedef IdT object_id; + + protected: + + object_id acquire_object_id(); + void release_object_id(object_id); + + private: + + boost::shared_ptr > id_supply; + }; + + ////////////////////////////////// + template + struct object_with_id : private object_with_id_base + { + typedef object_with_id self_t; + typedef object_with_id_base base_t; + typedef IdT object_id; + + object_with_id() : id(base_t::acquire_object_id()) {} + object_with_id(self_t const &other) + : base_t(other) + , id(base_t::acquire_object_id()) + {} // don't copy id + self_t &operator = (self_t const &other) + { // don't assign id + base_t::operator=(other); + return *this; + } + ~object_with_id() { base_t::release_object_id(id); } + object_id get_object_id() const { return id; } + + private: + + object_id const id; + }; + + ////////////////////////////////// + template + inline IdT + object_with_id_base_supply::acquire() + { +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex::scoped_lock lock(mutex); +#endif + if (free_ids.size()) + { + object_id id = *free_ids.rbegin(); + free_ids.pop_back(); + return id; + } + else + { + if (free_ids.capacity()<=max_id) + free_ids.reserve(max_id*3/2+1); + return ++max_id; + } + } + + ////////////////////////////////// + template + inline void + object_with_id_base_supply::release(IdT id) + { +#ifdef BOOST_SPIRIT_THREADSAFE + boost::mutex::scoped_lock lock(mutex); +#endif + if (max_id == id) + max_id--; + else + free_ids.push_back(id); // doesn't throw + } + + ////////////////////////////////// + template + inline IdT + object_with_id_base::acquire_object_id() + { + { +#ifdef BOOST_SPIRIT_THREADSAFE + static boost::mutex mutex; + boost::mutex::scoped_lock lock(mutex); +#endif + static boost::shared_ptr > + static_supply; + + if (!static_supply.get()) + static_supply.reset(new object_with_id_base_supply()); + id_supply = static_supply; + } + + return id_supply->acquire(); + } + + ////////////////////////////////// + template + inline void + object_with_id_base::release_object_id(IdT id) + { + id_supply->release(id); + } + + } // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/non_terminal/impl/rule.ipp b/boost/boost/spirit/core/non_terminal/impl/rule.ipp new file mode 100644 index 0000000000..ee9ed2c154 --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/impl/rule.ipp @@ -0,0 +1,407 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_RULE_IPP) +#define BOOST_SPIRIT_RULE_IPP + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +#include +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + template < + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT + ) + > + struct scanner_list; + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template + struct get_param + { + typedef typename mpl::if_< + is_base_and_derived + , T0 + , typename mpl::if_< + is_base_and_derived + , T1 + , typename mpl::if_< + is_base_and_derived + , T2 + , DefaultT + >::type + >::type + >::type type; + }; + + template + struct get_context + { + typedef typename get_param< + parser_context_base, parser_context<>, T0, T1, T2>::type + type; + }; + + template + struct get_tag + { + typedef typename get_param< + parser_tag_base, parser_address_tag, T0, T1, T2>::type + type; + }; + + template + struct get_scanner + { + typedef typename get_param< + scanner_base, scanner<>, T0, T1, T2>::type + type; + }; + + /////////////////////////////////////////////////////////////////////// + // + // rule_base class + // + // The rule_base class implements the basic plumbing for rules + // minus the storage mechanism. It is up to the derived class + // to actually store the definition somewhere. The rule_base + // class assumes that the derived class provides a get() function + // that will return a pointer to a parser. The get() function + // may return NULL. See rule below for details. + // + // <<< For framework use only. Not for public consumption. >>> + // + /////////////////////////////////////////////////////////////////////// + template < + typename DerivedT // derived class + , typename EmbedT // how derived class is embedded + , typename T0 = nil_t // see rule class + , typename T1 = nil_t // see rule class + , typename T2 = nil_t // see rule class + > + class rule_base; // forward declaration + + class rule_base_access + { +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + public: // YUCK! +#else + template < + typename DerivedT + , typename EmbedT + , typename T0 + , typename T1 + , typename T2 + > + friend class rule_base; +#endif + template + static typename RuleT::abstract_parser_t* + get(RuleT const& r) + { + return r.get(); + } + }; + + template < + typename DerivedT // derived class + , typename EmbedT // how derived class is embedded + , typename T0 // see rule class + , typename T1 // see rule class + , typename T2 // see rule class + > + class rule_base + : public parser + , public impl::get_context::type::base_t + , public context_aux< + typename impl::get_context::type, DerivedT> + , public impl::get_tag::type + { + public: + + typedef typename impl::get_scanner::type scanner_t; + typedef typename impl::get_context::type context_t; + typedef typename impl::get_tag::type tag_t; + + typedef EmbedT embed_t; + typedef typename context_t::context_linker_t linked_context_t; + typedef typename linked_context_t::attr_t attr_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef parser_scanner_linker linked_scanner_t; + typedef typename parser_result::type result_t; + BOOST_SPIRIT_CONTEXT_PARSE( + scan, *this, linked_scanner_t, linked_context_t, result_t); + } + + template + typename parser_result::type + parse_main(ScannerT const& scan) const + { + typename parser_result::type hit; + + // MWCW 8.3 needs this cast to be done through a pointer, + // not a reference. Otherwise, it will silently construct + // a temporary, causing an infinite runtime recursion. + DerivedT const* derived_this = static_cast(this); + + if (rule_base_access::get(*derived_this)) + { + typename ScannerT::iterator_t s(scan.first); + hit = rule_base_access::get(*derived_this) + ->do_parse_virtual(scan); + scan.group_match(hit, this->id(), s, scan.first); + } + else + { + hit = scan.no_match(); + } + return hit; + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // abstract_parser class + // + /////////////////////////////////////////////////////////////////////// + template + struct abstract_parser + { + abstract_parser() {} + virtual ~abstract_parser() {} + + virtual typename match_result::type + do_parse_virtual(ScannerT const& scan) const = 0; + + virtual abstract_parser* + clone() const = 0; + }; + + /////////////////////////////////////////////////////////////////////// + // + // concrete_parser class + // + /////////////////////////////////////////////////////////////////////// + template + struct concrete_parser : abstract_parser + { + concrete_parser(ParserT const& p) : p(p) {} + virtual ~concrete_parser() {} + + virtual typename match_result::type + do_parse_virtual(ScannerT const& scan) const + { + return p.parse(scan); + } + + virtual abstract_parser* + clone() const + { + return new concrete_parser(p); + } + + typename ParserT::embed_t p; + }; + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////// + // + // This generates partial specializations for the class + // + // abstract_parser + // + // with an increasing number of different ScannerT template parameters + // and corresponding do_parse_virtual function declarations for each + // of the different required scanner types: + // + // template + // struct abstract_parser, AttrT> + // { + // abstract_parser() {} + // virtual ~abstract_parser() {} + // + // virtual typename match_result::type + // do_parse_virtual(ScannerT0 const &scan) const = 0; + // + // virtual abstract_parser* + // clone() const = 0; + // + // ... + // }; + // + /////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _) \ + virtual typename match_result< \ + BOOST_PP_CAT(ScannerT, N), AttrT \ + >::type \ + do_parse_virtual( \ + BOOST_PP_CAT(ScannerT, N) const& scan) const = 0; \ + + #define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _) \ + template < \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \ + typename AttrT \ + > \ + struct abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + { \ + abstract_parser() {} \ + virtual ~abstract_parser() {} \ + \ + BOOST_PP_REPEAT_ ## z( \ + BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _) \ + \ + virtual abstract_parser* \ + clone() const = 0; \ + }; \ + + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _) + + #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A + #undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS + /////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////// + // + // This generates partial specializations for the class + // + // concrete_parser + // + // with an increasing number of different ScannerT template parameters + // and corresponding do_parse_virtual function declarations for each + // of the different required scanner types: + // + // template < + // typename ParserT, typename ScannerT0, ..., typename AttrT + // > + // struct concrete_parser< + // ParserT, scanner_list, AttrT + // > + // : public abstract_parser, AttrT> + // { + // concrete_parser(ParserT const& p_) : p(p_) {} + // virtual ~concrete_parser() {} + // + // virtual typename match_result::type + // do_parse_virtual(ScannerT0 const &scan) const + // { return p.parse(scan); } + // + // virtual abstract_parser, AttrT>* + // clone() const + // { + // return new concrete_parser(p); + // } + // + // ... + // + // typename ParserT::embed_t p; + // }; + // + /////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _) \ + virtual typename match_result< \ + BOOST_PP_CAT(ScannerT, N), AttrT \ + >::type \ + do_parse_virtual( \ + BOOST_PP_CAT(ScannerT, N) const& scan) const \ + { return p.parse(scan); } \ + + #define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _) \ + template < \ + typename ParserT, \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \ + typename AttrT \ + > \ + struct concrete_parser< \ + ParserT, \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + : abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + { \ + concrete_parser(ParserT const& p_) : p(p_) {} \ + virtual ~concrete_parser() {} \ + \ + BOOST_PP_REPEAT_ ## z( \ + BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _) \ + \ + virtual abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + >* \ + clone() const \ + { \ + return new concrete_parser(p); \ + } \ + \ + typename ParserT::embed_t p; \ + }; \ + + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _) + + #undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS + #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C + /////////////////////////////////////////////////////////////////////// + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + } // namespace impl + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/non_terminal/impl/subrule.ipp b/boost/boost/spirit/core/non_terminal/impl/subrule.ipp new file mode 100644 index 0000000000..a194d4fbae --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/impl/subrule.ipp @@ -0,0 +1,205 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SUBRULE_IPP) +#define BOOST_SPIRIT_SUBRULE_IPP + +namespace boost { namespace spirit { + + template + struct subrule_list; + + template + struct subrule_parser; + + namespace impl { + + #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template + struct get_subrule; + + template + struct get_subrule_chooser + { + static ListT t(); + static char test(nil_t); + static int test(...); + + // Set value to + // 0: ListT is empty + // 1: ListT's first item has same ID + // 2: ListT's first item has a different ID + + enum + { + id = ListT::first_t::id, + is_same_id = N == id, + is_nil_t = sizeof(char) == sizeof(test(t())), + value = is_nil_t ? 0 : (is_same_id ? 1 : 2) + }; + }; + + template + struct subrule_chooser; + + template <> + struct subrule_chooser<0> + { + // First case. ListT is empty + + template + struct result + { typedef nil_t type; }; + }; + + template <> + struct subrule_chooser<1> + { + // Second case. ListT is non-empty and the list's + // first item has the ID we are looking for. + + template + struct result + { typedef typename ListT::first_t::def_t type; }; + }; + + template <> + struct subrule_chooser<2> + { + // Third case. ListT is non-empty but the list's + // first item does not have the ID we are looking for. + + template + struct result + { typedef typename get_subrule::type type; }; + }; + + template + struct get_subrule + { + enum { n = get_subrule_chooser::value }; + typedef typename subrule_chooser::template + result::type type; + }; + + #else + + template + struct get_subrule + { + // First case. ListT is non-empty but the list's + // first item does not have the ID we are looking for. + + typedef typename get_subrule::type type; + }; + + template + struct get_subrule< + ID, + subrule_list< + subrule_parser, + RestT> > + { + // Second case. ListT is non-empty and the list's + // first item has the ID we are looking for. + + typedef DefT type; + }; + + template + struct get_subrule + { + // Third case. ListT is empty + typedef nil_t type; + }; + + #endif + + template + struct get_result_t { + + // If the result type dictated by the context is nil_t (no closures + // present), then the whole subrule_parser return type is equal to + // the return type of the right hand side of this subrule_parser, + // otherwise it is equal to the dictated return value. + + typedef typename mpl::if_< + boost::is_same, T2, T1 + >::type type; + }; + + template + struct get_subrule_result + { + typedef typename + impl::get_subrule::type + parser_t; + + typedef typename parser_result::type + def_result_t; + + typedef typename match_result::type + context_result_t; + + typedef typename get_result_t::type + type; + }; + + template + struct get_subrule_parser_result + { + typedef typename parser_result::type + def_result_t; + + typedef typename match_result::type + context_result_t; + + typedef typename get_result_t::type + type; + }; + + template + struct same_subrule_id + { + BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID)); + }; + + template + struct parse_subrule + { + template + static void + do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_) + { + r = list.first.rhs.parse(scan); + } + + template + static void + do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_) + { + typedef typename ListT::rest_t::first_t subrule_t; + mpl::bool_::value> same_id; + do_parse(r, scan, list.rest, same_id); + } + + static void + do_(RT& r, ScannerT const& scan) + { + typedef typename ScannerT::list_t::first_t subrule_t; + mpl::bool_::value> same_id; + do_parse(r, scan, scan.list, same_id); + } + }; + +}}} // namespace boost::spirit::impl + +#endif + diff --git a/boost/boost/spirit/core/non_terminal/parser_context.hpp b/boost/boost/spirit/core/non_terminal/parser_context.hpp new file mode 100644 index 0000000000..4c9662fc77 --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/parser_context.hpp @@ -0,0 +1,147 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_HPP) +#define BOOST_SPIRIT_PARSER_CONTEXT_HPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost +{ + namespace spirit + { + + /////////////////////////////////////////////////////////////////////////// + // + // default_parser_context_base class { default context base } + // + /////////////////////////////////////////////////////////////////////////// + struct default_parser_context_base + { + template + struct aux {}; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context_base class { base class of all context classes } + // + /////////////////////////////////////////////////////////////////////////// + struct parser_context_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context class { default context } + // + /////////////////////////////////////////////////////////////////////////// + struct nil_t; + template struct parser_context_linker; + + template + struct parser_context : parser_context_base + { + typedef AttrT attr_t; + typedef default_parser_context_base base_t; + typedef parser_context_linker > context_linker_t; + + template + parser_context(ParserT const&) {} + + template + void + pre_parse(ParserT const&, ScannerT const&) {} + + template + ResultT& + post_parse(ResultT& hit, ParserT const&, ScannerT const&) + { return hit; } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // context_aux class + // + // context_aux is a class derived from the + // ContextT's nested base_t::base template class. (see + // default_parser_context_base::aux for an example). + // + // Basically, this class provides ContextT dependent optional + // functionality to the derived class DerivedT through the CRTP + // idiom (Curiously recurring template pattern). + // + /////////////////////////////////////////////////////////////////////////// + template + struct context_aux : public ContextT::base_t::template aux {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_scanner_linker and parser_scanner_linker classes + // { helper templates for the rule extensibility } + // + // This classes can be 'overloaded' (defined elsewhere), to plug + // in additional functionality into the non-terminal parsing process. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED + + template + struct parser_scanner_linker : public ScannerT + { + parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {} + }; + + #endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + + ////////////////////////////////// + #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED + + template + struct parser_context_linker : public ContextT + { + template + parser_context_linker(ParserT const& p) + : ContextT(p) {} + + template + void pre_parse(ParserT const& p, ScannerT const& scan) + { ContextT::pre_parse(p, scan); } + + template + ResultT& + post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan) + { return ContextT::post_parse(hit, p, scan); } + }; + + #endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + + /////////////////////////////////////////////////////////////////////////// + // + // BOOST_SPIRIT_CONTEXT_PARSE helper macro + // + // The original implementation uses a template class. However, we + // need to lessen the template instantiation depth to help inferior + // compilers that sometimes choke on deep template instantiations. + // The objective is to avoid code redundancy. A macro, in this case + // is an obvious solution. Sigh! + // + // WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION. + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \ + scanner_t scan_wrap(scan); \ + context_t context_wrap(this_); \ + context_wrap.pre_parse(this_, scan_wrap); \ + result_t hit = parse_main(scan); \ + return context_wrap.post_parse(hit, this_, scan_wrap); + + } // namespace spirit +} // namespace boost + +#endif diff --git a/boost/boost/spirit/core/non_terminal/parser_id.hpp b/boost/boost/spirit/core/non_terminal/parser_id.hpp new file mode 100644 index 0000000000..3899865d28 --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/parser_id.hpp @@ -0,0 +1,114 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_ID_HPP) +#define BOOST_SPIRIT_PARSER_ID_HPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // parser_id class + // + /////////////////////////////////////////////////////////////////////////// + class parser_id + { + public: + parser_id() : p(0) {} + explicit parser_id(void const* prule) : p(prule) {} + parser_id(std::size_t l_) : l(l_) {} + + bool operator==(parser_id const& x) const { return p == x.p; } + bool operator!=(parser_id const& x) const { return !(*this == x); } + bool operator<(parser_id const& x) const { return p < x.p; } + std::size_t to_long() const { return l; } + + private: + + union + { + void const* p; + std::size_t l; + }; + }; + + #if defined(BOOST_SPIRIT_DEBUG) + inline std::ostream& + operator<<(std::ostream& out, parser_id const& rid) + { + out << rid.to_long(); + return out; + } + #endif + + /////////////////////////////////////////////////////////////////////////// + // + // parser_tag_base class: base class of all parser tags + // + /////////////////////////////////////////////////////////////////////////// + struct parser_tag_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_address_tag class: tags a parser with its address + // + /////////////////////////////////////////////////////////////////////////// + struct parser_address_tag : parser_tag_base + { + parser_id id() const + { return parser_id(reinterpret_cast(this)); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_tag class: tags a parser with an integer ID + // + /////////////////////////////////////////////////////////////////////////// + template + struct parser_tag : parser_tag_base + { + static parser_id id() + { return parser_id(std::size_t(N)); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // dynamic_parser_tag class: tags a parser with a dynamically changeable + // integer ID + // + /////////////////////////////////////////////////////////////////////////// + class dynamic_parser_tag : public parser_tag_base + { + public: + + dynamic_parser_tag() + : tag(std::size_t(0)) {} + + parser_id + id() const + { + return + tag.to_long() + ? tag + : parser_id(reinterpret_cast(this)); + } + + void set_id(parser_id id) { tag = id; } + + private: + + parser_id tag; + }; + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/non_terminal/rule.hpp b/boost/boost/spirit/core/non_terminal/rule.hpp new file mode 100644 index 0000000000..001e5cd3bf --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/rule.hpp @@ -0,0 +1,168 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_RULE_HPP) +#define BOOST_SPIRIT_RULE_HPP + +#include + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum number of simultaneously usable different +// scanner types. +// +// This limit defines the maximum number of of possible different scanner +// types for which a specific rule<> may be used. If this isn't defined, a +// rule<> may be used with one scanner type only (multiple scanner support +// is disabled). +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT) +# define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 1 +#endif + +// Ensure a meaningful maximum number of simultaneously usable scanner types +BOOST_STATIC_ASSERT(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 0); + +#include +#include + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +# include +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_list (a fake scanner) + // + // Typically, rules are tied to a specific scanner type and + // a particular rule cannot be used with anything else. Sometimes + // there's a need for rules that can accept more than one scanner + // type. The scanner_list can be used as a template + // parameter to the rule class to specify up to the number of + // scanner types defined by the BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT + // constant. Example: + // + // rule > r; + // + // *** This feature is available only to compilers that support + // partial template specialization. *** + // + /////////////////////////////////////////////////////////////////////////// + template < + BOOST_PP_ENUM_PARAMS( + BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + typename ScannerT + ) + > + struct scanner_list : scanner_base {}; + +#endif + + /////////////////////////////////////////////////////////////////////////// + // + // rule class + // + // The rule is a polymorphic parser that acts as a named place- + // holder capturing the behavior of an EBNF expression assigned to + // it. + // + // The rule is a template class parameterized by: + // + // 1) scanner (scanner_t, see scanner.hpp), + // 2) the rule's context (context_t, see parser_context.hpp) + // 3) an arbitrary tag (tag_t, see parser_id.hpp) that allows + // a rule to be tagged for identification. + // + // These template parameters may be specified in any order. The + // scanner will default to scanner<> when it is not specified. + // The context will default to parser_context when not specified. + // The tag will default to parser_address_tag when not specified. + // + // The definition of the rule (its right hand side, RHS) held by + // the rule through a scoped_ptr. When a rule is seen in the RHS + // of an assignment or copy construction EBNF expression, the rule + // is held by the LHS rule by reference. + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T0 = nil_t + , typename T1 = nil_t + , typename T2 = nil_t + > + class rule + : public impl::rule_base< + rule + , rule const& + , T0, T1, T2> + { + public: + + typedef rule self_t; + typedef impl::rule_base< + self_t + , self_t const& + , T0, T1, T2> + base_t; + + typedef typename base_t::scanner_t scanner_t; + typedef typename base_t::attr_t attr_t; + typedef impl::abstract_parser abstract_parser_t; + + rule() : ptr() {} + ~rule() {} + + rule(rule const& r) + : ptr(new impl::concrete_parser(r)) {} + + template + rule(ParserT const& p) + : ptr(new impl::concrete_parser(p)) {} + + template + rule& operator=(ParserT const& p) + { + ptr.reset(new impl::concrete_parser(p)); + return *this; + } + + rule& operator=(rule const& r) + { + ptr.reset(new impl::concrete_parser(r)); + return *this; + } + + rule + copy() const + { + return rule(ptr.get() ? ptr->clone() : 0); + } + + private: + friend class impl::rule_base_access; + + abstract_parser_t* + get() const + { + return ptr.get(); + } + + rule(abstract_parser_t const* ptr) + : ptr(ptr) {} + + scoped_ptr ptr; + }; + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/non_terminal/subrule.hpp b/boost/boost/spirit/core/non_terminal/subrule.hpp new file mode 100644 index 0000000000..bde2f103db --- /dev/null +++ b/boost/boost/spirit/core/non_terminal/subrule.hpp @@ -0,0 +1,297 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SUBRULE_HPP) +#define BOOST_SPIRIT_SUBRULE_HPP + +#include +#include + +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // subrules_scanner class + // + /////////////////////////////////////////////////////////////////////////// + template + struct subrules_scanner : public ScannerT + { + typedef ScannerT scanner_t; + typedef ListT list_t; + typedef subrules_scanner self_t; + + subrules_scanner(ScannerT const& scan, ListT const& list_) + : ScannerT(scan), list(list_) {} + + template + struct rebind_policies + { + typedef typename rebind_scanner_policies::type + rebind_scanner; + typedef subrules_scanner type; + }; + + template + subrules_scanner< + typename rebind_scanner_policies::type, + ListT> + change_policies(PoliciesT const& policies) const + { + typedef subrules_scanner< + BOOST_DEDUCED_TYPENAME + rebind_scanner_policies::type, + ListT> + subrules_scanner_t; + + return subrules_scanner_t( + ScannerT::change_policies(policies), + list); + } + + template + struct rebind_iterator + { + typedef typename rebind_scanner_iterator::type + rebind_scanner; + typedef subrules_scanner type; + }; + + template + subrules_scanner< + typename rebind_scanner_iterator::type, + ListT> + change_iterator(IteratorT const& first, IteratorT const &last) const + { + typedef subrules_scanner< + BOOST_DEDUCED_TYPENAME + rebind_scanner_iterator::type, + ListT> + subrules_scanner_t; + + return subrules_scanner_t( + ScannerT::change_iterator(first, last), + list); + } + + ListT const& list; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule_scanner type computer class + // + // This computer ensures that the scanner will not be recursively + // instantiated if it's not needed. + // + /////////////////////////////////////////////////////////////////////////// + template + struct subrules_scanner_finder + { + typedef subrules_scanner type; + }; + + template + struct subrules_scanner_finder, ListT> + { + typedef subrules_scanner type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule_list class + // + /////////////////////////////////////////////////////////////////////////// + template + struct subrule_list : public parser > + { + typedef subrule_list self_t; + typedef FirstT first_t; + typedef RestT rest_t; + + subrule_list(FirstT const& first_, RestT const& rest_) + : first(first_), rest(rest_) {} + + template + struct result + { + typedef typename parser_result::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename subrules_scanner_finder::type + subrules_scanner_t; + subrules_scanner_t g_arg(scan, *this); + return first.start.parse(g_arg); + } + + template + subrule_list< + FirstT, + subrule_list< + subrule_parser, + RestT> > + operator,(subrule_parser const& rhs) + { + return subrule_list< + FirstT, + subrule_list< + subrule_parser, + RestT> >( + first, + subrule_list< + subrule_parser, + RestT>(rhs, rest)); + } + + FirstT first; + RestT rest; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule_parser class + // + /////////////////////////////////////////////////////////////////////////// + template > + struct subrule; // Forward declaration + + template + struct subrule_parser + : public parser > + { + typedef subrule_parser self_t; + typedef subrule subrule_t; + typedef DefT def_t; + + BOOST_STATIC_CONSTANT(int, id = ID); + + template + struct result + { + typedef typename + impl::get_subrule_parser_result< + DefT, ScannerT, typename subrule_t::attr_t>::type type; + }; + + subrule_parser(subrule_t const& start_, DefT const& rhs_) + : rhs(rhs_), start(start_) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + // This will only be called when parsing single subrules. + typedef subrule_list list_t; + typedef subrules_scanner scanner_t; + + list_t list(*this, nil_t()); + scanner_t g_arg(scan, list); + return start.parse(g_arg); + } + + template + inline subrule_list< + self_t, + subrule_list< + subrule_parser, + nil_t> > + operator,(subrule_parser const& rhs) const + { + return subrule_list< + self_t, + subrule_list< + subrule_parser, + nil_t> >( + *this, + subrule_list< + subrule_parser, nil_t>( + rhs, nil_t())); + } + + typename DefT::embed_t rhs; + subrule_t const& start; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // subrule class + // + /////////////////////////////////////////////////////////////////////////// + template + struct subrule + : public parser > + , public ContextT::base_t + , public context_aux > + { + typedef subrule self_t; + typedef subrule const& embed_t; + + typedef typename ContextT::context_linker_t context_t; + typedef typename context_t::attr_t attr_t; + + BOOST_STATIC_CONSTANT(int, id = ID); + + template + struct result + { + typedef typename + impl::get_subrule_result::type type; + }; + + template + typename parser_result::type + parse_main(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + result_t result; + impl::parse_subrule:: + do_(result, scan); + return result; + } + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef parser_scanner_linker scanner_t; + BOOST_SPIRIT_CONTEXT_PARSE( + scan, *this, scanner_t, context_t, result_t); + } + + template + subrule_parser + operator=(parser const& rhs) const + { + return subrule_parser(*this, rhs.derived()); + } + + private: + + // assignment of subrules is not allowed. Use subrules + // with identical IDs if you want to have aliases. + + subrule& operator=(subrule const&); + + template + subrule& operator=(subrule const&); + }; + +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/parser.hpp b/boost/boost/spirit/core/parser.hpp new file mode 100644 index 0000000000..6b0a616b39 --- /dev/null +++ b/boost/boost/spirit/core/parser.hpp @@ -0,0 +1,219 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PARSER_HPP) +#define BOOST_SPIRIT_PARSER_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit +{ + template + class action; // forward declaration + + /////////////////////////////////////////////////////////////////////////// + // + // Parser categories + // + // Helper template classes to distinguish different types of + // parsers. The following categories are the most generic. More + // specific types may inherit from these. Each parser has a typedef + // parser_category_t that defines its category. By default, if one + // is not specified, it will inherit from the base parser class + // which typedefs its parser_category_t as plain_parser_category. + // + // - plain parser has nothing special + // - binary parser has subject a and b (e.g. alternative) + // - unary parser has single subject (e.g. kleene star) + // - action parser has an attached action parser + // + /////////////////////////////////////////////////////////////////////////// + struct plain_parser_category {}; + struct binary_parser_category : plain_parser_category {}; + struct unary_parser_category : plain_parser_category {}; + struct action_parser_category : unary_parser_category {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_result metafunction + // + // Given a scanner type ScannerT and a parser type ParserT, the + // parser_result metafunction provides the actual result of the + // parser. + // + // Usage: + // + // typename parser_result::type + // + /////////////////////////////////////////////////////////////////////////// + template + struct parser_result + { + typedef typename boost::remove_reference::type parser_type; + typedef typename parser_type::template result::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser class + // + // This class is a protocol base class for all parsers. This is + // essentially an interface contract. The parser class does not + // really know how to parse anything but instead relies on the + // template parameter DerivedT (which obviously is assumed to be a + // subclass) to do the actual parsing. + // + // Concrete sub-classes inheriting from parser must have a + // corresponding member function parse(...) compatible with the + // conceptual Interface: + // + // template + // RT parse(ScannerT const& scan) const; + // + // where RT is the desired return type of the parser and ScannerT + // scan is the scanner (see scanner.hpp). + // + // Concrete sub-classes inheriting from parser in most cases need to + // have a nested meta-function result that returns the result type + // of the parser's parse member function, given a scanner type. The + // meta-function has the form: + // + // template + // struct result + // { + // typedef RT type; + // }; + // + // where RT is the desired return type of the parser. This is + // usually, but not always, dependent on the template parameter + // ScannerT. If a parser does not supply a result metafunction, a + // default is provided by the base parser class. + // + // The parser's derived() member function returns a reference to the + // parser as its derived object. + // + // An operator[] is provided. The operator returns a semantic action + // handler (see actions.hpp). + // + // Each parser has a typedef embed_t. This typedef specifies how a + // parser is embedded in a composite (see composite.hpp). By + // default, if one is not specified, the parser will be embedded by + // value. That is, a copy of the parser is placed as a member + // variable of the composite. Most parsers are embedded by value. In + // certain situations however, this is not desirable or possible. + // + /////////////////////////////////////////////////////////////////////////// + template + struct parser + { + typedef DerivedT embed_t; + typedef DerivedT derived_t; + typedef plain_parser_category parser_category_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + DerivedT& derived() + { + return *static_cast(this); + } + + DerivedT const& derived() const + { + return *static_cast(this); + } + + template + action + operator[](ActionT const& actor) const + { + return action(derived(), actor); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parse_info + // + // Results returned by the free parse functions: + // + // stop: points to the final parse position (i.e parsing + // processed the input up to this point). + // + // hit: true if parsing is successful. This may be full: + // the parser consumed all the input, or partial: + // the parser consumed only a portion of the input. + // + // full: true when we have a full hit (i.e the parser + // consumed all the input. + // + // length: The number of characters consumed by the parser. + // This is valid only if we have a successful hit + // (either partial or full). + // + /////////////////////////////////////////////////////////////////////////// + template + struct parse_info + { + IteratorT stop; + bool hit; + bool full; + std::size_t length; + + parse_info( + IteratorT const& stop_ = IteratorT(), + bool hit_ = false, + bool full_ = false, + std::size_t length_ = 0) + : stop(stop_) + , hit(hit_) + , full(full_) + , length(length_) {} + + template + parse_info(ParseInfoT const& pi) + : stop(pi.stop) + , hit(pi.hit) + , full(pi.full) + , length(pi.length) {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Generic parse function + // + /////////////////////////////////////////////////////////////////////////// + template + parse_info + parse( + IteratorT const& first, + IteratorT const& last, + parser const& p); + + /////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings + // + /////////////////////////////////////////////////////////////////////////// + template + parse_info + parse( + CharT const* str, + parser const& p); + +}} // namespace boost::spirit + +#endif + +#include diff --git a/boost/boost/spirit/core/primitives/impl/numerics.ipp b/boost/boost/spirit/core/primitives/impl/numerics.ipp new file mode 100644 index 0000000000..a4800ef23d --- /dev/null +++ b/boost/boost/spirit/core/primitives/impl/numerics.ipp @@ -0,0 +1,532 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_NUMERICS_IPP +#define BOOST_SPIRIT_NUMERICS_IPP + +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_SPIRIT_IMPL_STD_NS +#else +# define BOOST_SPIRIT_IMPL_STD_NS std +#endif + +namespace boost { namespace spirit { + + struct sign_parser; // forward declaration only + + namespace impl + { + /////////////////////////////////////////////////////////////////////// + // + // Extract the prefix sign (- or +) + // + /////////////////////////////////////////////////////////////////////// + template + bool + extract_sign(ScannerT const& scan, std::size_t& count) + { + // Extract the sign + count = 0; + bool neg = *scan == '-'; + if (neg || (*scan == '+')) + { + ++scan; + ++count; + return neg; + } + + return false; + } + + /////////////////////////////////////////////////////////////////////// + // + // Traits class for radix specific number conversion + // + // Test the validity of a single character: + // + // template static bool is_valid(CharT ch); + // + // Convert a digit from character representation to binary + // representation: + // + // template static int digit(CharT ch); + // + /////////////////////////////////////////////////////////////////////// + template + struct radix_traits; + + ////////////////////////////////// Binary + template<> + struct radix_traits<2> + { + template + static bool is_valid(CharT ch) + { + return ('0' == ch || '1' == ch); + } + + template + static int digit(CharT ch) + { + return ch - '0'; + } + }; + + ////////////////////////////////// Octal + template<> + struct radix_traits<8> + { + template + static bool is_valid(CharT ch) + { + return ('0' <= ch && ch <= '7'); + } + + template + static int digit(CharT ch) + { + return ch - '0'; + } + }; + + ////////////////////////////////// Decimal + template<> + struct radix_traits<10> + { + template + static bool is_valid(CharT ch) + { + return impl::isdigit_(ch); + } + + template + static int digit(CharT ch) + { + return ch - '0'; + } + }; + + ////////////////////////////////// Hexadecimal + template<> + struct radix_traits<16> + { + template + static bool is_valid(CharT ch) + { + return impl::isxdigit_(ch); + } + + template + static int digit(CharT ch) + { + if (impl::isdigit_(ch)) + return ch - '0'; + return impl::tolower_(ch) - 'a' + 10; + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // Helper templates for encapsulation of radix specific + // conversion of an input string to an integral value. + // + // main entry point: + // + // extract_int + // ::f(first, last, n, count); + // + // The template parameter Radix represents the radix of the + // number contained in the parsed string. The template + // parameter MinDigits specifies the minimum digits to + // accept. The template parameter MaxDigits specifies the + // maximum digits to parse. A -1 value for MaxDigits will + // make it parse an arbitrarilly large number as long as the + // numeric type can hold it. Accumulate is either + // positive_accumulate (default) for parsing positive + // numbers or negative_accumulate otherwise. + // + // scan.first and scan.last are iterators as usual (i.e. + // first is mutable and is moved forward when a match is + // found), n is a variable that holds the number (passed by + // reference). The number of parsed characters is added to + // count (also passed by reference) + // + // NOTE: + // Returns a non-match, if the number to parse + // overflows (or underflows) the used integral type. + // Overflow (or underflow) is detected when an + // operation wraps a value from its maximum to its + // minimum (or vice-versa). For example, overflow + // occurs when the result of the expression n * x is + // less than n (assuming n is positive and x is + // greater than 1). + // + // BEWARE: + // the parameters 'n' and 'count' should be properly + // initialized before calling this function. + // + /////////////////////////////////////////////////////////////////////// + template + struct positive_accumulate + { + // Use this accumulator if number is positive + + template + static bool check(T const& n, T const& prev) + { + return n < prev; + } + + template + static void add(T& n, CharT ch) + { + n += radix_traits::digit(ch); + } + }; + + template + struct negative_accumulate + { + // Use this accumulator if number is negative + + template + static bool check(T const& n, T const& prev) + { + return n > prev; + } + + template + static void add(T& n, CharT ch) + { + n -= radix_traits::digit(ch); + } + }; + + template + struct extract_int_base + { + // Common code for extract_int specializations + template + static bool + f(ScannerT& scan, T& n) + { + T prev = n; + n *= Radix; + if (Accumulate::check(n, prev)) + return false; // over/underflow! + prev = n; + Accumulate::add(n, *scan); + if (Accumulate::check(n, prev)) + return false; // over/underflow! + return true; + } + }; + + template + struct extract_int_ + { + template < + int Radix, + unsigned MinDigits, + int MaxDigits, + typename Accumulate + > + struct apply + { + typedef extract_int_base base; + typedef radix_traits check; + + template + static bool + f(ScannerT& scan, T& n, std::size_t& count) + { + std::size_t i = 0; + for (; (i < MaxDigits) && !scan.at_end() + && check::is_valid(*scan); + ++i, ++scan, ++count) + { + if (!base::f(scan, n)) + return false; // over/underflow! + } + return i >= MinDigits; + } + }; + }; + + template <> + struct extract_int_ + { + template < + int Radix, + unsigned MinDigits, + int MaxDigits, + typename Accumulate + > + struct apply + { + typedef extract_int_base base; + typedef radix_traits check; + + template + static bool + f(ScannerT& scan, T& n, std::size_t& count) + { + std::size_t i = 0; + for (; !scan.at_end() && check::is_valid(*scan); + ++i, ++scan, ++count) + { + if (!base::f(scan, n)) + return false; // over/underflow! + } + return i >= MinDigits; + } + }; + }; + + ////////////////////////////////// + template < + int Radix, unsigned MinDigits, int MaxDigits, + typename Accumulate = positive_accumulate + > + struct extract_int + { + template + static bool + f(ScannerT& scan, T& n, std::size_t& count) + { + typedef typename extract_int_<(MaxDigits >= 0)>::template + apply extractor; + return extractor::f(scan, n, count); + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // uint_parser_impl class + // + /////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct uint_parser_impl + : parser > + { + typedef uint_parser_impl self_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + if (!scan.at_end()) + { + T n = 0; + std::size_t count = 0; + typename ScannerT::iterator_t save = scan.first; + if (extract_int:: + f(scan, n, count)) + { + return scan.create_match(count, n, save, scan.first); + } + // return no-match if number overflows + } + return scan.no_match(); + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // int_parser_impl class + // + /////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct int_parser_impl + : parser > + { + typedef int_parser_impl self_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef extract_int > extract_int_neg_t; + typedef extract_int + extract_int_pos_t; + + if (!scan.at_end()) + { + T n = 0; + std::size_t count = 0; + typename ScannerT::iterator_t save = scan.first; + + bool hit = impl::extract_sign(scan, count); + + if (hit) + hit = extract_int_neg_t::f(scan, n, count); + else + hit = extract_int_pos_t::f(scan, n, count); + + if (hit) + return scan.create_match(count, n, save, scan.first); + else + scan.first = save; + // return no-match if number overflows or underflows + } + return scan.no_match(); + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // real_parser_impl class + // + /////////////////////////////////////////////////////////////////////// +#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) +#pragma warning(push) +#pragma warning(disable:4127) +#endif + + template + struct real_parser_impl + { + typedef real_parser_impl self_t; + + template + RT parse_main(ScannerT const& scan) const + { + if (scan.at_end()) + return scan.no_match(); + typename ScannerT::iterator_t save = scan.first; + + typedef typename parser_result::type + sign_match_t; + typedef typename parser_result, ScannerT>::type + exp_match_t; + + sign_match_t sign_match = RealPoliciesT::parse_sign(scan); + std::size_t count = sign_match ? sign_match.length() : 0; + bool neg = sign_match.has_valid_attribute() ? + sign_match.value() : false; + + RT n_match = RealPoliciesT::parse_n(scan); + T n = n_match.has_valid_attribute() ? + n_match.value() : T(0); + bool got_a_number = n_match; + exp_match_t e_hit; + + if (!got_a_number && !RealPoliciesT::allow_leading_dot) + return scan.no_match(); + else + count += n_match.length(); + + if (neg) + n = -n; + + if (RealPoliciesT::parse_dot(scan)) + { + // We got the decimal point. Now we will try to parse + // the fraction if it is there. If not, it defaults + // to zero (0) only if we already got a number. + + if (RT hit = RealPoliciesT::parse_frac_n(scan)) + { + hit.value(hit.value() + * BOOST_SPIRIT_IMPL_STD_NS:: + pow(T(10), T(-hit.length()))); + if (neg) + n -= hit.value(); + else + n += hit.value(); + count += hit.length() + 1; + + } + + else if (!got_a_number || + !RealPoliciesT::allow_trailing_dot) + return scan.no_match(); + + e_hit = RealPoliciesT::parse_exp(scan); + } + else + { + // We have reached a point where we + // still haven't seen a number at all. + // We return early with a no-match. + if (!got_a_number) + return scan.no_match(); + + // If we must expect a dot and we didn't see + // an exponent, return early with a no-match. + e_hit = RealPoliciesT::parse_exp(scan); + if (RealPoliciesT::expect_dot && !e_hit) + return scan.no_match(); + } + + if (e_hit) + { + // We got the exponent prefix. Now we will try to parse the + // actual exponent. It is an error if it is not there. + if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan)) + { + n *= BOOST_SPIRIT_IMPL_STD_NS:: + pow(T(10), T(e_n_hit.value())); + count += e_n_hit.length() + e_hit.length(); + } + else + { + // Oops, no exponent, return a no-match + return scan.no_match(); + } + } + + return scan.create_match(count, n, save, scan.first); + } + + template + static RT parse(ScannerT const& scan) + { + static self_t this_; + return impl::implicit_lexeme_parse(this_, scan, scan); + } + }; + +#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) +#pragma warning(pop) +#pragma warning(disable:4127) +#endif + + } // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#endif +#undef BOOST_SPIRIT_IMPL_STD_NS diff --git a/boost/boost/spirit/core/primitives/impl/primitives.ipp b/boost/boost/spirit/core/primitives/impl/primitives.ipp new file mode 100644 index 0000000000..27ad87a054 --- /dev/null +++ b/boost/boost/spirit/core/primitives/impl/primitives.ipp @@ -0,0 +1,376 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Martin Wille + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PRIMITIVES_IPP) +#define BOOST_SPIRIT_PRIMITIVES_IPP + +// This should eventually go to a config file. +#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(_STLPORT_VERSION) +# ifndef BOOST_SPIRIT_NO_CHAR_TRAITS +# define BOOST_SPIRIT_NO_CHAR_TRAITS +# endif +#endif + +#include +#if !defined(BOOST_NO_CWCTYPE) +#include +#endif + +#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS +# include // char_traits +#endif + +#if defined(BOOST_MSVC) +# pragma warning(disable:4800) +#endif + +namespace boost { namespace spirit { + + template struct char_parser; + + namespace impl + { + template + inline IteratorT + get_last(IteratorT first) + { + while (*first) + first++; + return first; + } + + template< + typename RT, + typename IteratorT, + typename ScannerT> + inline RT + string_parser_parse( + IteratorT str_first, + IteratorT str_last, + ScannerT& scan) + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t saved = scan.first; + std::size_t slen = str_last - str_first; + + while (str_first != str_last) + { + if (scan.at_end() || (*str_first != *scan)) + return scan.no_match(); + ++str_first; + ++scan; + } + + return scan.create_match(slen, nil_t(), saved, scan.first); + } + + /////////////////////////////////////////////////////////////////////////// + // + // Conversion from char_type to int_type + // + /////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS +# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE std +#else + + template + struct char_traits + { + typedef CharT int_type; + typedef CharT char_type; + }; + + template<> + struct char_traits + { + typedef int int_type; + typedef char char_type; + + static char_type + to_char_type(int_type c) + { + return static_cast(c); + } + + static int + to_int_type(char c) + { + return static_cast(c); + } + }; + + template<> + struct char_traits + { + typedef int int_type; + typedef unsigned char char_type; + + static char_type + to_char_type(int_type c) + { + return static_cast(c); + } + + static int + to_int_type(unsigned char c) + { + return c; + } + }; + +# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE impl +# ifndef BOOST_NO_CWCHAR + + template<> + struct char_traits + { + typedef wint_t int_type; + typedef wchar_t char_type; + + static char_type + to_char_type(int_type c) + { + return static_cast(c); + } + + static wint_t + to_int_type(wchar_t c) + { + return c; + } + }; + +# endif +#endif // BOOST_SPIRIT_NO_CHAR_TRAITS + + template + inline typename + BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE::char_traits::int_type + to_int_type(CharT c) + { + return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE + ::char_traits::to_int_type(c); + } + + template + inline CharT + to_char_type(typename + BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE::char_traits::int_type c) + { + return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE + ::char_traits::to_char_type(c); + } + + /////////////////////////////////////////////////////////////////////// + // + // Convenience functions + // + /////////////////////////////////////////////////////////////////////// + + inline bool + isalnum_(char c) + { + using namespace std; + return isalnum(to_int_type(c)); + } + + inline bool + isalpha_(char c) + { + using namespace std; + return isalpha(to_int_type(c)); + } + + inline bool + iscntrl_(char c) + { + using namespace std; + return iscntrl(to_int_type(c)); + } + + inline bool + isdigit_(char c) + { + using namespace std; + return isdigit(to_int_type(c)); + } + + inline bool + isgraph_(char c) + { + using namespace std; + return isgraph(to_int_type(c)); + } + + inline bool + islower_(char c) + { + using namespace std; + return islower(to_int_type(c)); + } + + inline bool + isprint_(char c) + { + using namespace std; + return isprint(to_int_type(c)); + } + + inline bool + ispunct_(char c) + { + using namespace std; + return ispunct(to_int_type(c)); + } + + inline bool + isspace_(char c) + { + using namespace std; + return isspace(to_int_type(c)); + } + + inline bool + isupper_(char c) + { + using namespace std; + return isupper(to_int_type(c)); } + + inline bool + isxdigit_(char c) + { + using namespace std; + return isxdigit(to_int_type(c)); + } + + inline bool + isblank_(char c) + { + return (c == ' ' || c == '\t'); + } + + inline char + tolower_(char c) + { + using namespace std; + return to_char_type(tolower(to_int_type(c))); + } + + inline char + toupper_(char c) + { + using namespace std; + return to_char_type(toupper(to_int_type(c))); + } + +#if !defined(BOOST_NO_CWCTYPE) + + inline bool + isalnum_(wchar_t c) + { + using namespace std; + return iswalnum(to_int_type(c)); + } + + inline bool + isalpha_(wchar_t c) + { + using namespace std; + return iswalpha(to_int_type(c)); + } + + inline bool + iscntrl_(wchar_t c) + { + using namespace std; + return iswcntrl(to_int_type(c)); + } + + inline bool + isdigit_(wchar_t c) + { + using namespace std; + return iswdigit(to_int_type(c)); + } + + inline bool + isgraph_(wchar_t c) + { + using namespace std; + return iswgraph(to_int_type(c)); + } + + inline bool + islower_(wchar_t c) + { + using namespace std; + return iswlower(to_int_type(c)); + } + + inline bool + isprint_(wchar_t c) + { + using namespace std; + return iswprint(to_int_type(c)); + } + + inline bool + ispunct_(wchar_t c) + { + using namespace std; + return iswpunct(to_int_type(c)); + } + + inline bool + isspace_(wchar_t c) + { + using namespace std; + return iswspace(to_int_type(c)); + } + + inline bool + isupper_(wchar_t c) + { + using namespace std; + return iswupper(to_int_type(c)); + } + + inline bool + isxdigit_(wchar_t c) + { + using namespace std; + return iswxdigit(to_int_type(c)); + } + + inline bool + isblank_(wchar_t c) + { + return (c == L' ' || c == L'\t'); + } + + inline wchar_t + tolower_(wchar_t c) + { + using namespace std; + return to_char_type(towlower(to_int_type(c))); + } + + inline wchar_t + toupper_(wchar_t c) + { + using namespace std; + return to_char_type(towupper(to_int_type(c))); + } + +#endif // !defined(BOOST_NO_CWCTYPE) + +}}} // namespace boost::spirit::impl + +#endif diff --git a/boost/boost/spirit/core/primitives/numerics.hpp b/boost/boost/spirit/core/primitives/numerics.hpp new file mode 100644 index 0000000000..f737549300 --- /dev/null +++ b/boost/boost/spirit/core/primitives/numerics.hpp @@ -0,0 +1,283 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2001-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef BOOST_SPIRIT_NUMERICS_HPP +#define BOOST_SPIRIT_NUMERICS_HPP + +#include +#include +#include +#include + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // + // uint_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct uint_parser : parser > + { + typedef uint_parser self_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef impl::uint_parser_impl impl_t; + typedef typename parser_result::type result_t; + return impl::contiguous_parser_parse(impl_t(), scan, scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // int_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T = unsigned, + int Radix = 10, + unsigned MinDigits = 1, + int MaxDigits = -1 + > + struct int_parser : parser > + { + typedef int_parser self_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef impl::int_parser_impl impl_t; + typedef typename parser_result::type result_t; + return impl::contiguous_parser_parse(impl_t(), scan, scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // uint_parser/int_parser instantiations + // + /////////////////////////////////////////////////////////////////////////// + int_parser const + int_p = int_parser(); + + uint_parser const + uint_p = uint_parser(); + + uint_parser const + bin_p = uint_parser(); + + uint_parser const + oct_p = uint_parser(); + + uint_parser const + hex_p = uint_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // sign_parser class + // + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + // Utility to extract the prefix sign ('-' | '+') + template + bool extract_sign(ScannerT const& scan, std::size_t& count); + } + + struct sign_parser : public parser + { + typedef sign_parser self_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + sign_parser() {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + if (!scan.at_end()) + { + std::size_t length; + typename ScannerT::iterator_t save(scan.first); + bool neg = impl::extract_sign(scan, length); + if (length) + return scan.create_match(1, neg, save, scan.first); + } + return scan.no_match(); + } + }; + + sign_parser const sign_p = sign_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // default real number policies + // + /////////////////////////////////////////////////////////////////////////// + template + struct ureal_parser_policies + { + // trailing dot policy suggested suggested by Gustavo Guerra + BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true); + BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true); + BOOST_STATIC_CONSTANT(bool, expect_dot = false); + + typedef uint_parser uint_parser_t; + typedef int_parser int_parser_t; + + template + static typename match_result::type + parse_sign(ScannerT& scan) + { + return scan.no_match(); + } + + template + static typename parser_result::type + parse_n(ScannerT& scan) + { + return uint_parser_t().parse(scan); + } + + template + static typename parser_result, ScannerT>::type + parse_dot(ScannerT& scan) + { + return ch_p('.').parse(scan); + } + + template + static typename parser_result::type + parse_frac_n(ScannerT& scan) + { + return uint_parser_t().parse(scan); + } + + template + static typename parser_result, ScannerT>::type + parse_exp(ScannerT& scan) + { + return as_lower_d['e'].parse(scan); + } + + template + static typename parser_result::type + parse_exp_n(ScannerT& scan) + { + return int_parser_t().parse(scan); + } + }; + + template + struct real_parser_policies : public ureal_parser_policies + { + template + static typename parser_result::type + parse_sign(ScannerT& scan) + { + return sign_p.parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // real_parser class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T = double, + typename RealPoliciesT = ureal_parser_policies + > + struct real_parser + : public parser > + { + typedef real_parser self_t; + + template + struct result + { + typedef typename match_result::type type; + }; + + real_parser() {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + return impl::real_parser_impl::parse(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // real_parser instantiations + // + /////////////////////////////////////////////////////////////////////////// + real_parser > const + ureal_p = real_parser >(); + + real_parser > const + real_p = real_parser >(); + + /////////////////////////////////////////////////////////////////////////// + // + // strict reals (do not allow plain integers (no decimal point)) + // + /////////////////////////////////////////////////////////////////////////// + template + struct strict_ureal_parser_policies : public ureal_parser_policies + { + BOOST_STATIC_CONSTANT(bool, expect_dot = true); + }; + + template + struct strict_real_parser_policies : public real_parser_policies + { + BOOST_STATIC_CONSTANT(bool, expect_dot = true); + }; + + real_parser > const + strict_ureal_p + = real_parser >(); + + real_parser > const + strict_real_p + = real_parser >(); + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/primitives/primitives.hpp b/boost/boost/spirit/core/primitives/primitives.hpp new file mode 100644 index 0000000000..af8036b443 --- /dev/null +++ b/boost/boost/spirit/core/primitives/primitives.hpp @@ -0,0 +1,614 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + Copyright (c) 2003 Martin Wille + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_PRIMITIVES_HPP) +#define BOOST_SPIRIT_PRIMITIVES_HPP + +#include +#include +#include +#include +#include + +namespace boost { namespace spirit { + + /////////////////////////////////////////////////////////////////////////// + // + // char_parser class + // + /////////////////////////////////////////////////////////////////////////// + template + struct char_parser : public parser + { + typedef DerivedT self_t; + template + struct result + { + typedef typename match_result< + ScannerT, + typename ScannerT::value_t + >::type type; + }; + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + typedef typename ScannerT::value_t value_t; + typedef typename ScannerT::iterator_t iterator_t; + + if (!scan.at_end()) + { + value_t ch = *scan; + if (this->derived().test(ch)) + { + iterator_t save(scan.first); + ++scan.first; + return scan.create_match(1, ch, save, scan.first); + } + } + return scan.no_match(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // negation of char_parsers + // + /////////////////////////////////////////////////////////////////////////// + template + struct negated_char_parser + : public char_parser > + { + typedef negated_char_parser self_t; + typedef PositiveT positive_t; + + negated_char_parser(positive_t const& p) + : positive(p.derived()) {} + + template + bool test(T ch) const + { + return !positive.test(ch); + } + + positive_t const positive; + }; + + template + inline negated_char_parser + operator~(char_parser const& p) + { + return negated_char_parser(p.derived()); + } + + template + inline ParserT + operator~(negated_char_parser const& n) + { + return n.positive; + } + + /////////////////////////////////////////////////////////////////////////// + // + // chlit class + // + /////////////////////////////////////////////////////////////////////////// + template + struct chlit : public char_parser > + { + chlit(CharT ch_) + : ch(ch_) {} + + template + bool test(T ch_) const + { + return ch_ == ch; + } + + CharT ch; + }; + + template + inline chlit + ch_p(CharT ch) + { + return chlit(ch); + } + + /////////////////////////////////////////////////////////////////////////// + // + // range class + // + /////////////////////////////////////////////////////////////////////////// + template + struct range : public char_parser > + { + range(CharT first_, CharT last_) + : first(first_), last(last_) + { + BOOST_SPIRIT_ASSERT(!(last < first)); + } + + template + bool test(T ch) const + { + return !(CharT(ch) < first) && !(last < CharT(ch)); + } + + CharT first; + CharT last; + }; + + template + inline range + range_p(CharT first, CharT last) + { + return range(first, last); + } + + /////////////////////////////////////////////////////////////////////////// + // + // chseq class + // + /////////////////////////////////////////////////////////////////////////// + template + class chseq : public parser > + { + public: + + typedef chseq self_t; + + chseq(IteratorT first_, IteratorT last_) + : first(first_), last(last_) {} + + chseq(IteratorT first_) + : first(first_), last(impl::get_last(first_)) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename boost::unwrap_reference::type striter_t; + typedef typename parser_result::type result_t; + return impl::string_parser_parse( + striter_t(first), + striter_t(last), + scan); + } + + private: + + IteratorT first; + IteratorT last; + }; + + template + inline chseq + chseq_p(CharT const* str) + { + return chseq(str); + } + + template + inline chseq + chseq_p(IteratorT first, IteratorT last) + { + return chseq(first, last); + } + + /////////////////////////////////////////////////////////////////////////// + // + // strlit class + // + /////////////////////////////////////////////////////////////////////////// + template + class strlit : public parser > + { + public: + + typedef strlit self_t; + + strlit(IteratorT first, IteratorT last) + : seq(first, last) {} + + strlit(IteratorT first) + : seq(first) {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typedef typename parser_result::type result_t; + return impl::contiguous_parser_parse + (seq, scan, scan); + } + + private: + + chseq seq; + }; + + template + inline strlit + str_p(CharT const* str) + { + return strlit(str); + } + + template + inline strlit + str_p(IteratorT first, IteratorT last) + { + return strlit(first, last); + } + + /////////////////////////////////////////////////////////////////////////// + // + // nothing_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct nothing_parser : public parser + { + typedef nothing_parser self_t; + + nothing_parser() {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + return scan.no_match(); + } + }; + + nothing_parser const nothing_p = nothing_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // anychar_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct anychar_parser : public char_parser + { + typedef anychar_parser self_t; + + anychar_parser() {} + + template + bool test(CharT) const + { + return true; + } + }; + + anychar_parser const anychar_p = anychar_parser(); + + inline nothing_parser + operator~(anychar_parser) + { + return nothing_p; + } + + /////////////////////////////////////////////////////////////////////////// + // + // alnum_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct alnum_parser : public char_parser + { + typedef alnum_parser self_t; + + alnum_parser() {} + + template + bool test(CharT ch) const + { + return impl::isalnum_(ch); + } + }; + + alnum_parser const alnum_p = alnum_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // alpha_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct alpha_parser : public char_parser + { + typedef alpha_parser self_t; + + alpha_parser() {} + + template + bool test(CharT ch) const + { + return impl::isalpha_(ch); + } + }; + + alpha_parser const alpha_p = alpha_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // cntrl_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct cntrl_parser : public char_parser + { + typedef cntrl_parser self_t; + + cntrl_parser() {} + + template + bool test(CharT ch) const + { + return impl::iscntrl_(ch); + } + }; + + cntrl_parser const cntrl_p = cntrl_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // digit_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct digit_parser : public char_parser + { + typedef digit_parser self_t; + + digit_parser() {} + + template + bool test(CharT ch) const + { + return impl::isdigit_(ch); + } + }; + + digit_parser const digit_p = digit_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // graph_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct graph_parser : public char_parser + { + typedef graph_parser self_t; + + graph_parser() {} + + template + bool test(CharT ch) const + { + return impl::isgraph_(ch); + } + }; + + graph_parser const graph_p = graph_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // lower_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct lower_parser : public char_parser + { + typedef lower_parser self_t; + + lower_parser() {} + + template + bool test(CharT ch) const + { + return impl::islower_(ch); + } + }; + + lower_parser const lower_p = lower_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // print_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct print_parser : public char_parser + { + typedef print_parser self_t; + + print_parser() {} + + template + bool test(CharT ch) const + { + return impl::isprint_(ch); + } + }; + + print_parser const print_p = print_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // punct_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct punct_parser : public char_parser + { + typedef punct_parser self_t; + + punct_parser() {} + + template + bool test(CharT ch) const + { + return impl::ispunct_(ch); + } + }; + + punct_parser const punct_p = punct_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // blank_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct blank_parser : public char_parser + { + typedef blank_parser self_t; + + blank_parser() {} + + template + bool test(CharT ch) const + { + return impl::isblank_(ch); + } + }; + + blank_parser const blank_p = blank_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // space_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct space_parser : public char_parser + { + typedef space_parser self_t; + + space_parser() {} + + template + bool test(CharT ch) const + { + return impl::isspace_(ch); + } + }; + + space_parser const space_p = space_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // upper_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct upper_parser : public char_parser + { + typedef upper_parser self_t; + + upper_parser() {} + + template + bool test(CharT ch) const + { + return impl::isupper_(ch); + } + }; + + upper_parser const upper_p = upper_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // xdigit_parser class + // + /////////////////////////////////////////////////////////////////////////// + struct xdigit_parser : public char_parser + { + typedef xdigit_parser self_t; + + xdigit_parser() {} + + template + bool test(CharT ch) const + { + return impl::isxdigit_(ch); + } + }; + + xdigit_parser const xdigit_p = xdigit_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // eol_parser class (contributed by Martin Wille) + // + /////////////////////////////////////////////////////////////////////////// + struct eol_parser : public parser + { + typedef eol_parser self_t; + + eol_parser() {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + typename ScannerT::iterator_t save = scan.first; + std::size_t len = 0; + + if (!scan.at_end() && *scan == '\r') // CR + { + ++scan.first; + ++len; + } + + if (!scan.at_end() && *scan == '\n') // LF + { + ++scan.first; + ++len; + } + + if (len) + return scan.create_match(len, nil_t(), save, scan.first); + return scan.no_match(); + } + }; + + eol_parser const eol_p = eol_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // end_parser class (suggested by Markus Schöpflin) + // + /////////////////////////////////////////////////////////////////////////// + struct end_parser : public parser + { + typedef end_parser self_t; + + end_parser() {} + + template + typename parser_result::type + parse(ScannerT const& scan) const + { + if (scan.at_end()) + return scan.empty_match(); + return scan.no_match(); + } + }; + + end_parser const end_p = end_parser(); + + /////////////////////////////////////////////////////////////////////////// + // + // the pizza_p parser :-) + // + /////////////////////////////////////////////////////////////////////////// + inline strlit const + pizza_p(char const* your_favorite_pizza) + { + return your_favorite_pizza; + } + +}} // namespace boost::spirit + +#endif diff --git a/boost/boost/spirit/core/safe_bool.hpp b/boost/boost/spirit/core/safe_bool.hpp new file mode 100644 index 0000000000..5a2631aac0 --- /dev/null +++ b/boost/boost/spirit/core/safe_bool.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SAFE_BOOL_HPP) +#define BOOST_SPIRIT_SAFE_BOOL_HPP + +#include +#include + +namespace boost { namespace spirit +{ + namespace impl + { + template + struct no_base {}; + + template + struct safe_bool_impl + { +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + void stub(T*) {}; + typedef void (safe_bool_impl::*type)(T*); +#else + typedef T* TP; // workaround to make parsing easier + TP stub; + typedef TP safe_bool_impl::*type; +#endif + }; + } + + template > + struct safe_bool : BaseT + { + private: + typedef impl::safe_bool_impl impl_t; + typedef typename impl_t::type bool_type; + + public: + operator bool_type() const + { + return static_cast(this)->operator_bool() ? + &impl_t::stub : 0; + } + + operator bool_type() + { + return static_cast(this)->operator_bool() ? + &impl_t::stub : 0; + } + }; +}} + +#endif + diff --git a/boost/boost/spirit/core/scanner/impl/skipper.ipp b/boost/boost/spirit/core/scanner/impl/skipper.ipp new file mode 100644 index 0000000000..267dadb533 --- /dev/null +++ b/boost/boost/spirit/core/scanner/impl/skipper.ipp @@ -0,0 +1,179 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +============================================================================*/ +#if !defined(BOOST_SPIRIT_SKIPPER_IPP) +#define BOOST_SPIRIT_SKIPPER_IPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + + struct space_parser; + template + struct no_skipper_iteration_policy; + + namespace impl + { + template + inline void + skipper_skip( + ST const& s, + ScannerT const& scan, + skipper_iteration_policy const&) + { + typedef scanner_policies< + no_skipper_iteration_policy< + BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, + BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, + BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t + > policies_t; + + scanner + scan2(scan.first, scan.last, policies_t(scan)); + typedef typename ScannerT::iterator_t iterator_t; + + for (;;) + { + iterator_t save = scan.first; + if (!s.parse(scan2)) + { + scan.first = save; + break; + } + } + } + + template + inline void + skipper_skip( + ST const& s, + ScannerT const& scan, + no_skipper_iteration_policy const&) + { + for (;;) + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (!s.parse(scan)) + { + scan.first = save; + break; + } + } + } + + template + inline void + skipper_skip( + ST const& s, + ScannerT const& scan, + iteration_policy const&) + { + for (;;) + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + if (!s.parse(scan)) + { + scan.first = save; + break; + } + } + } + + template + struct phrase_parser + { + template + static parse_info + parse( + IteratorT const& first_, + IteratorT const& last, + ParserT const& p, + SkipT const& skip) + { + typedef skip_parser_iteration_policy iter_policy_t; + typedef scanner_policies scanner_policies_t; + typedef scanner scanner_t; + + iter_policy_t iter_policy(skip); + scanner_policies_t policies(iter_policy); + IteratorT first = first_; + scanner_t scan(first, last, policies); + match hit = p.parse(scan); + scan.skip(scan); + return parse_info( + first, hit, hit && (first == last), + hit.length()); + } + }; + + template <> + struct phrase_parser + { + template + static parse_info + parse( + IteratorT const& first_, + IteratorT const& last, + ParserT const& p, + space_parser const&) + { + typedef skipper_iteration_policy<> iter_policy_t; + typedef scanner_policies scanner_policies_t; + typedef scanner scanner_t; + + IteratorT first = first_; + scanner_t scan(first, last); + match hit = p.parse(scan); + scan.skip(scan); + return parse_info( + first, hit, hit && (first == last), + hit.length()); + } + }; + } + + /////////////////////////////////////////////////////////////////////////// + // + // Free parse functions using the skippers + // + /////////////////////////////////////////////////////////////////////////// + template + inline parse_info + parse( + IteratorT const& first, + IteratorT const& last, + parser const& p, + parser const& skip) + { + return impl::phrase_parser:: + parse(first, last, p.derived(), skip.derived()); + } + + /////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings using the skippers + // + /////////////////////////////////////////////////////////////////////////// + template + inline parse_info + parse( + CharT const* str, + parser const& p, + parser const& skip) + { + CharT const* last = str; + while (*last) + last++; + return parse(str, last, p, skip); + } + +}} // namespace boost::spirit + +#endif + diff --git a/boost/boost/spirit/core/scanner/scanner.hpp b/boost/boost/spirit/core/scanner/scanner.hpp new file mode 100644 index 0000000000..525949cdaf --- /dev/null +++ b/boost/boost/spirit/core/scanner/scanner.hpp @@ -0,0 +1,318 @@ +/*============================================================================= + Copyright (c) 1998-2002 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SCANNER_HPP) +#define BOOST_SPIRIT_SCANNER_HPP + +#include +#include +#include +#include +#include // for boost::detail::iterator_traits + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // + // iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + struct iteration_policy + { + template + void + advance(ScannerT const& scan) const + { + ++scan.first; + } + + template + bool at_end(ScannerT const& scan) const + { + return scan.first == scan.last; + } + + template + T filter(T ch) const + { + return ch; + } + + template + typename ScannerT::ref_t + get(ScannerT const& scan) const + { + return *scan.first; + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // match_policy class + // + /////////////////////////////////////////////////////////////////////////// + struct match_policy + { + template + struct result { typedef match type; }; + + const match + no_match() const + { + return match(); + } + + const match + empty_match() const + { + return match(0, nil_t()); + } + + template + match + create_match( + std::size_t length, + AttrT const& val, + IteratorT const& /*first*/, + IteratorT const& /*last*/) const + { + return match(length, val); + } + + template + void group_match( + MatchT& /*m*/, + parser_id const& /*id*/, + IteratorT const& /*first*/, + IteratorT const& /*last*/) const {} + + template + void concat_match(Match1T& l, Match2T const& r) const + { + l.concat(r); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // match_result class + // + /////////////////////////////////////////////////////////////////////////// + template + struct match_result + { + typedef typename MatchPolicyT::template result::type type; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // action_policy class + // + /////////////////////////////////////////////////////////////////////////// + template + struct attributed_action_policy + { + template + static void + call( + ActorT const& actor, + AttrT& val, + IteratorT const&, + IteratorT const&) + { + actor(val); + } + }; + + ////////////////////////////////// + template <> + struct attributed_action_policy + { + template + static void + call( + ActorT const& actor, + nil_t, + IteratorT const& first, + IteratorT const& last) + { + actor(first, last); + } + }; + + ////////////////////////////////// + struct action_policy + { + template + void + do_action( + ActorT const& actor, + AttrT& val, + IteratorT const& first, + IteratorT const& last) const + { + attributed_action_policy::call(actor, val, first, last); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_policies class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename IterationPolicyT = iteration_policy, + typename MatchPolicyT = match_policy, + typename ActionPolicyT = action_policy> + struct scanner_policies : + public IterationPolicyT, + public MatchPolicyT, + public ActionPolicyT + { + typedef IterationPolicyT iteration_policy_t; + typedef MatchPolicyT match_policy_t; + typedef ActionPolicyT action_policy_t; + + scanner_policies( + IterationPolicyT const& i_policy = IterationPolicyT(), + MatchPolicyT const& m_policy = MatchPolicyT(), + ActionPolicyT const& a_policy = ActionPolicyT()) + : IterationPolicyT(i_policy) + , MatchPolicyT(m_policy) + , ActionPolicyT(a_policy) {} + + template + scanner_policies(ScannerPoliciesT const& policies) + : IterationPolicyT(policies) + , MatchPolicyT(policies) + , ActionPolicyT(policies) {} + }; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_policies_base class: the base class of all scanners + // + /////////////////////////////////////////////////////////////////////////// + struct scanner_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // scanner class + // + /////////////////////////////////////////////////////////////////////////// + template < + typename IteratorT = char const*, + typename PoliciesT = scanner_policies<> > + class scanner : public PoliciesT, public scanner_base + { + public: + + typedef IteratorT iterator_t; + typedef PoliciesT policies_t; + + typedef typename boost::detail:: + iterator_traits::value_type value_t; + typedef typename boost::detail:: + iterator_traits::reference ref_t; + typedef typename boost:: + call_traits::param_type iter_param_t; + + scanner( + IteratorT& first_, + iter_param_t last_, + PoliciesT const& policies = PoliciesT()) + : PoliciesT(policies), first(first_), last(last_) + { + at_end(); + } + + scanner(scanner const& other) + : PoliciesT(other), first(other.first), last(other.last) {} + + scanner(scanner const& other, IteratorT& first_) + : PoliciesT(other), first(first_), last(other.last) {} + + bool + at_end() const + { + typedef typename PoliciesT::iteration_policy_t iteration_policy_t; + return iteration_policy_t::at_end(*this); + } + + value_t + operator*() const + { + typedef typename PoliciesT::iteration_policy_t iteration_policy_t; + return iteration_policy_t::filter(iteration_policy_t::get(*this)); + } + + scanner const& + operator++() const + { + typedef typename PoliciesT::iteration_policy_t iteration_policy_t; + iteration_policy_t::advance(*this); + return *this; + } + + template + struct rebind_policies + { + typedef scanner type; + }; + + template + scanner + change_policies(PoliciesT2 const& policies) const + { + return scanner(first, last, policies); + } + + template + struct rebind_iterator + { + typedef scanner type; + }; + + template + scanner + change_iterator(IteratorT2 const& first_, IteratorT2 const &last_) const + { + return scanner(first_, last_, *this); + } + + IteratorT& first; + IteratorT const last; + + private: + + scanner& + operator=(scanner const& other); + }; + + /////////////////////////////////////////////////////////////////////////// + // + // rebind_scanner_policies class + // + /////////////////////////////////////////////////////////////////////////// + template + struct rebind_scanner_policies + { + typedef typename ScannerT::template + rebind_policies::type type; + }; + + ////////////////////////////////// + template + struct rebind_scanner_iterator + { + typedef typename ScannerT::template + rebind_iterator::type type; + }; +}} + +#endif diff --git a/boost/boost/spirit/core/scanner/skipper.hpp b/boost/boost/spirit/core/scanner/skipper.hpp new file mode 100644 index 0000000000..33547bdc20 --- /dev/null +++ b/boost/boost/spirit/core/scanner/skipper.hpp @@ -0,0 +1,171 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_SKIPPER_HPP) +#define BOOST_SPIRIT_SKIPPER_HPP + +/////////////////////////////////////////////////////////////////////////////// +#include + +#include +#include + +namespace boost { namespace spirit { + + template + struct no_skipper_iteration_policy; // forward + + /////////////////////////////////////////////////////////////////////////// + // + // skipper_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + template + struct skipper_iteration_policy : public BaseT + { + typedef BaseT base_t; + + skipper_iteration_policy() + : BaseT() {} + + template + skipper_iteration_policy(PolicyT const& other) + : BaseT(other) {} + + template + void + advance(ScannerT const& scan) const + { + BaseT::advance(scan); + scan.skip(scan); + } + + template + bool + at_end(ScannerT const& scan) const + { + scan.skip(scan); + return BaseT::at_end(scan); + } + + template + void + skip(ScannerT const& scan) const + { + while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan))) + BaseT::advance(scan); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // skipper_iteration_policy class + // + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template + void + skipper_skip( + ST const& s, + ScannerT const& scan, + skipper_iteration_policy const&); + + template + void + skipper_skip( + ST const& s, + ScannerT const& scan, + no_skipper_iteration_policy const&); + + template + void + skipper_skip( + ST const& s, + ScannerT const& scan, + iteration_policy const&); + } + + template + class skip_parser_iteration_policy : public skipper_iteration_policy + { + public: + + typedef skipper_iteration_policy base_t; + + skip_parser_iteration_policy( + ParserT const& skip_parser, + base_t const& base = base_t()) + : base_t(base), subject(skip_parser) {} + + template + skip_parser_iteration_policy(PolicyT const& other) + : base_t(other), subject(other.skipper()) {} + + template + void + skip(ScannerT const& scan) const + { + impl::skipper_skip(subject, scan, scan); + } + + ParserT const& + skipper() const + { + return subject; + } + + private: + + ParserT const& subject; + }; + + /////////////////////////////////////////////////////////////////////////////// + // + // Free parse functions using the skippers + // + /////////////////////////////////////////////////////////////////////////////// + template + parse_info + parse( + IteratorT const& first, + IteratorT const& last, + parser const& p, + parser const& skip); + + /////////////////////////////////////////////////////////////////////////////// + // + // Parse function for null terminated strings using the skippers + // + /////////////////////////////////////////////////////////////////////////////// + template + parse_info + parse( + CharT const* str, + parser const& p, + parser const& skip); + + /////////////////////////////////////////////////////////////////////////////// + // + // phrase_scanner_t and wide_phrase_scanner_t + // + // The most common scanners. Use these typedefs when you need + // a scanner that skips white spaces. + // + /////////////////////////////////////////////////////////////////////////////// + typedef skipper_iteration_policy<> iter_policy_t; + typedef scanner_policies scanner_policies_t; + typedef scanner phrase_scanner_t; + typedef scanner wide_phrase_scanner_t; + + /////////////////////////////////////////////////////////////////////////////// +}} // namespace boost::spirit + +#include +#endif +