diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/metaparse/example | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/metaparse/example')
96 files changed, 4423 insertions, 0 deletions
diff --git a/src/boost/libs/metaparse/example/Jamfile.v2 b/src/boost/libs/metaparse/example/Jamfile.v2 new file mode 100644 index 000000000..3b82aec21 --- /dev/null +++ b/src/boost/libs/metaparse/example/Jamfile.v2 @@ -0,0 +1,14 @@ +build-project binary_number ; +build-project calculator ; +build-project calculator_with_parens ; +build-project calculator_with_parens_and_unary_ops ; +build-project compile_to_native_code ; +build-project constexpr_parser ; +build-project grammar_calculator ; +build-project meta_hs ; +build-project meta_lambda ; +build-project meta_metaparse ; +build-project minimal_rational ; +build-project parsing_error ; +build-project rational ; +build-project regexp ; diff --git a/src/boost/libs/metaparse/example/binary_number/Jamfile.v2 b/src/boost/libs/metaparse/example/binary_number/Jamfile.v2 new file mode 100644 index 000000000..9d1bdfdc0 --- /dev/null +++ b/src/boost/libs/metaparse/example/binary_number/Jamfile.v2 @@ -0,0 +1 @@ +exe binary_number : main.cpp ; diff --git a/src/boost/libs/metaparse/example/binary_number/README b/src/boost/libs/metaparse/example/binary_number/README new file mode 100644 index 000000000..580532f48 --- /dev/null +++ b/src/boost/libs/metaparse/example/binary_number/README @@ -0,0 +1 @@ +Parser for binary numbers diff --git a/src/boost/libs/metaparse/example/binary_number/main.cpp b/src/boost/libs/metaparse/example/binary_number/main.cpp new file mode 100644 index 000000000..636245834 --- /dev/null +++ b/src/boost/libs/metaparse/example/binary_number/main.cpp @@ -0,0 +1,85 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2011. +// Distributed under 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) + +#include <boost/metaparse/foldl1.hpp> +#include <boost/metaparse/build_parser.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/one_of_c.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> + +#include <boost/metaparse/util/digit_to_int.hpp> + +#include <boost/mpl/int.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/times.hpp> + +#include <iostream> + +using boost::metaparse::foldl1; +using boost::metaparse::build_parser; +using boost::metaparse::transform; +using boost::metaparse::one_of_c; +using boost::metaparse::entire_input; + +using boost::metaparse::util::digit_to_int; + +using boost::mpl::int_; +using boost::mpl::plus; +using boost::mpl::times; + +/* + * The grammar + * + * expression ::= ('1' | '0')* + */ + +struct next_element +{ + template <class Acc, class B> + struct apply : plus<times<Acc, int_<2> >, B> {}; +}; + +typedef + foldl1<transform<one_of_c<'0', '1'>, digit_to_int<> >, int_<0>, next_element> + S; + +typedef build_parser<entire_input<S> > binary_parser; + +template <class S> +struct binary : binary_parser::apply<S>::type {}; + +#ifdef _STR +# error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +#if BOOST_METAPARSE_STD < 2011 + +int main() +{ + using std::cout; + using std::endl; + using boost::metaparse::string; + + cout + << binary<string<'1','0','0'> >::value << endl + << binary<string<'1','0','1','1'> >::value << endl + << binary<string<'1'> >::value << endl; +} +#else +int main() +{ + using std::cout; + using std::endl; + + cout + << binary<_STR("100")>::value << endl + << binary<_STR("1011")>::value << endl + << binary<_STR("1")>::value << endl; +} +#endif + + diff --git a/src/boost/libs/metaparse/example/calculator/Jamfile.v2 b/src/boost/libs/metaparse/example/calculator/Jamfile.v2 new file mode 100644 index 000000000..887cff6a8 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator/Jamfile.v2 @@ -0,0 +1,6 @@ +project : requirements + <toolset>gcc:<cxxflags>-ftemplate-depth=512 + <toolset>clang:<cxxflags>-ftemplate-depth=512 +; + +exe calculator : main.cpp ; diff --git a/src/boost/libs/metaparse/example/calculator/README b/src/boost/libs/metaparse/example/calculator/README new file mode 100644 index 000000000..8229ef4b0 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator/README @@ -0,0 +1 @@ +Calculator, working at compile-time diff --git a/src/boost/libs/metaparse/example/calculator/main.cpp b/src/boost/libs/metaparse/example/calculator/main.cpp new file mode 100644 index 000000000..fc0dbffa1 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator/main.cpp @@ -0,0 +1,157 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2011. +// Distributed under 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) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/first_of.hpp> +#include <boost/metaparse/space.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/bool.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::last_of; +using boost::metaparse::first_of; +using boost::metaparse::space; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::int_; +using boost::metaparse::foldl_reject_incomplete_start_with_parser; +using boost::metaparse::get_result; +using boost::metaparse::one_of; +using boost::metaparse::token; +using boost::metaparse::entire_input; + +using boost::mpl::apply_wrap1; +using boost::mpl::fold; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::plus; +using boost::mpl::minus; +using boost::mpl::times; +using boost::mpl::divides; +using boost::mpl::eval_if; +using boost::mpl::bool_; +using boost::mpl::equal_to; +using boost::mpl::bool_; + +/* + * The grammar + * + * expression ::= plus_exp + * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* + * prod_exp ::= int_token ((mult_token | div_token) int_token)* + */ + +typedef token<lit_c<'+'> > plus_token; +typedef token<lit_c<'-'> > minus_token; +typedef token<lit_c<'*'> > mult_token; +typedef token<lit_c<'/'> > div_token; + +typedef token<int_> int_token; + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct eval_plus +{ + template <class State, class C> + struct apply : + eval_if< + is_c<front<C>, '+'>, + plus<typename State::type, typename back<C>::type>, + minus<typename State::type, typename back<C>::type> + > + {}; +}; + +struct eval_mult +{ + template <class State, class C> + struct apply : + eval_if< + is_c<front<C>, '*'>, + times<typename State::type, typename back<C>::type>, + divides<typename State::type, typename back<C>::type> + > + {}; +}; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<mult_token, div_token>, int_token>, + int_token, + eval_mult + > + prod_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, prod_exp>, + prod_exp, + eval_plus + > + plus_exp; + +typedef last_of<repeated<space>, plus_exp> expression; + +typedef build_parser<entire_input<expression> > calculator_parser; + +#ifdef _STR +# error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +#if BOOST_METAPARSE_STD < 2011 +int main() +{ + using std::cout; + using std::endl; + using boost::metaparse::string; + + cout + << apply_wrap1<calculator_parser, string<'1','3'> >::type::value << endl + << + apply_wrap1< + calculator_parser, string<' ','1','+',' ','2','*','4','-','6','/','2'> + >::type::value + << endl + ; +} +#else +int main() +{ + using std::cout; + using std::endl; + + cout + << apply_wrap1<calculator_parser, _STR("13")>::type::value << endl + << apply_wrap1<calculator_parser, _STR(" 1+ 2*4-6/2")>::type::value << endl + ; +} +#endif + + diff --git a/src/boost/libs/metaparse/example/calculator_with_parens/Jamfile.v2 b/src/boost/libs/metaparse/example/calculator_with_parens/Jamfile.v2 new file mode 100644 index 000000000..af3cf8796 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator_with_parens/Jamfile.v2 @@ -0,0 +1 @@ +exe calculator_with_parens : main.cpp ; diff --git a/src/boost/libs/metaparse/example/calculator_with_parens/README b/src/boost/libs/metaparse/example/calculator_with_parens/README new file mode 100644 index 000000000..32bccca45 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator_with_parens/README @@ -0,0 +1,2 @@ +This is an extended version of the calculator example: it supports parens as +well. diff --git a/src/boost/libs/metaparse/example/calculator_with_parens/main.cpp b/src/boost/libs/metaparse/example/calculator_with_parens/main.cpp new file mode 100644 index 000000000..9a154fc36 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator_with_parens/main.cpp @@ -0,0 +1,163 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2014. +// Distributed under 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) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/first_of.hpp> +#include <boost/metaparse/middle_of.hpp> +#include <boost/metaparse/space.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/bool.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::last_of; +using boost::metaparse::first_of; +using boost::metaparse::middle_of; +using boost::metaparse::space; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::int_; +using boost::metaparse::foldl_reject_incomplete_start_with_parser; +using boost::metaparse::get_result; +using boost::metaparse::one_of; +using boost::metaparse::token; +using boost::metaparse::entire_input; + +using boost::mpl::apply_wrap1; +using boost::mpl::fold; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::plus; +using boost::mpl::minus; +using boost::mpl::times; +using boost::mpl::divides; +using boost::mpl::eval_if; +using boost::mpl::bool_; +using boost::mpl::equal_to; +using boost::mpl::bool_; + +/* + * The grammar + * + * expression ::= plus_exp + * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* + * prod_exp ::= int_token ((mult_token | div_token) simple_exp)* + * simple_exp ::= int_token | paren_exp + * paren_exp ::= open_paren_token expression close_paren_token + */ + +typedef token<lit_c<'+'> > plus_token; +typedef token<lit_c<'-'> > minus_token; +typedef token<lit_c<'*'> > mult_token; +typedef token<lit_c<'/'> > div_token; + +typedef token<lit_c<'('> > open_paren_token; +typedef token<lit_c<')'> > close_paren_token; + +typedef token<int_> int_token; + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct eval_plus +{ + template <class State, class C> + struct apply : + eval_if< + is_c<front<C>, '+'>, + plus<typename State::type, typename back<C>::type>, + minus<typename State::type, typename back<C>::type> + > + {}; +}; + +struct eval_mult +{ + template <class State, class C> + struct apply : + eval_if< + is_c<front<C>, '*'>, + times<typename State::type, typename back<C>::type>, + divides<typename State::type, typename back<C>::type> + > + {}; +}; + +struct plus_exp; + +typedef middle_of<open_paren_token, plus_exp, close_paren_token> paren_exp; + +typedef one_of<int_token, paren_exp> simple_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<mult_token, div_token>, simple_exp>, + simple_exp, + eval_mult + > + prod_exp; + +struct plus_exp : + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, prod_exp>, + prod_exp, + eval_plus + > +{}; + +typedef last_of<repeated<space>, plus_exp> expression; + +typedef build_parser<entire_input<expression> > calculator_parser; + +#ifdef _STR +# error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +#if BOOST_METAPARSE_STD < 2011 +int main() +{ + std::cout << "Please use a compiler that support constexpr" << std::endl; +} +#else +int main() +{ + using std::cout; + using std::endl; + + cout + << apply_wrap1<calculator_parser, _STR("13")>::type::value << endl + << apply_wrap1<calculator_parser, _STR(" 1+ 2*4-6/2")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("1+2*3+4")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("(1+2)*(3+4)")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("(2*3)+(4*5)")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("2 * 3 + 4")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("2 + (3 * 4)")>::type::value << endl + ; +} +#endif + diff --git a/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/Jamfile.v2 b/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/Jamfile.v2 new file mode 100644 index 000000000..4457aa322 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/Jamfile.v2 @@ -0,0 +1 @@ +exe calculator_with_parens_and_unary_ops : main.cpp ; diff --git a/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/README b/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/README new file mode 100644 index 000000000..ed8e33ad4 --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/README @@ -0,0 +1,2 @@ +This is an extended version of the calculator example: it supports unary +operators (eg. -13) as well. diff --git a/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/main.cpp b/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/main.cpp new file mode 100644 index 000000000..e9557562d --- /dev/null +++ b/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/main.cpp @@ -0,0 +1,192 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2014. +// Distributed under 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) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/first_of.hpp> +#include <boost/metaparse/middle_of.hpp> +#include <boost/metaparse/space.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/foldr_start_with_parser.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/negate.hpp> +#include <boost/mpl/char.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::last_of; +using boost::metaparse::first_of; +using boost::metaparse::middle_of; +using boost::metaparse::space; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::int_; +using boost::metaparse::foldl_reject_incomplete_start_with_parser; +using boost::metaparse::foldr_start_with_parser; +using boost::metaparse::get_result; +using boost::metaparse::one_of; +using boost::metaparse::token; +using boost::metaparse::entire_input; + +using boost::mpl::apply_wrap1; +using boost::mpl::fold; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::plus; +using boost::mpl::minus; +using boost::mpl::times; +using boost::mpl::divides; +using boost::mpl::eval_if; +using boost::mpl::bool_; +using boost::mpl::equal_to; +using boost::mpl::bool_; +using boost::mpl::negate; +using boost::mpl::char_; + +/* + * The grammar + * + * expression ::= plus_exp + * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* + * prod_exp ::= int_token ((mult_token | div_token) simple_exp)* + * simple_exp ::= (plus_token | minus_token)* (int_token | paren_exp) + * paren_exp ::= open_paren_token expression close_paren_token + */ + +typedef token<lit_c<'+'> > plus_token; +typedef token<lit_c<'-'> > minus_token; +typedef token<lit_c<'*'> > mult_token; +typedef token<lit_c<'/'> > div_token; + +typedef token<lit_c<'('> > open_paren_token; +typedef token<lit_c<')'> > close_paren_token; + +typedef token<int_> int_token; + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct eval_plus +{ + template <class State, class C> + struct apply : + eval_if< + is_c<front<C>, '+'>, + plus<typename State::type, typename back<C>::type>, + minus<typename State::type, typename back<C>::type> + > + {}; +}; + +struct eval_mult +{ + template <class State, class C> + struct apply : + eval_if< + is_c<front<C>, '*'>, + times<typename State::type, typename back<C>::type>, + divides<typename State::type, typename back<C>::type> + > + {}; +}; + +struct eval_unary_plus +{ + template <class State, class C> + struct apply : + eval_if< + typename equal_to<char_<'+'>, typename C::type>::type, + State, // +State is State + negate<typename State::type> + > + {}; +}; + +struct plus_exp; + +typedef middle_of<open_paren_token, plus_exp, close_paren_token> paren_exp; + +typedef + foldr_start_with_parser< + one_of<plus_token, minus_token>, + one_of<int_token, paren_exp>, + eval_unary_plus + > + simple_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<mult_token, div_token>, simple_exp>, + simple_exp, + eval_mult + > + prod_exp; + +struct plus_exp : + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, prod_exp>, + prod_exp, + eval_plus + > +{}; + +typedef last_of<repeated<space>, plus_exp> expression; + +typedef build_parser<entire_input<expression> > calculator_parser; + +#ifdef _STR +# error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +#if BOOST_METAPARSE_STD < 2011 +int main() +{ + std::cout << "Please use a compiler that support constexpr" << std::endl; +} +#else +int main() +{ + using std::cout; + using std::endl; + + cout + << apply_wrap1<calculator_parser, _STR("13")>::type::value << endl + << apply_wrap1<calculator_parser, _STR(" 1+ 2*4-6/2")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("1+2*3+4")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("(1+2)*(3+4)")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("(2*3)+(4*5)")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("2 * 3 + 4")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("2 + (3 * 4)")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("+3")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("-21")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("24 + - 21")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("- - 21")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("-(3 * 4)")>::type::value << endl + ; +} +#endif + diff --git a/src/boost/libs/metaparse/example/compile_to_native_code/Jamfile.v2 b/src/boost/libs/metaparse/example/compile_to_native_code/Jamfile.v2 new file mode 100644 index 000000000..05530b7c8 --- /dev/null +++ b/src/boost/libs/metaparse/example/compile_to_native_code/Jamfile.v2 @@ -0,0 +1 @@ +exe compile_to_native_code : main.cpp ; diff --git a/src/boost/libs/metaparse/example/compile_to_native_code/README b/src/boost/libs/metaparse/example/compile_to_native_code/README new file mode 100644 index 000000000..f41680ff7 --- /dev/null +++ b/src/boost/libs/metaparse/example/compile_to_native_code/README @@ -0,0 +1 @@ +An example on how to compile an EDSL into native executable code. diff --git a/src/boost/libs/metaparse/example/compile_to_native_code/main.cpp b/src/boost/libs/metaparse/example/compile_to_native_code/main.cpp new file mode 100644 index 000000000..e83624b2f --- /dev/null +++ b/src/boost/libs/metaparse/example/compile_to_native_code/main.cpp @@ -0,0 +1,252 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/space.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/always.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/if.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::last_of; +using boost::metaparse::space; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::int_; +using boost::metaparse::foldl_reject_incomplete_start_with_parser; +using boost::metaparse::get_result; +using boost::metaparse::one_of; +using boost::metaparse::token; +using boost::metaparse::entire_input; +using boost::metaparse::transform; +using boost::metaparse::always; + +using boost::mpl::apply_wrap1; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::if_; +using boost::mpl::bool_; + +/* + * The grammar + * + * expression ::= plus_exp + * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* + * prod_exp ::= value_exp ((mult_token | div_token) value_exp)* + * value_exp ::= int_token | '_' + */ + +typedef token<lit_c<'+'> > plus_token; +typedef token<lit_c<'-'> > minus_token; +typedef token<lit_c<'*'> > mult_token; +typedef token<lit_c<'/'> > div_token; + +typedef token<int_> int_token; +typedef token<lit_c<'_'> > arg_token; + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct build_plus +{ + template <class A, class B> + class _plus + { + public: + typedef _plus type; + + template <class T> + T operator()(T t) const + { + return _left(t) + _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class A, class B> + class _minus + { + public: + typedef _minus type; + + template <class T> + T operator()(T t) const + { + return _left(t) - _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '+'>::type, + _plus<State, typename back<C>::type>, + _minus<State, typename back<C>::type> + > + {}; +}; + +struct build_mult +{ + template <class A, class B> + class _mult + { + public: + typedef _mult type; + + template <class T> + T operator()(T t) const + { + return _left(t) * _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class A, class B> + class _div + { + public: + typedef _div type; + + template <class T> + T operator()(T t) const + { + return _left(t) / _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '*'>::type, + _mult<State, typename back<C>::type>, + _div<State, typename back<C>::type> + > + {}; +}; + +struct build_value +{ + typedef build_value type; + + template <class V> + struct apply + { + typedef apply type; + + template <class T> + int operator()(T) const + { + return V::type::value; + } + }; +}; + +struct arg +{ + typedef arg type; + + template <class T> + T operator()(T t) const + { + return t; + } +}; + +typedef + one_of<transform<int_token, build_value>, always<arg_token, arg> > + value_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<mult_token, div_token>, value_exp>, + value_exp, + build_mult + > + prod_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, prod_exp>, + prod_exp, + build_plus + > + plus_exp; + +typedef last_of<repeated<space>, plus_exp> expression; + +typedef build_parser<entire_input<expression> > function_parser; + +#if BOOST_METAPARSE_STD < 2011 + +template <class Exp> +struct lambda : apply_wrap1<function_parser, Exp> {}; + +using boost::metaparse::string; + +lambda<string<'1','3'> >::type f1; +lambda<string<'2',' ','+',' ','3'> >::type f2; +lambda<string<'2',' ','*',' ','2'> >::type f3; +lambda<string<' ','1','+',' ','2','*','4','-','6','/','2'> >::type f4; +lambda<string<'2',' ','*',' ','_'> >::type f5; + +#else + +#ifdef LAMBDA + #error LAMBDA already defined +#endif +#define LAMBDA(exp) apply_wrap1<function_parser, BOOST_METAPARSE_STRING(#exp)>::type + +LAMBDA(13) f1; +LAMBDA(2 + 3) f2; +LAMBDA(2 * 2) f3; +LAMBDA( 1+ 2*4-6/2) f4; +LAMBDA(2 * _) f5; + +#endif + +int main() +{ + using std::cout; + using std::endl; + + cout + << f1(11) << endl + << f2(11) << endl + << f3(11) << endl + << f4(11) << endl + << f5(11) << endl + << f5(1.1) << endl + ; +} + + diff --git a/src/boost/libs/metaparse/example/constexpr_parser/Jamfile.v2 b/src/boost/libs/metaparse/example/constexpr_parser/Jamfile.v2 new file mode 100644 index 000000000..5e1f4246a --- /dev/null +++ b/src/boost/libs/metaparse/example/constexpr_parser/Jamfile.v2 @@ -0,0 +1 @@ +exe constexpr_parser : main.cpp ; diff --git a/src/boost/libs/metaparse/example/constexpr_parser/README b/src/boost/libs/metaparse/example/constexpr_parser/README new file mode 100644 index 000000000..8b50db0e5 --- /dev/null +++ b/src/boost/libs/metaparse/example/constexpr_parser/README @@ -0,0 +1,12 @@ +Parsers parsing "a* b* a*" and counting the appearance of the characters. +This parser is implemented in three different ways: +- One built with Metaparse +- One implemented using constexpr functions +- One built with Metaparse but parsing a subexpression with a constexpr parser: + - a* at the beginning is parsed using a Metaparse parser + - b* is parsed using a constexpr function + - a* at the end is parsed using a Mataparse parser again + +This example demonstrates how Metaparse can be combined with parsers using +constexpr functions. + diff --git a/src/boost/libs/metaparse/example/constexpr_parser/main.cpp b/src/boost/libs/metaparse/example/constexpr_parser/main.cpp new file mode 100644 index 000000000..4fe291b07 --- /dev/null +++ b/src/boost/libs/metaparse/example/constexpr_parser/main.cpp @@ -0,0 +1,318 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/foldl.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/build_parser.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/start.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/iterate_c.hpp> +#include <boost/metaparse/one_char.hpp> +#include <boost/metaparse/return_.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/pop_front.hpp> +#include <boost/mpl/size.hpp> + +#include <iostream> +#include <string> + +#if BOOST_METAPARSE_STD < 2011 + +int main() +{ + std::cout + << "This example focuses on constexpr, which is not supported" + << std::endl; +} + +#else + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::build_parser; +using boost::metaparse::foldl; +using boost::metaparse::entire_input; +using boost::metaparse::get_result; +using boost::metaparse::start; +using boost::metaparse::last_of; +using boost::metaparse::iterate_c; +using boost::metaparse::one_char; +using boost::metaparse::return_; + +using boost::mpl::apply_wrap1; +using boost::mpl::apply_wrap2; +using boost::mpl::plus; +using boost::mpl::int_; +using boost::mpl::at_c; +using boost::mpl::front; +using boost::mpl::pop_front; +using boost::mpl::size; + +using std::ostream; + +/* + * The grammar + * + * S ::= a* b* a* + */ + +struct parsed +{ + template <class T> + constexpr static parsed build() + { + return + parsed( + at_c<typename T::type, 0>::type::value, + at_c<typename T::type, 1>::type::value, + at_c<typename T::type, 2>::type::value + ); + } + + constexpr parsed(int a1, int b, int a2) : + a_count1(a1), + b_count(b), + a_count2(a2) + {}; + + int a_count1; + int b_count; + int a_count2; +}; + +ostream& operator<<(ostream& o, const parsed& p) +{ + return + o << "(" << p.a_count1 << ", " << p.b_count << ", " << p.a_count2 << ")"; +} + +// constexpr parser + +template <class T, int Len> +struct const_list +{ + T head; + const_list<T, Len - 1> tail; + + constexpr const_list(const T& h, const const_list<T, Len - 1>& t) : + head(h), + tail(t) + {} + + constexpr const_list<T, Len + 1> push_front(const T& t) const + { + return const_list<T, Len + 1>(t, *this); + } + + constexpr T at(int n) const + { + return n == 0 ? head : tail.at(n - 1); + } +}; + +template <class T> +struct const_list<T, 0> +{ + constexpr const_list<T, 1> push_front(const T& t) const + { + return const_list<T, 1>(t, *this); + } + + constexpr T at(int) const + { + return T(); + } +}; + +template <class T, int N, int from = 0> +struct to_list +{ + static constexpr const_list<T, N - from> run(const T (&s)[N]) + { + return const_list<T, N - from>(s[from], to_list<T, N, from + 1>::run(s)); + } +}; + +template <class T, int N> +struct to_list<T, N, N> +{ + static constexpr const_list<T, 0> run(const T (&s)[N]) + { + return const_list<T, 0>(); + } +}; + +struct presult +{ + int value; + int remaining_from; + + constexpr presult(int v, int r) : value(v), remaining_from(r) {} + + constexpr presult incr() const { return presult(value + 1, remaining_from); } +}; + +template <char C, int N> +constexpr presult parse_cs(const const_list<char, N>& s, int from) +{ + return + from < N ? + (s.at(from) == C ? parse_cs<C, N>(s, from + 1).incr() : presult(0, from)) : + presult(0, from); +} + +template <int N> +constexpr parsed parse_impl(const const_list<char, N>& s) +{ + return + parsed( + parse_cs<'a', N>(s, 0).value, + parse_cs<'b', N>(s, parse_cs<'a', N>(s, 0).remaining_from).value, + parse_cs<'a', N>( + s, + parse_cs<'b', N>( + s, + parse_cs<'a', N>(s, 0).remaining_from + ).remaining_from + ).value + ); +} + +template <int N> +constexpr parsed parse(const char (&s)[N]) +{ + return parse_impl(to_list<char, N>::run(s)); +} + +// TMP parser + +struct count +{ + typedef count type; + + template <class State, class C> + struct apply : plus<int_<1>, State> {}; +}; + +typedef foldl<lit_c<'a'>, int_<0>, count> as; +typedef foldl<lit_c<'b'>, int_<0>, count> bs; + +typedef sequence<as, bs, as> s; + +typedef build_parser<entire_input<s> > parser; + +#ifdef P + #error P already defined +#endif +#define P(x) \ + parsed::build<boost::mpl::apply_wrap1<parser, BOOST_METAPARSE_STRING(#x)> >() + +// Mixed parser + +template <class ValueType, class L, int Len> +struct tmp_to_const_list_impl +{ + constexpr static const_list<ValueType, Len> run() + { + return + const_list<ValueType, Len>( + front<L>::type::value, + tmp_to_const_list_impl< + ValueType, + typename pop_front<L>::type, + Len - 1 + >::run() + ); + } +}; + +template <class ValueType, class L> +struct tmp_to_const_list_impl<ValueType, L, 0> +{ + constexpr static const_list<ValueType, 0> run() + { + return const_list<ValueType, 0>(); + } +}; + +template <class ValueType, class L> +struct tmp_to_const_list : + tmp_to_const_list_impl<ValueType, L, size<L>::type::value> +{}; + +template <char C> +struct parse_with_constexpr +{ + typedef parse_with_constexpr type; + + template <class S> + static constexpr presult impl() + { + return + parse_cs<C, size<S>::type::value>(tmp_to_const_list<char, S>::run(), 0); + } + + template <class S, class Pos> + struct apply : + apply_wrap2< + last_of< + iterate_c<one_char, impl<S>().remaining_from>, + return_<int_<impl<S>().value> > + >, + S, + Pos + > + {}; +}; + +typedef parse_with_constexpr<'b'> bs_mixed; + +typedef sequence<as, bs_mixed, as> s_mixed; + +typedef build_parser<entire_input<s_mixed> > parser_mixed; + +#ifdef P_MIXED + #error P_MIXED already defined +#endif +#define P_MIXED(x) \ + parsed::build< \ + boost::mpl::apply_wrap1<parser_mixed, BOOST_METAPARSE_STRING(#x)> \ + >() + +int main() +{ + using std::cout; + using std::endl; + + cout + << "TMP only parsers:" << endl + << P(aba) << endl + << P(aaaaaaabbbbaaaa) << endl + << endl + + << "constexpr only parsers:" << endl + << parse("") << endl + << parse("aba") << endl + << parse("aaaaaaabbbbaaaa") << endl + << endl + + << "mixed parsers:" << endl + << P_MIXED(aba) << endl + << P_MIXED(aaaaaaabbbbaaaa) << endl + << endl + ; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/1.hpp b/src/boost/libs/metaparse/example/getting_started/1.hpp new file mode 100644 index 000000000..ee00e7a1d --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/1.hpp @@ -0,0 +1,9 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_1_HPP + +// Automatically generated header file + +// Definitions of section + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/10.hpp b/src/boost/libs/metaparse/example/getting_started/10.hpp new file mode 100644 index 000000000..e8ed5f1c3 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/10.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_10_HPP +#define BOOST_METAPARSE_GETTING_STARTED_10_HPP + +// Automatically generated header file + +// Definitions before section 9 +#include "9.hpp" + +// Definitions of section 9 +#include <boost/mpl/negate.hpp> + +using unary_exp1 = + foldr_start_with_parser< + minus_token, + int_token, + boost::mpl::lambda<boost::mpl::negate<boost::mpl::_1>>::type + >; + +using mult_exp4 = + foldl_start_with_parser< + sequence<one_of<times_token, divides_token>, unary_exp1>, + unary_exp1, + boost::mpl::quote2<binary_op> + >; + +using exp_parser18 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp4>, + mult_exp4, + boost::mpl::quote2<binary_op> + > + >; + +// query: +// exp_parser18::apply<BOOST_METAPARSE_STRING("---13")>::type + +// query: +// exp_parser18::apply<BOOST_METAPARSE_STRING("13")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/11.hpp b/src/boost/libs/metaparse/example/getting_started/11.hpp new file mode 100644 index 000000000..3583496a8 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/11.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_11_HPP +#define BOOST_METAPARSE_GETTING_STARTED_11_HPP + +// Automatically generated header file + +// Definitions before section 10 +#include "10.hpp" + +// Definitions of section 10 +using lparen_token = token<lit_c<'('>>; + +using rparen_token = token<lit_c<')'>>; + +using plus_exp1 = + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp4>, + mult_exp4, + boost::mpl::quote2<binary_op> + >; + +using paren_exp1 = sequence<lparen_token, plus_exp1, rparen_token>; + +#include <boost/metaparse/middle_of.hpp> + +using paren_exp2 = middle_of<lparen_token, plus_exp1, rparen_token>; + +using primary_exp1 = one_of<int_token, paren_exp2>; + +struct plus_exp2; + +using paren_exp3 = middle_of<lparen_token, plus_exp2, rparen_token>; + +using primary_exp2 = one_of<int_token, paren_exp2>; + +using unary_exp2 = + foldr_start_with_parser< + minus_token, + primary_exp2, + boost::mpl::lambda<boost::mpl::negate<boost::mpl::_1>>::type + >; + +using mult_exp5 = + foldl_start_with_parser< + sequence<one_of<times_token, divides_token>, unary_exp2>, + unary_exp2, + boost::mpl::quote2<binary_op> + >; + +struct plus_exp2 : + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp5>, + mult_exp5, + boost::mpl::quote2<binary_op> + > {}; + +using exp_parser19 = build_parser<plus_exp2>; + +// query: +// exp_parser19::apply<BOOST_METAPARSE_STRING("(1 + 2) * 3")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/11_1.hpp b/src/boost/libs/metaparse/example/getting_started/11_1.hpp new file mode 100644 index 000000000..be2a2de63 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/11_1.hpp @@ -0,0 +1,14 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_11_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_11_1_HPP + +// Automatically generated header file + +// Definitions before section 11 +#include "11.hpp" + +// Definitions of section 11 +// query: +// exp_parser19::apply<BOOST_METAPARSE_STRING("hello")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/11_2.hpp b/src/boost/libs/metaparse/example/getting_started/11_2.hpp new file mode 100644 index 000000000..ae36b4e46 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/11_2.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_11_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_11_2_HPP + +// Automatically generated header file + +// Definitions before section 11.1 +#include "11_1.hpp" + +// Definitions of section 11.1 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/11_3.hpp b/src/boost/libs/metaparse/example/getting_started/11_3.hpp new file mode 100644 index 000000000..a93c2dc47 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/11_3.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_11_3_HPP +#define BOOST_METAPARSE_GETTING_STARTED_11_3_HPP + +// Automatically generated header file + +// Definitions before section 11.2 +#include "11_2.hpp" + +// Definitions of section 11.2 +#include <boost/metaparse/define_error.hpp> + +BOOST_METAPARSE_DEFINE_ERROR(missing_primary_expression, "Missing primary expression"); + +struct plus_exp3; + +using paren_exp4 = middle_of<lparen_token, plus_exp3, rparen_token>; + +#include <boost/metaparse/fail.hpp> + +using primary_exp3 = one_of<int_token, paren_exp4, fail<missing_primary_expression>>; + +using unary_exp3 = + foldr_start_with_parser< + minus_token, + primary_exp3, + boost::mpl::lambda<boost::mpl::negate<boost::mpl::_1>>::type + >; + +using mult_exp6 = + foldl_start_with_parser< + sequence<one_of<times_token, divides_token>, unary_exp3>, + unary_exp3, + boost::mpl::quote2<binary_op> + >; + +struct plus_exp3 : + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp6>, + mult_exp6, + boost::mpl::quote2<binary_op> + > {}; + +using exp_parser20 = build_parser<plus_exp3>; + +// query: +// exp_parser20::apply<BOOST_METAPARSE_STRING("hello")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/11_3_1.hpp b/src/boost/libs/metaparse/example/getting_started/11_3_1.hpp new file mode 100644 index 000000000..56da35a82 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/11_3_1.hpp @@ -0,0 +1,38 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_11_3_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_11_3_1_HPP + +// Automatically generated header file + +// Definitions before section 11.3 +#include "11_3.hpp" + +// Definitions of section 11.3 +// query: +// exp_parser20::apply<BOOST_METAPARSE_STRING("(1+2")>::type + +// query: +// exp_parser20::apply<BOOST_METAPARSE_STRING("0+(1+2")>::type + +#include <boost/metaparse/fail_at_first_char_expected.hpp> + +#include <boost/metaparse/first_of.hpp> + +struct plus_exp4 : + first_of< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp6>, + mult_exp6, + boost::mpl::quote2<binary_op> + >, + fail_at_first_char_expected< + sequence<one_of<plus_token, minus_token>, mult_exp6> + > + > {}; + +using exp_parser21 = build_parser<plus_exp4>; + +// query: +// exp_parser21::apply<BOOST_METAPARSE_STRING("0+(1+2")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/11_3_2.hpp b/src/boost/libs/metaparse/example/getting_started/11_3_2.hpp new file mode 100644 index 000000000..bf2e4b457 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/11_3_2.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_11_3_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_11_3_2_HPP + +// Automatically generated header file + +// Definitions before section 11.3.1 +#include "11_3_1.hpp" + +// Definitions of section 11.3.1 +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> + +struct plus_exp5 : + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp6>, + mult_exp6, + boost::mpl::quote2<binary_op> + > {}; + +using exp_parser22 = build_parser<plus_exp5>; + +// query: +// exp_parser22::apply<BOOST_METAPARSE_STRING("0+(1+2")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/12.hpp b/src/boost/libs/metaparse/example/getting_started/12.hpp new file mode 100644 index 000000000..d503539b1 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/12.hpp @@ -0,0 +1,46 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_12_HPP +#define BOOST_METAPARSE_GETTING_STARTED_12_HPP + +// Automatically generated header file + +// Definitions before section 11.3.2 +#include "11_3_2.hpp" + +// Definitions of section 11.3.2 +struct plus_exp6; + +using paren_exp5 = middle_of<lparen_token, plus_exp6, rparen_token>; + +using primary_exp4 = one_of<int_token, paren_exp5, fail<missing_primary_expression>>; + +using unary_exp4 = + foldr_start_with_parser< + minus_token, + primary_exp4, + boost::mpl::lambda<boost::mpl::negate<boost::mpl::_1>>::type + >; + +using mult_exp7 = + foldl_reject_incomplete_start_with_parser< + sequence<one_of<times_token, divides_token>, unary_exp4>, + unary_exp4, + boost::mpl::quote2<binary_op> + >; + +struct plus_exp6 : + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp7>, + mult_exp7, + boost::mpl::quote2<binary_op> + > {}; + +using exp_parser23 = build_parser<plus_exp6>; + +// query: +// exp_parser23::apply<BOOST_METAPARSE_STRING("1+(2*")>::type + +// query: +// exp_parser23::apply<BOOST_METAPARSE_STRING("1+(2*3")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/1_1.hpp b/src/boost/libs/metaparse/example/getting_started/1_1.hpp new file mode 100644 index 000000000..36fa44660 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/1_1.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_1_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_1_1_HPP + +// Automatically generated header file + +// Definitions before section 1 +#include "1.hpp" + +// Definitions of section 1 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/1_2.hpp b/src/boost/libs/metaparse/example/getting_started/1_2.hpp new file mode 100644 index 000000000..dd19e3ef9 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/1_2.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_1_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_1_2_HPP + +// Automatically generated header file + +// Definitions before section 1.1 +#include "1_1.hpp" + +// Definitions of section 1.1 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/1_2_1.hpp b/src/boost/libs/metaparse/example/getting_started/1_2_1.hpp new file mode 100644 index 000000000..db5d3fe53 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/1_2_1.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_1_2_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_1_2_1_HPP + +// Automatically generated header file + +// Definitions before section 1.2 +#include "1_2.hpp" + +// Definitions of section 1.2 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/1_2_2.hpp b/src/boost/libs/metaparse/example/getting_started/1_2_2.hpp new file mode 100644 index 000000000..f84edb36c --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/1_2_2.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_1_2_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_1_2_2_HPP + +// Automatically generated header file + +// Definitions before section 1.2.1 +#include "1_2_1.hpp" + +// Definitions of section 1.2.1 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/2.hpp b/src/boost/libs/metaparse/example/getting_started/2.hpp new file mode 100644 index 000000000..3c3ecb422 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/2.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_2_HPP + +// Automatically generated header file + +// Definitions before section 1.2.2 +#include "1_2_2.hpp" + +// Definitions of section 1.2.2 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/3.hpp b/src/boost/libs/metaparse/example/getting_started/3.hpp new file mode 100644 index 000000000..4df3b531d --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/3.hpp @@ -0,0 +1,19 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_3_HPP +#define BOOST_METAPARSE_GETTING_STARTED_3_HPP + +// Automatically generated header file + +// Definitions before section 2 +#include "2.hpp" + +// Definitions of section 2 +#include <boost/metaparse/string.hpp> + +// query: +// boost::metaparse::string<'1', '1', ' ', '+', ' ', '2'> + +// query: +// BOOST_METAPARSE_STRING("11 + 2") + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/3_1.hpp b/src/boost/libs/metaparse/example/getting_started/3_1.hpp new file mode 100644 index 000000000..f383508db --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/3_1.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_3_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_3_1_HPP + +// Automatically generated header file + +// Definitions before section 3 +#include "3.hpp" + +// Definitions of section 3 +#include <boost/metaparse/int_.hpp> + +#include <boost/metaparse/build_parser.hpp> + +using namespace boost::metaparse; + +using exp_parser1 = build_parser<int_>; + +// query: +// exp_parser1::apply<BOOST_METAPARSE_STRING("13")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/3_2.hpp b/src/boost/libs/metaparse/example/getting_started/3_2.hpp new file mode 100644 index 000000000..0cc9a48e7 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/3_2.hpp @@ -0,0 +1,14 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_3_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_3_2_HPP + +// Automatically generated header file + +// Definitions before section 3.1 +#include "3_1.hpp" + +// Definitions of section 3.1 +// query: +// exp_parser1::apply<BOOST_METAPARSE_STRING("thirteen")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/3_3.hpp b/src/boost/libs/metaparse/example/getting_started/3_3.hpp new file mode 100644 index 000000000..cc35183f1 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/3_3.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_3_3_HPP +#define BOOST_METAPARSE_GETTING_STARTED_3_3_HPP + +// Automatically generated header file + +// Definitions before section 3.2 +#include "3_2.hpp" + +// Definitions of section 3.2 +// query: +// exp_parser1::apply<BOOST_METAPARSE_STRING("11 13")>::type + +#include <boost/metaparse/entire_input.hpp> + +using exp_parser2 = build_parser<entire_input<int_>>; + +// query: +// exp_parser2::apply<BOOST_METAPARSE_STRING("13")>::type + +// query: +// exp_parser2::apply<BOOST_METAPARSE_STRING("11 13")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/4.hpp b/src/boost/libs/metaparse/example/getting_started/4.hpp new file mode 100644 index 000000000..6fe2fc8f6 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/4.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_4_HPP +#define BOOST_METAPARSE_GETTING_STARTED_4_HPP + +// Automatically generated header file + +// Definitions before section 3.3 +#include "3_3.hpp" + +// Definitions of section 3.3 +// query: +// exp_parser2::apply<BOOST_METAPARSE_STRING("11 ")>::type + +#include <boost/metaparse/token.hpp> + +using exp_parser3 = build_parser<entire_input<token<int_>>>; + +// query: +// exp_parser3::apply<BOOST_METAPARSE_STRING("11 ")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/4_1.hpp b/src/boost/libs/metaparse/example/getting_started/4_1.hpp new file mode 100644 index 000000000..513705947 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/4_1.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_4_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_4_1_HPP + +// Automatically generated header file + +// Definitions before section 4 +#include "4.hpp" + +// Definitions of section 4 +#include <boost/metaparse/lit_c.hpp> + +#include <boost/metaparse/sequence.hpp> + +using exp_parser4 = build_parser<sequence<token<int_>, token<lit_c<'+'>>, token<int_>>>; + +// query: +// exp_parser4::apply<BOOST_METAPARSE_STRING("11 + 2")>::type + +#ifdef __METASHELL +#include <metashell/formatter.hpp> +#endif + +// query: +// exp_parser4::apply<BOOST_METAPARSE_STRING("11 + 2")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/4_2.hpp b/src/boost/libs/metaparse/example/getting_started/4_2.hpp new file mode 100644 index 000000000..1663c4686 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/4_2.hpp @@ -0,0 +1,20 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_4_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_4_2_HPP + +// Automatically generated header file + +// Definitions before section 4.1 +#include "4_1.hpp" + +// Definitions of section 4.1 +using int_token = token<int_>; + +using plus_token = token<lit_c<'+'>>; + +using exp_parser5 = build_parser<sequence<int_token, plus_token, int_token>>; + +// query: +// exp_parser5::apply<BOOST_METAPARSE_STRING("11 + 2")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5.hpp b/src/boost/libs/metaparse/example/getting_started/5.hpp new file mode 100644 index 000000000..671b34e9e --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_HPP + +// Automatically generated header file + +// Definitions before section 4.2 +#include "4_2.hpp" + +// Definitions of section 4.2 +#include <boost/metaparse/transform.hpp> + +#include <boost/mpl/plus.hpp> + +#include <boost/mpl/at.hpp> + +template <class Vector> + struct eval_plus : + boost::mpl::plus< + typename boost::mpl::at_c<Vector, 0>::type, + typename boost::mpl::at_c<Vector, 2>::type + > {}; + +// query: +// eval_plus< +// boost::mpl::vector< +// mpl_::integral_c<int, 11>, +// mpl_::char_<'+'>, +// mpl_::integral_c<int, 2> +// >>::type + +#include <boost/mpl/quote.hpp> + +using exp_parser6 = + build_parser< + transform< + sequence<int_token, plus_token, int_token>, + boost::mpl::quote1<eval_plus> + > + >; + +// query: +// exp_parser6::apply<BOOST_METAPARSE_STRING("11 + 2")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5_1.hpp b/src/boost/libs/metaparse/example/getting_started/5_1.hpp new file mode 100644 index 000000000..4042182e2 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5_1.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_1_HPP + +// Automatically generated header file + +// Definitions before section 5 +#include "5.hpp" + +// Definitions of section 5 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5_2.hpp b/src/boost/libs/metaparse/example/getting_started/5_2.hpp new file mode 100644 index 000000000..ea9a0b18a --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5_2.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_2_HPP + +// Automatically generated header file + +// Definitions before section 5.1 +#include "5_1.hpp" + +// Definitions of section 5.1 +#include <boost/metaparse/any.hpp> + +using exp_parser7 = + build_parser< + sequence< + int_token, /* The first <number> */ + repeated<sequence<plus_token, int_token>> /* The "+ <number>" elements */ + > + >; + +// query: +// exp_parser7::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5_2_1.hpp b/src/boost/libs/metaparse/example/getting_started/5_2_1.hpp new file mode 100644 index 000000000..f8e9ca219 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5_2_1.hpp @@ -0,0 +1,13 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_2_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_2_1_HPP + +// Automatically generated header file + +// Definitions before section 5.2 +#include "5_2.hpp" + +// Definitions of section 5.2 +using temp_result = exp_parser7::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type; + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5_2_2.hpp b/src/boost/libs/metaparse/example/getting_started/5_2_2.hpp new file mode 100644 index 000000000..ea9ecb366 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5_2_2.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_2_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_2_2_HPP + +// Automatically generated header file + +// Definitions before section 5.2.1 +#include "5_2_1.hpp" + +// Definitions of section 5.2.1 +#include <boost/mpl/fold.hpp> + +using vector_of_numbers = + boost::mpl::vector< + boost::mpl::int_<2>, + boost::mpl::int_<5>, + boost::mpl::int_<6> + >; + +template <class Vector> + struct sum_vector : + boost::mpl::fold< + Vector, + boost::mpl::int_<0>, + boost::mpl::lambda< + boost::mpl::plus<boost::mpl::_1, boost::mpl::_2> + >::type + > + {}; + +// query: +// sum_vector<vector_of_numbers>::type + +template <class Sum, class Item> + struct sum_items : + boost::mpl::plus< + Sum, + typename boost::mpl::at_c<Item, 1>::type + > + {}; + +// query: +// sum_items< +// mpl_::integral_c<int, 1>, +// boost::mpl::vector<mpl_::char_<'+'>, mpl_::integral_c<int, 2>> +// >::type + +// query: +// boost::mpl::at_c<temp_result, 1>::type + +// query: +// boost::mpl::fold< +// boost::mpl::at_c<temp_result, 1>::type, /* The vector to summarise */ +// boost::mpl::int_<0>, /* The value to start the sum from */ +// boost::mpl::quote2<sum_items> /* The function to call in each iteration */ +// >::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5_2_3.hpp b/src/boost/libs/metaparse/example/getting_started/5_2_3.hpp new file mode 100644 index 000000000..b14a0c5e5 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5_2_3.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_2_3_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_2_3_HPP + +// Automatically generated header file + +// Definitions before section 5.2.2 +#include "5_2_2.hpp" + +// Definitions of section 5.2.2 +using exp_parser8 = + build_parser< + sequence< + int_token, /* parse the first <number> */ + transform< + repeated<sequence<plus_token, int_token>>, /* parse the "+ <number>" elements */ + /* lambda expression summarising the "+ <number>" elements using fold */ + boost::mpl::lambda< + /* The folding expression we have just created */ + boost::mpl::fold< + boost::mpl::_1, /* the argument of the lambda expression, the result */ + /* of the repeated<...> parser */ + boost::mpl::int_<0>, + boost::mpl::quote2<sum_items> + > + >::type + > + > + >; + +// query: +// exp_parser8::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type + +using exp_parser9 = + build_parser< + transform< + /* What we had so far */ + sequence< + int_token, + transform< + repeated<sequence<plus_token, int_token>>, + boost::mpl::lambda< + boost::mpl::fold< + boost::mpl::_1, + boost::mpl::int_<0>, + boost::mpl::quote2<sum_items> + > + >::type + > + >, + boost::mpl::quote1<sum_vector> /* summarise the vector of numbers */ + > + >; + +// query: +// exp_parser9::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/5_2_4.hpp b/src/boost/libs/metaparse/example/getting_started/5_2_4.hpp new file mode 100644 index 000000000..3d4d30210 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/5_2_4.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_5_2_4_HPP +#define BOOST_METAPARSE_GETTING_STARTED_5_2_4_HPP + +// Automatically generated header file + +// Definitions before section 5.2.3 +#include "5_2_3.hpp" + +// Definitions of section 5.2.3 +#include <boost/metaparse/foldl.hpp> + +using exp_parser10 = + build_parser< + transform< + sequence< + int_token, + foldl< + sequence<plus_token, int_token>, + boost::mpl::int_<0>, + boost::mpl::quote2<sum_items> + > + >, + boost::mpl::quote1<sum_vector>> + >; + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/6.hpp b/src/boost/libs/metaparse/example/getting_started/6.hpp new file mode 100644 index 000000000..906cb04bd --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/6.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_6_HPP +#define BOOST_METAPARSE_GETTING_STARTED_6_HPP + +// Automatically generated header file + +// Definitions before section 5.2.4 +#include "5_2_4.hpp" + +// Definitions of section 5.2.4 +#include <boost/metaparse/foldl_start_with_parser.hpp> + +using exp_parser11 = + build_parser< + foldl_start_with_parser< + sequence<plus_token, int_token>, /* apply this parser repeatedly */ + int_token, /* use this parser to get the initial value */ + boost::mpl::quote2<sum_items> /* use this function to add a new value to the summary */ + > + >; + +// query: +// exp_parser11::apply<BOOST_METAPARSE_STRING("1 + 2 + 3 + 4")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/6_1.hpp b/src/boost/libs/metaparse/example/getting_started/6_1.hpp new file mode 100644 index 000000000..0cc124497 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/6_1.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_6_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_6_1_HPP + +// Automatically generated header file + +// Definitions before section 6 +#include "6.hpp" + +// Definitions of section 6 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/6_2.hpp b/src/boost/libs/metaparse/example/getting_started/6_2.hpp new file mode 100644 index 000000000..d9f8bad27 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/6_2.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_6_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_6_2_HPP + +// Automatically generated header file + +// Definitions before section 6.1 +#include "6_1.hpp" + +// Definitions of section 6.1 +using minus_token = token<lit_c<'-'>>; + +#include <boost/metaparse/one_of.hpp> + +using exp_parser12 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, int_token>, + int_token, + boost::mpl::quote2<sum_items> + > + >; + +// query: +// exp_parser12::apply<BOOST_METAPARSE_STRING("1 + 2 - 3")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/7.hpp b/src/boost/libs/metaparse/example/getting_started/7.hpp new file mode 100644 index 000000000..fe245b98a --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/7.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_7_HPP +#define BOOST_METAPARSE_GETTING_STARTED_7_HPP + +// Automatically generated header file + +// Definitions before section 6.2 +#include "6_2.hpp" + +// Definitions of section 6.2 +#include <boost/mpl/minus.hpp> + +template <class L, char Op, class R> struct eval_binary_op; + +template <class L, class R> struct eval_binary_op<L, '+', R> : boost::mpl::plus<L, R>::type {}; + +template <class L, class R> struct eval_binary_op<L, '-', R> : boost::mpl::minus<L, R>::type {}; + +// query: +// eval_binary_op<boost::mpl::int_<11>, '+', boost::mpl::int_<2>>::type + +// query: +// eval_binary_op<boost::mpl::int_<13>, '-', boost::mpl::int_<2>>::type + +template <class S, class Item> + struct binary_op : + eval_binary_op< + S, + boost::mpl::at_c<Item, 0>::type::value, + typename boost::mpl::at_c<Item, 1>::type + > + {}; + +// query: +// binary_op<boost::mpl::int_<11>, boost::mpl::vector<boost::mpl::char_<'+'>, boost::mpl::int_<2>>>::type + +using exp_parser13 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, int_token>, + int_token, + boost::mpl::quote2<binary_op> + > + >; + +// query: +// exp_parser13::apply<BOOST_METAPARSE_STRING("1 + 2 - 3")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/7_1.hpp b/src/boost/libs/metaparse/example/getting_started/7_1.hpp new file mode 100644 index 000000000..02b99e7b6 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/7_1.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_7_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_7_1_HPP + +// Automatically generated header file + +// Definitions before section 7 +#include "7.hpp" + +// Definitions of section 7 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/7_2.hpp b/src/boost/libs/metaparse/example/getting_started/7_2.hpp new file mode 100644 index 000000000..07e1a3583 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/7_2.hpp @@ -0,0 +1,35 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_7_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_7_2_HPP + +// Automatically generated header file + +// Definitions before section 7.1 +#include "7_1.hpp" + +// Definitions of section 7.1 +#include <boost/mpl/times.hpp> + +template <class L, class R> struct eval_binary_op<L, '*', R> : boost::mpl::times<L, R>::type {}; + +// query: +// eval_binary_op<boost::mpl::int_<3>, '*', boost::mpl::int_<4>>::type + +using times_token = token<lit_c<'*'>>; + +using exp_parser14 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token, times_token>, int_token>, + int_token, + boost::mpl::quote2<binary_op> + > + >; + +// query: +// exp_parser14::apply<BOOST_METAPARSE_STRING("2 * 3")>::type + +// query: +// exp_parser14::apply<BOOST_METAPARSE_STRING("1 + 2 * 3")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/8.hpp b/src/boost/libs/metaparse/example/getting_started/8.hpp new file mode 100644 index 000000000..c052f5b83 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/8.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_8_HPP +#define BOOST_METAPARSE_GETTING_STARTED_8_HPP + +// Automatically generated header file + +// Definitions before section 7.2 +#include "7_2.hpp" + +// Definitions of section 7.2 +using mult_exp1 = foldl_start_with_parser<sequence<times_token, int_token>, int_token, boost::mpl::quote2<binary_op>>; + +using exp_parser15 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp1>, + mult_exp1, + boost::mpl::quote2<binary_op> + > + >; + +// query: +// exp_parser15::apply<BOOST_METAPARSE_STRING("1 + 2 * 3")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/8_1.hpp b/src/boost/libs/metaparse/example/getting_started/8_1.hpp new file mode 100644 index 000000000..aca70e75c --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/8_1.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_8_1_HPP +#define BOOST_METAPARSE_GETTING_STARTED_8_1_HPP + +// Automatically generated header file + +// Definitions before section 8 +#include "8.hpp" + +// Definitions of section 8 +#include <boost/mpl/divides.hpp> + +template <class L, class R> struct eval_binary_op<L, '/', R> : boost::mpl::divides<L, R>::type {}; + +using divides_token = token<lit_c<'/'>>; + +using mult_exp2 = + foldl_start_with_parser< + sequence<one_of<times_token, divides_token>, int_token>, + int_token, + boost::mpl::quote2<binary_op> + >; + +using exp_parser16 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp2>, + mult_exp2, + boost::mpl::quote2<binary_op> + > + >; + +// query: +// exp_parser16::apply<BOOST_METAPARSE_STRING("8 / 4")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/8_2.hpp b/src/boost/libs/metaparse/example/getting_started/8_2.hpp new file mode 100644 index 000000000..303c38830 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/8_2.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_8_2_HPP +#define BOOST_METAPARSE_GETTING_STARTED_8_2_HPP + +// Automatically generated header file + +// Definitions before section 8.1 +#include "8_1.hpp" + +// Definitions of section 8.1 + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/9.hpp b/src/boost/libs/metaparse/example/getting_started/9.hpp new file mode 100644 index 000000000..47366b913 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/9.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_METAPARSE_GETTING_STARTED_9_HPP +#define BOOST_METAPARSE_GETTING_STARTED_9_HPP + +// Automatically generated header file + +// Definitions before section 8.2 +#include "8_2.hpp" + +// Definitions of section 8.2 +template <class S, class Item> + struct reverse_binary_op : + eval_binary_op< + typename boost::mpl::at_c<Item, 0>::type, + boost::mpl::at_c<Item, 1>::type::value, + S + > + {}; + +#include <boost/metaparse/foldr_start_with_parser.hpp> + +using mult_exp3 = + foldr_start_with_parser< + sequence<int_token, one_of<times_token, divides_token>>, /* The parser applied repeatedly */ + int_token, /* The parser parsing the last number */ + boost::mpl::quote2<reverse_binary_op> /* The function called for every result */ + /* of applying the above parser */ + >; + +using exp_parser17 = + build_parser< + foldl_start_with_parser< + sequence<one_of<plus_token, minus_token>, mult_exp3>, + mult_exp3, + boost::mpl::quote2<binary_op> + > + >; + +// query: +// exp_parser17::apply<BOOST_METAPARSE_STRING("8 / 4 / 2")>::type + +#endif + diff --git a/src/boost/libs/metaparse/example/getting_started/README b/src/boost/libs/metaparse/example/getting_started/README new file mode 100644 index 000000000..f2c6703b5 --- /dev/null +++ b/src/boost/libs/metaparse/example/getting_started/README @@ -0,0 +1,6 @@ +This example contains the code snippets of Getting Started. These headers are +intended to be used from Metashell. To get all the definitions before section +N. you need to include N.hpp + +The headers can always be re-generated by running tools/generate_all.py + diff --git a/src/boost/libs/metaparse/example/grammar_calculator/Jamfile.v2 b/src/boost/libs/metaparse/example/grammar_calculator/Jamfile.v2 new file mode 100644 index 000000000..cc98a4090 --- /dev/null +++ b/src/boost/libs/metaparse/example/grammar_calculator/Jamfile.v2 @@ -0,0 +1,6 @@ +project : requirements + <toolset>gcc:<cxxflags>-ftemplate-depth=512 + <toolset>clang:<cxxflags>-ftemplate-depth=512 +; + +exe grammar_calculator : main.cpp ; diff --git a/src/boost/libs/metaparse/example/grammar_calculator/README b/src/boost/libs/metaparse/example/grammar_calculator/README new file mode 100644 index 000000000..553170a15 --- /dev/null +++ b/src/boost/libs/metaparse/example/grammar_calculator/README @@ -0,0 +1,2 @@ +Calculator, working at compile-time. This example demonstrates how to build it +with grammars. diff --git a/src/boost/libs/metaparse/example/grammar_calculator/main.cpp b/src/boost/libs/metaparse/example/grammar_calculator/main.cpp new file mode 100644 index 000000000..95ca139c0 --- /dev/null +++ b/src/boost/libs/metaparse/example/grammar_calculator/main.cpp @@ -0,0 +1,160 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2011. +// Distributed under 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) + +#include <boost/config.hpp> + +#if BOOST_METAPARSE_STD < 2011 +#include <iostream> + +int main() +{ + std::cout << "Please use a compiler that supports constexpr" << std::endl; +} +#else + +#define BOOST_MPL_LIMIT_STRING_SIZE 64 +#define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE + +#include <boost/metaparse/grammar.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/build_parser.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/util/digit_to_int.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/lambda.hpp> +#include <boost/mpl/char.hpp> +#include <boost/mpl/int.hpp> + +using boost::metaparse::build_parser; +using boost::metaparse::entire_input; +using boost::metaparse::token; +using boost::metaparse::grammar; + +using boost::metaparse::util::digit_to_int; + +using boost::mpl::apply_wrap1; +using boost::mpl::fold; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::plus; +using boost::mpl::minus; +using boost::mpl::times; +using boost::mpl::divides; +using boost::mpl::eval_if; +using boost::mpl::equal_to; +using boost::mpl::_1; +using boost::mpl::_2; +using boost::mpl::char_; +using boost::mpl::lambda; +using boost::mpl::int_; + +#ifdef _STR + #error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +template <class A, class B> +struct lazy_plus : plus<typename A::type, typename B::type> {}; + +template <class A, class B> +struct lazy_minus : minus<typename A::type, typename B::type> {}; + +template <class A, class B> +struct lazy_times : times<typename A::type, typename B::type> {}; + +template <class A, class B> +struct lazy_divides : divides<typename A::type, typename B::type> {}; + +template <class C, class T, class F> +struct lazy_eval_if : eval_if<typename C::type, T, F> {}; + +template <class A, class B> +struct lazy_equal_to : equal_to<typename A::type, typename B::type> {}; + +template <class Sequence, class State, class ForwardOp> +struct lazy_fold : + fold<typename Sequence::type, typename State::type, typename ForwardOp::type> +{}; + +typedef + lazy_fold< + back<_1>, + front<_1>, + lambda< + lazy_eval_if< + lazy_equal_to<front<_2>, char_<'*'>>, + lazy_times<_1, back<_2>>, + lazy_divides<_1, back<_2>> + > + >::type + > + prod_action; + +typedef + lazy_fold< + back<_1>, + front<_1>, + lambda< + lazy_eval_if< + lazy_equal_to<front<_2>, char_<'+'>>, + lazy_plus<_1, back<_2>>, + lazy_minus<_1, back<_2>> + > + >::type + > + plus_action; + +typedef + lambda< + lazy_fold< + _1, + int_<0>, + lambda< + lazy_plus<lazy_times<_1, int_<10>>, apply_wrap1<digit_to_int<>, _2>> + >::type + > + >::type + int_action; + +typedef + grammar<_STR("plus_exp")> + + ::rule<_STR("int ::= ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')+"), int_action>::type + ::rule<_STR("ws ::= (' ' | '\n' | '\r' | '\t')*")>::type + ::rule<_STR("int_token ::= int ws"), front<_1>>::type + ::rule<_STR("plus_token ::= '+' ws"), front<_1>>::type + ::rule<_STR("minus_token ::= '-' ws"), front<_1>>::type + ::rule<_STR("mult_token ::= '*' ws"), front<_1>>::type + ::rule<_STR("div_token ::= '/' ws"), front<_1>>::type + ::rule<_STR("plus_token ::= '+' ws")>::type + ::rule<_STR("plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*"), plus_action>::type + ::rule<_STR("prod_exp ::= int_token ((mult_token | div_token) int_token)*"), prod_action>::type + expression; + +typedef build_parser<entire_input<expression>> calculator_parser; + +int main() +{ + using std::cout; + using std::endl; + + cout + << apply_wrap1<calculator_parser, _STR("13")>::type::value << endl + << apply_wrap1<calculator_parser, _STR("1+ 2*4-6/2")>::type::value << endl + ; +} +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/Jamfile.v2 b/src/boost/libs/metaparse/example/meta_hs/Jamfile.v2 new file mode 100644 index 000000000..84d5c3c12 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/Jamfile.v2 @@ -0,0 +1,11 @@ + +project meta_hs : + requirements + <include>. + <toolset>gcc:<cxxflags>-ftemplate-depth=512 + <toolset>clang:<cxxflags>-ftemplate-depth=512 + ; + +exe handcrafted : main_handcrafted.cpp ; +exe in_haskell : main_in_haskell.cpp ; + diff --git a/src/boost/libs/metaparse/example/meta_hs/README b/src/boost/libs/metaparse/example/meta_hs/README new file mode 100644 index 000000000..0afcc4eb8 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/README @@ -0,0 +1,4 @@ +Haskell-like functional EDSL for template metafunctions. +This example contains two programs. Both of them define and execute a few +template metaprograms. One of the do it by using Boost.MPL directly, while the +other one defines the template metaprograms using the EDSL. diff --git a/src/boost/libs/metaparse/example/meta_hs/ast.hpp b/src/boost/libs/metaparse/example/meta_hs/ast.hpp new file mode 100644 index 000000000..68f25eaf9 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/ast.hpp @@ -0,0 +1,43 @@ +#ifndef META_HS_AST_HPP +#define META_HS_AST_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +namespace ast +{ + template <class V> + struct value + { + typedef value type; + }; + + template <class Name> + struct ref + { + typedef ref type; + }; + + template <class F, class Arg> + struct application + { + typedef application type; + }; + + template <class F, class ArgName> + struct lambda + { + typedef lambda type; + }; + + template <class E> + struct top_bound + { + typedef top_bound type; + }; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/bind.hpp b/src/boost/libs/metaparse/example/meta_hs/bind.hpp new file mode 100644 index 000000000..29316084a --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/bind.hpp @@ -0,0 +1,63 @@ +#ifndef META_HS_BIND_HPP +#define META_HS_BIND_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <lazy.hpp> +#include <ast.hpp> + +#include <boost/mpl/at.hpp> +#include <boost/mpl/insert.hpp> +#include <boost/mpl/pair.hpp> + +template <class AST, class TopEnv, class Env> +struct bind; + +template <class V, class TopEnv, class Env> +struct bind<ast::value<V>, TopEnv, Env> +{ + typedef lazy::value<V> type; +}; + +template <class Name, class TopEnv, class Env> +struct bind<ast::ref<Name>, TopEnv, Env> : + bind<typename boost::mpl::at<Env, Name>::type, TopEnv, Env> +{}; + +template <class F, class Arg, class TopEnv, class Env> +struct bind<ast::application<F, Arg>, TopEnv, Env> +{ + typedef + lazy::application< + typename bind<F, TopEnv, Env>::type, + typename bind<Arg, TopEnv, Env>::type + > + type; +}; + +template <class F, class ArgName, class TopEnv, class Env> +struct bind<ast::lambda<F, ArgName>, TopEnv, Env> +{ + typedef bind type; + + template <class ArgValue> + struct apply : + bind< + F, + TopEnv, + typename boost::mpl::insert< + Env, + boost::mpl::pair<ArgName, ast::value<ArgValue> > + >::type + >::type + {}; +}; + +template <class E, class TopEnv, class Env> +struct bind<ast::top_bound<E>, TopEnv, Env> : bind<E, TopEnv, TopEnv> {}; + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/builder.hpp b/src/boost/libs/metaparse/example/meta_hs/builder.hpp new file mode 100644 index 000000000..b49a06a33 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/builder.hpp @@ -0,0 +1,80 @@ +#ifndef META_HS_EXCEPT_BUILDER_HPP +#define META_HS_EXCEPT_BUILDER_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <grammar.hpp> +#include <ast.hpp> +#include <bind.hpp> +#include <curry.hpp> + +#include <boost/mpl/map.hpp> +#include <boost/mpl/insert.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/pair.hpp> +#include <boost/mpl/apply_wrap.hpp> + +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/repetition/repeat_from_to.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +typedef boost::mpl::map<> empty_environment; + +template <class Env = empty_environment> +struct builder +{ + typedef builder type; + + template <class Name, class Value> + struct import : + builder< + typename boost::mpl::insert< + Env, + boost::mpl::pair<Name, ast::value<Value> > + >::type + > + {}; + +#ifdef IMPORT +# error IMPORT already defined +#endif +#define IMPORT(z, n, unused) \ + template < \ + class Name, \ + template <BOOST_PP_ENUM(n, class BOOST_PP_TUPLE_EAT(3), ~)> class F \ + > \ + struct BOOST_PP_CAT(import, n) : \ + builder< \ + typename boost::mpl::insert< \ + Env, \ + boost::mpl::pair<Name, ast::value<BOOST_PP_CAT(curry, n)<F> > > \ + >::type \ + > \ + {}; + +BOOST_PP_REPEAT_FROM_TO(1, CURRY_MAX_ARGUMENT, IMPORT, ~) + +#undef IMPORT + + template <class S> + struct define : + builder< + typename boost::mpl::insert< + Env, + typename boost::mpl::apply_wrap1<grammar::def_parser, S>::type + >::type + > + {}; + + template <class S> + struct get : + bind<typename boost::mpl::at<Env, S>::type, Env, Env>::type::type + {}; +}; + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/curry.hpp b/src/boost/libs/metaparse/example/meta_hs/curry.hpp new file mode 100644 index 000000000..5ca1711d3 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/curry.hpp @@ -0,0 +1,106 @@ +#ifndef BOOST_METAPARSE_META_HS_CURRY_HPP +#define BOOST_METAPARSE_META_HS_CURRY_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2010. +// Distributed under 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) + +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/apply.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/push_back.hpp> +#include <boost/mpl/unpack_args.hpp> +#include <boost/mpl/deque.hpp> +#include <boost/mpl/quote.hpp> + +#include <boost/preprocessor/repetition/repeat_from_to.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +#ifndef CURRY_MAX_ARGUMENT +# define CURRY_MAX_ARGUMENT 5 +#endif + +namespace impl +{ + template < + class UnpackedMetafunctionClass, + class ArgumentsLeft, + class ArgumentList + > + struct curry_impl; + + + + template < + class UnpackedMetafunctionClass, + class ArgumentsLeft, + class ArgumentList + > + struct next_currying_step + { + typedef next_currying_step type; + + template <class T> + struct apply : + curry_impl< + UnpackedMetafunctionClass, + typename boost::mpl::minus< + ArgumentsLeft, + boost::mpl::int_<1> + >::type, + typename boost::mpl::push_back<ArgumentList, T>::type + > + {}; + }; + + + template < + class UnpackedMetafunctionClass, + class ArgumentsLeft, + class ArgumentList + > + struct curry_impl : + boost::mpl::eval_if< + typename boost::mpl::equal_to< + ArgumentsLeft, + boost::mpl::int_<0> + >::type, + boost::mpl::apply<UnpackedMetafunctionClass, ArgumentList>, + next_currying_step< + UnpackedMetafunctionClass, + ArgumentsLeft, + ArgumentList + > + > + {}; +} + + +template <class T> +struct curry0 : T {}; + +#ifdef CURRY +# error CURRY already defined +#endif +#define CURRY(z, n, unused) \ + template <template <BOOST_PP_ENUM(n,class BOOST_PP_TUPLE_EAT(3),~)> class T> \ + struct BOOST_PP_CAT(curry, n) : \ + impl::curry_impl< \ + boost::mpl::unpack_args<boost::mpl::BOOST_PP_CAT(quote, n) <T> >, \ + boost::mpl::int_<n>, \ + boost::mpl::deque<> \ + >::type \ + {}; + +BOOST_PP_REPEAT_FROM_TO(1, CURRY_MAX_ARGUMENT, CURRY, ~) + +#undef CURRY + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/double_number.hpp b/src/boost/libs/metaparse/example/meta_hs/double_number.hpp new file mode 100644 index 000000000..03d338c8c --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/double_number.hpp @@ -0,0 +1,18 @@ +#ifndef DOUBLE_NUMBER_HPP +#define DOUBLE_NUMBER_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/mpl/int.hpp> +#include <boost/mpl/times.hpp> + +template <class N> +struct double_number : + boost::mpl::times<typename N::type, boost::mpl::int_<2> > +{}; + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/example_handcrafted.hpp b/src/boost/libs/metaparse/example/meta_hs/example_handcrafted.hpp new file mode 100644 index 000000000..b38441c93 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/example_handcrafted.hpp @@ -0,0 +1,93 @@ +#ifndef EXAMPLE_HANDCRAFTED_HPP +#define EXAMPLE_HANDCRAFTED_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <double_number.hpp> + +#include <boost/mpl/int.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/less.hpp> + +typedef boost::mpl::int_<11> val; + +struct fib +{ + typedef fib type; + + template <class N> + struct impl; + + template <class N> + struct apply : + boost::mpl::eval_if< + typename boost::mpl::less<N, boost::mpl::int_<2> >::type, + boost::mpl::int_<1>, + impl<N> + > + {}; +}; + +template <class N> +struct fib::impl : + boost::mpl::plus< + typename fib::apply< + typename boost::mpl::minus<N, boost::mpl::int_<1> >::type + >::type, + typename fib::apply< + typename boost::mpl::minus<N, boost::mpl::int_<2> >::type + >::type + > +{}; + +struct fact +{ + typedef fact type; + + template <class N> + struct impl; + + template <class N> + struct apply : + boost::mpl::eval_if< + typename boost::mpl::less<N, boost::mpl::int_<1> >::type, + boost::mpl::int_<1>, + impl<N> + > + {}; +}; + +template <class N> +struct fact::impl : + boost::mpl::times< + N, + typename fact::apply< + typename boost::mpl::minus<N, boost::mpl::int_<1> >::type + >::type + > +{}; + +struct times4 +{ + typedef times4 type; + + template <class N> + struct apply : double_number<typename double_number<N>::type> {}; +}; + +struct times11 +{ + typedef times11 type; + + template <class N> + struct apply : boost::mpl::times<N, val> {}; +}; + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/example_in_haskell.hpp b/src/boost/libs/metaparse/example/meta_hs/example_in_haskell.hpp new file mode 100644 index 000000000..7642eca6b --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/example_in_haskell.hpp @@ -0,0 +1,53 @@ +#ifndef EXAMPLE_IN_HASKELL_HPP +#define EXAMPLE_IN_HASKELL_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/config.hpp> + +#if BOOST_METAPARSE_STD < 2011 + +// We have to fall back on the handcrafted one +#include <example_handcrafted.hpp> + +#else + +#define BOOST_MPL_LIMIT_STRING_SIZE 50 +#define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE + +#include <meta_hs.hpp> +#include <double_number.hpp> + +#include <boost/metaparse/string.hpp> + +#include <boost/mpl/int.hpp> + +#ifdef _STR +# error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +typedef + meta_hs + ::import1<_STR("f"), double_number>::type + ::import<_STR("val"), boost::mpl::int_<11> >::type + + ::define<_STR("fib n = if n<2 then 1 else fib(n-2) + fib(n-1)")>::type + ::define<_STR("fact n = if n<1 then 1 else n * fact(n-1)")>::type + ::define<_STR("times4 n = f (f n)")>::type + ::define<_STR("times11 n = n * val")>::type + metafunctions; + +typedef metafunctions::get<_STR("fib")> fib; +typedef metafunctions::get<_STR("fact")> fact; +typedef metafunctions::get<_STR("times4")> times4; +typedef metafunctions::get<_STR("times11")> times11; + +#endif + +#endif + + diff --git a/src/boost/libs/metaparse/example/meta_hs/except_keywords.hpp b/src/boost/libs/metaparse/example/meta_hs/except_keywords.hpp new file mode 100644 index 000000000..b6700f008 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/except_keywords.hpp @@ -0,0 +1,61 @@ +#ifndef META_HS_EXCEPT_KEYWORDS_HPP +#define META_HS_EXCEPT_KEYWORDS_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/metaparse/accept_when.hpp> + +#include <boost/mpl/equal.hpp> +#include <boost/mpl/and.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/apply_wrap.hpp> + +struct keywords_are_not_allowed {}; + +template <class P, class Keywords> +class except_keywords +{ +private: + template <class T> + struct not_a_keyword + { + typedef not_a_keyword type; + + template <class Acc, class Keyword> + struct apply : + boost::mpl::and_< + Acc, + boost::mpl::not_<typename boost::mpl::equal<T, Keyword>::type> + > + {}; + }; + + struct not_keyword + { + typedef not_keyword type; + + template <class T> + struct apply : + boost::mpl::fold<Keywords, boost::mpl::true_, not_a_keyword<T> > + {}; + }; +public: + typedef except_keywords type; + + template <class S, class Pos> + struct apply : + boost::mpl::apply_wrap2< + boost::metaparse::accept_when<P, not_keyword, keywords_are_not_allowed>, + S, + Pos + > + {}; +}; + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/grammar.hpp b/src/boost/libs/metaparse/example/meta_hs/grammar.hpp new file mode 100644 index 000000000..e4bcf0b63 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/grammar.hpp @@ -0,0 +1,130 @@ +#ifndef META_HS_GRAMMAR_HPP +#define META_HS_GRAMMAR_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <token.hpp> +#include <semantic.hpp> + +#include <boost/metaparse/middle_of.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/foldr_start_with_parser.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/build_parser.hpp> + +namespace grammar +{ + /* + * The grammar + * + * definition ::= token::name+ token::define expression + * expression ::= cmp_exp + * cmp_exp ::= plus_exp (token::cmp plus_exp)* + * plus_exp ::= mult_exp ((token::plus | token::minus) mult_exp)* + * mult_exp ::= application ((token::mult | token::div) application)* + * application ::= single_exp+ + * single_exp ::= if_exp | token::name | token::int_ | bracket_exp + * if_exp ::= token::if_ expression token::then expression token::else_ expression + * bracket_exp ::= token::open_bracket expression token::close_bracket + */ + + struct expression; + + typedef + boost::metaparse::middle_of< + token::open_bracket, + expression, + token::close_bracket + > + bracket_exp; + + typedef + boost::metaparse::transform< + boost::metaparse::sequence< + boost::metaparse::last_of<token::if_, expression>, + boost::metaparse::last_of<token::then, expression>, + boost::metaparse::last_of<token::else_, expression> + >, + semantic::if_ + > + if_exp; + + typedef + boost::metaparse::one_of< + if_exp, + boost::metaparse::transform<token::name, semantic::ref>, + boost::metaparse::transform<token::int_, semantic::value>, + bracket_exp + > + single_exp; + + typedef + boost::metaparse::foldl_reject_incomplete_start_with_parser< + single_exp, + single_exp, + semantic::application + > + application; + + typedef + boost::metaparse::foldl_reject_incomplete_start_with_parser< + boost::metaparse::sequence< + boost::metaparse::one_of<token::mult, token::div>, + application + >, + application, + semantic::binary_op + > + mult_exp; + + typedef + boost::metaparse::foldl_reject_incomplete_start_with_parser< + boost::metaparse::sequence< + boost::metaparse::one_of<token::plus, token::minus>, + mult_exp + >, + mult_exp, + semantic::binary_op + > + plus_exp; + + typedef + boost::metaparse::foldl_reject_incomplete_start_with_parser< + boost::metaparse::sequence<token::cmp, plus_exp>, + plus_exp, + semantic::binary_op + > + cmp_exp; + + struct expression : cmp_exp {}; + + typedef + boost::metaparse::transform< + boost::metaparse::sequence< + token::name, + boost::metaparse::foldr_start_with_parser< + token::name, + boost::metaparse::last_of<token::define, expression>, + semantic::lambda + > + >, + semantic::pair + > + definition; + + typedef + boost::metaparse::build_parser< + boost::metaparse::entire_input<definition> + > + def_parser; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/lazy.hpp b/src/boost/libs/metaparse/example/meta_hs/lazy.hpp new file mode 100644 index 000000000..c3a3cf832 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/lazy.hpp @@ -0,0 +1,24 @@ +#ifndef META_HS_LAZY_HPP +#define META_HS_LAZY_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/mpl/apply_wrap.hpp> + +namespace lazy +{ + template <class V> + struct value + { + typedef V type; + }; + + template <class F, class Arg> + struct application : boost::mpl::apply_wrap1<typename F::type, Arg>::type {}; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/main_handcrafted.cpp b/src/boost/libs/metaparse/example/meta_hs/main_handcrafted.cpp new file mode 100644 index 000000000..33df728fa --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/main_handcrafted.cpp @@ -0,0 +1,20 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <example_handcrafted.hpp> + +#include <iostream> + +int main() +{ + using boost::mpl::int_; + + std::cout + << "fib 6 = " << fib::apply<int_<6> >::type::value << std::endl + << "fact 4 = " << fact::apply<int_<4> >::type::value << std::endl + << "times4 3 = " << times4::apply<int_<3> >::type::value << std::endl + << "times11 2 = " << times11::apply<int_<2> >::type::value << std::endl; +} + diff --git a/src/boost/libs/metaparse/example/meta_hs/main_in_haskell.cpp b/src/boost/libs/metaparse/example/meta_hs/main_in_haskell.cpp new file mode 100644 index 000000000..af10d9a8e --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/main_in_haskell.cpp @@ -0,0 +1,20 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <example_in_haskell.hpp> + +#include <iostream> + +int main() +{ + using boost::mpl::int_; + + std::cout + << "fib 6 = " << fib::apply<int_<6> >::type::value << std::endl + << "fact 4 = " << fact::apply<int_<4> >::type::value << std::endl + << "times4 3 = " << times4::apply<int_<3> >::type::value << std::endl + << "times11 2 = " << times11::apply<int_<2> >::type::value << std::endl; +} + diff --git a/src/boost/libs/metaparse/example/meta_hs/meta_hs.hpp b/src/boost/libs/metaparse/example/meta_hs/meta_hs.hpp new file mode 100644 index 000000000..061b442a7 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/meta_hs.hpp @@ -0,0 +1,64 @@ +#ifndef META_HS_META_HS_HPP +#define META_HS_META_HS_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <builder.hpp> + +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/less.hpp> +#include <boost/mpl/less_equal.hpp> +#include <boost/mpl/greater.hpp> +#include <boost/mpl/greater_equal.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/not_equal_to.hpp> + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/seq/for_each.hpp> + +#ifdef DEFINE_LAZY + #error DEFINE_LAZY already defined +#endif +#define DEFINE_LAZY(r, unused, name) \ + template <class A, class B> \ + struct BOOST_PP_CAT(lazy_, name) : \ + boost::mpl::name<typename A::type, typename B::type> \ + {}; + +BOOST_PP_SEQ_FOR_EACH(DEFINE_LAZY, ~, + (plus) + (minus) + (times) + (divides) + (less) + (less_equal) + (greater) + (greater_equal) + (equal_to) + (not_equal_to) +) + +#undef DEFINE_LAZY + +typedef builder<> + ::import2<boost::metaparse::string<'.','+','.'>, lazy_plus>::type + ::import2<boost::metaparse::string<'.','-','.'>, lazy_minus>::type + ::import2<boost::metaparse::string<'.','*','.'>, lazy_times>::type + ::import2<boost::metaparse::string<'.','/','.'>, lazy_divides>::type + ::import2<boost::metaparse::string<'.','<','.'>, lazy_less>::type + ::import2<boost::metaparse::string<'.','<','=','.'>, lazy_less_equal>::type + ::import2<boost::metaparse::string<'.','>','.'>, lazy_greater>::type + ::import2<boost::metaparse::string<'.','>','=','.'>, lazy_greater_equal>::type + ::import2<boost::metaparse::string<'.','=','=','.'>, lazy_equal_to>::type + ::import2<boost::metaparse::string<'.','/','=','.'>, lazy_not_equal_to>::type + + meta_hs; + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/semantic.hpp b/src/boost/libs/metaparse/example/meta_hs/semantic.hpp new file mode 100644 index 000000000..42ad42217 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/semantic.hpp @@ -0,0 +1,115 @@ +#ifndef META_HS_SEMANTIC_HPP +#define META_HS_SEMANTIC_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <ast.hpp> +#include <curry.hpp> + +#include <boost/mpl/if.hpp> +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/pair.hpp> + +namespace semantic +{ + struct ref + { + typedef ref type; + + template <class Name> + struct apply : ast::ref<Name> {}; + }; + + struct value + { + typedef value type; + + template <class V> + struct apply : ast::value<V> {}; + }; + + struct lambda + { + typedef lambda type; + + template <class F, class ArgName> + struct apply : ast::lambda<F, ArgName> {}; + }; + + struct application + { + typedef application type; + + template <class F, class Arg> + struct apply : ast::application<F, Arg> {}; + }; + + class if_ + { + private: + template <class C, class T, class F> + struct lazy_if : boost::mpl::if_<typename C::type, T, F> {}; + public: + typedef if_ type; + + template <class Seq> + struct apply : + boost::mpl::apply_wrap2< + application, + typename boost::mpl::apply_wrap2< + application, + typename boost::mpl::apply_wrap2< + application, + ast::value<curry3<lazy_if> >, + typename boost::mpl::at_c<Seq, 0>::type + >::type, + typename boost::mpl::at_c<Seq, 1>::type + >::type, + typename boost::mpl::at_c<Seq, 2>::type + > + {}; + }; + + struct binary_op + { + typedef binary_op type; + + template <class Exp, class C> + struct apply : + boost::mpl::apply_wrap2< + application, + typename boost::mpl::apply_wrap2< + application, + typename boost::mpl::apply_wrap1< + ref, + typename boost::mpl::front<C>::type + >::type, + Exp + >::type, + typename boost::mpl::back<C>::type + > + {}; + }; + + struct pair + { + typedef pair type; + + template <class Seq> + struct apply : + boost::mpl::pair< + typename boost::mpl::front<Seq>::type, + ast::top_bound<typename boost::mpl::back<Seq>::type> + > + {}; + }; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_hs/token.hpp b/src/boost/libs/metaparse/example/meta_hs/token.hpp new file mode 100644 index 000000000..23ec0bf79 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_hs/token.hpp @@ -0,0 +1,168 @@ +#ifndef META_HS_TOKEN_HPP +#define META_HS_TOKEN_HPP + +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <ast.hpp> +#include <except_keywords.hpp> + +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/always_c.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/return_.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/alphanum.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/letter.hpp> +#include <boost/metaparse/keyword.hpp> +#include <boost/metaparse/optional.hpp> + +#include <boost/mpl/lambda.hpp> +#include <boost/mpl/push_back.hpp> +#include <boost/mpl/vector.hpp> + +namespace token +{ + typedef + boost::metaparse::token< + boost::metaparse::always_c<'+',boost::metaparse::string<'.','+','.'> > + > + plus; + + typedef + boost::metaparse::token< + boost::metaparse::always_c<'-',boost::metaparse::string<'.','-','.'> > + > + minus; + + typedef + boost::metaparse::token< + boost::metaparse::always_c<'*',boost::metaparse::string<'.','*','.'> > + > + mult; + + typedef + boost::metaparse::token< + boost::metaparse::always_c<'/',boost::metaparse::string<'.','/','.'> > + > + div; + + typedef + boost::metaparse::token< + boost::metaparse::one_of< + boost::metaparse::last_of< + boost::metaparse::lit_c<'='>, + boost::metaparse::lit_c<'='>, + boost::metaparse::return_< + boost::metaparse::string<'.','=','=','.'> + > + >, + boost::metaparse::last_of< + boost::metaparse::lit_c<'/'>, + boost::metaparse::lit_c<'='>, + boost::metaparse::return_< + boost::metaparse::string<'.','/','=','.'> + > + >, + boost::metaparse::last_of< + boost::metaparse::lit_c<'<'>, + boost::metaparse::one_of< + boost::metaparse::always_c< + '=', + boost::metaparse::string<'.','<','=','.'> + >, + boost::metaparse::return_< + boost::metaparse::string<'.','<','.'> + > + > + >, + boost::metaparse::last_of< + boost::metaparse::lit_c<'>'>, + boost::metaparse::optional< + boost::metaparse::always_c< + '=', + boost::metaparse::string<'.','>','=','.'> + >, + boost::metaparse::string<'.','>','.'> + > + > + > + > + cmp; + + typedef + boost::metaparse::token<boost::metaparse::lit_c<'('> > + open_bracket; + + typedef + boost::metaparse::token<boost::metaparse::lit_c<')'> > + close_bracket; + + typedef + boost::metaparse::token<boost::metaparse::lit_c<'='> > + define; + + typedef boost::metaparse::token<boost::metaparse::int_> int_; + + typedef + boost::metaparse::token< + except_keywords< + boost::metaparse::foldl_reject_incomplete_start_with_parser< + boost::metaparse::one_of< + boost::metaparse::alphanum, + boost::metaparse::lit_c<'_'> + >, + boost::metaparse::transform< + boost::metaparse::one_of< + boost::metaparse::letter, + boost::metaparse::lit_c<'_'> + >, + boost::mpl::lambda< + boost::mpl::push_back< + boost::metaparse::string<>, + boost::mpl::_1 + > + >::type + >, + boost::mpl::lambda< + boost::mpl::push_back<boost::mpl::_1, boost::mpl::_2> + >::type + >, + boost::mpl::vector< + boost::metaparse::string<'i','f'>, + boost::metaparse::string<'t','h','e','n'>, + boost::metaparse::string<'e','l','s','e'> + > + > + > + name; + + typedef + boost::metaparse::token< + boost::metaparse::keyword<boost::metaparse::string<'i','f'> > + > + if_; + + typedef + boost::metaparse::token< + boost::metaparse::keyword<boost::metaparse::string<'t','h','e','n'> > + > + then; + + typedef + boost::metaparse::token< + boost::metaparse::keyword<boost::metaparse::string<'e','l','s','e'> > + > + else_; +} + +#endif + + diff --git a/src/boost/libs/metaparse/example/meta_lambda/Jamfile.v2 b/src/boost/libs/metaparse/example/meta_lambda/Jamfile.v2 new file mode 100644 index 000000000..fcaeae093 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_lambda/Jamfile.v2 @@ -0,0 +1 @@ +exe meta_lambda : main.cpp ; diff --git a/src/boost/libs/metaparse/example/meta_lambda/README b/src/boost/libs/metaparse/example/meta_lambda/README new file mode 100644 index 000000000..f55faff95 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_lambda/README @@ -0,0 +1 @@ +An example on how to compile an EDSL into a C++ template metaprogram. diff --git a/src/boost/libs/metaparse/example/meta_lambda/main.cpp b/src/boost/libs/metaparse/example/meta_lambda/main.cpp new file mode 100644 index 000000000..892e5756f --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_lambda/main.cpp @@ -0,0 +1,265 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/space.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/always.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/if.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::last_of; +using boost::metaparse::space; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::int_; +using boost::metaparse::foldl_reject_incomplete_start_with_parser; +using boost::metaparse::get_result; +using boost::metaparse::one_of; +using boost::metaparse::token; +using boost::metaparse::entire_input; +using boost::metaparse::transform; +using boost::metaparse::always; + +using boost::mpl::apply_wrap1; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::plus; +using boost::mpl::minus; +using boost::mpl::times; +using boost::mpl::divides; +using boost::mpl::if_; +using boost::mpl::bool_; +using boost::mpl::equal_to; + +/* + * The grammar + * + * expression ::= plus_exp + * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* + * prod_exp ::= value_exp ((mult_token | div_token) value_exp)* + * value_exp ::= int_token | '_' + */ + +typedef token<lit_c<'+'> > plus_token; +typedef token<lit_c<'-'> > minus_token; +typedef token<lit_c<'*'> > mult_token; +typedef token<lit_c<'/'> > div_token; + +typedef token<int_> int_token; +typedef token<lit_c<'_'> > arg_token; + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct build_plus +{ + template <class A, class B> + struct _plus + { + typedef _plus type; + + template <class T> + struct apply : + plus<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type> + {}; + }; + + template <class A, class B> + struct _minus + { + typedef _minus type; + + template <class T> + struct apply : + minus<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type> + {}; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '+'>::type, + _plus<State, typename back<C>::type>, + _minus<State, typename back<C>::type> + > + {}; +}; + +struct build_mult +{ + template <class A, class B> + struct _mult + { + typedef _mult type; + + template <class T> + struct apply : + times<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type> + {}; + }; + + template <class A, class B> + struct _div + { + typedef _div type; + + template <class T> + struct apply : + divides< + typename apply_wrap1<A, T>::type, + typename apply_wrap1<B, T>::type + > + {}; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '*'>::type, + _mult<State, typename back<C>::type>, + _div<State, typename back<C>::type> + > + {}; +}; + +class build_value +{ +private: + template <class V> + struct impl + { + typedef impl type; + + template <class T> + struct apply : V {}; + }; + +public: + typedef build_value type; + + template <class V> + struct apply : impl<typename V::type> {}; +}; + +struct arg +{ + typedef arg type; + + template <class T> + struct apply + { + typedef T type; + }; +}; + +typedef + one_of<transform<int_token, build_value>, always<arg_token, arg> > + value_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<mult_token, div_token>, value_exp>, + value_exp, + build_mult + > + prod_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, prod_exp>, + prod_exp, + build_plus + > + plus_exp; + +typedef last_of<repeated<space>, plus_exp> expression; + +typedef build_parser<entire_input<expression> > metafunction_parser; + +#if BOOST_METAPARSE_STD < 2011 + +template <class Exp> +struct meta_lambda : apply_wrap1<metafunction_parser, Exp> {}; + +int main() +{ + using std::cout; + using std::endl; + using boost::metaparse::string; + + typedef meta_lambda<string<'1','3'> >::type metafunction_class_1; + typedef meta_lambda<string<'2',' ','+',' ','3'> >::type metafunction_class_2; + typedef meta_lambda<string<'2',' ','*',' ','2'> >::type metafunction_class_3; + typedef + meta_lambda<string<' ','1','+',' ','2','*','4','-','6','/','2'> >::type + metafunction_class_4; + typedef meta_lambda<string<'2',' ','*',' ','_'> >::type metafunction_class_5; + + typedef boost::mpl::int_<11> int11; + + cout + << apply_wrap1<metafunction_class_1, int11>::type::value << endl + << apply_wrap1<metafunction_class_2, int11>::type::value << endl + << apply_wrap1<metafunction_class_3, int11>::type::value << endl + << apply_wrap1<metafunction_class_4, int11>::type::value << endl + << apply_wrap1<metafunction_class_5, int11>::type::value << endl + ; +} + +#else + +#ifdef META_LAMBDA + #error META_LAMBDA already defined +#endif +#define META_LAMBDA(exp) \ + apply_wrap1<metafunction_parser, BOOST_METAPARSE_STRING(#exp)>::type + +int main() +{ + using std::cout; + using std::endl; + + typedef META_LAMBDA(13) metafunction_class_1; + typedef META_LAMBDA(2 + 3) metafunction_class_2; + typedef META_LAMBDA(2 * 2) metafunction_class_3; + typedef META_LAMBDA( 1+ 2*4-6/2) metafunction_class_4; + typedef META_LAMBDA(2 * _) metafunction_class_5; + + typedef boost::mpl::int_<11> int11; + + cout + << apply_wrap1<metafunction_class_1, int11>::type::value << endl + << apply_wrap1<metafunction_class_2, int11>::type::value << endl + << apply_wrap1<metafunction_class_3, int11>::type::value << endl + << apply_wrap1<metafunction_class_4, int11>::type::value << endl + << apply_wrap1<metafunction_class_5, int11>::type::value << endl + ; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/meta_metaparse/Jamfile.v2 b/src/boost/libs/metaparse/example/meta_metaparse/Jamfile.v2 new file mode 100644 index 000000000..404a50065 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_metaparse/Jamfile.v2 @@ -0,0 +1,6 @@ +project : requirements + <toolset>gcc:<cxxflags>-ftemplate-depth=512 + <toolset>clang:<cxxflags>-ftemplate-depth=512 +; + +exe meta_metaparse : main.cpp ; diff --git a/src/boost/libs/metaparse/example/meta_metaparse/README b/src/boost/libs/metaparse/example/meta_metaparse/README new file mode 100644 index 000000000..a4d4a64b5 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_metaparse/README @@ -0,0 +1 @@ +This example demonstrates how to build an embedded DSL for Metaparse parsers. diff --git a/src/boost/libs/metaparse/example/meta_metaparse/main.cpp b/src/boost/libs/metaparse/example/meta_metaparse/main.cpp new file mode 100644 index 000000000..442549835 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_metaparse/main.cpp @@ -0,0 +1,258 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under 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) + +#define BOOST_MPL_LIMIT_STRING_SIZE 64 +#define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE + +#include <boost/metaparse/grammar.hpp> + +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/build_parser.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/transform.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/fold.hpp> + +using boost::mpl::apply_wrap1; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::if_; +using boost::mpl::bool_; + +using boost::metaparse::build_parser; +using boost::metaparse::token; +using boost::metaparse::entire_input; +using boost::metaparse::int_; +using boost::metaparse::grammar; +using boost::metaparse::transform; + +#if BOOST_METAPARSE_STD < 2011 +int main() +{ + std::cout << "Please use a compiler that supports constexpr" << std::endl; +} +#else + +#ifdef _STR +# error _STR already defined +#endif +#define _STR BOOST_METAPARSE_STRING + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct build_plus_impl +{ + template <class A, class B> + class _plus + { + public: + typedef _plus type; + + template <class T> + T operator()(T t) const + { + return _left(t) + _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class A, class B> + class _minus + { + public: + typedef _minus type; + + template <class T> + T operator()(T t) const + { + return _left(t) - _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '+'>::type, + _plus<State, typename back<C>::type>, + _minus<State, typename back<C>::type> + > + {}; +}; + +struct build_plus +{ + typedef build_plus type; + + template <class Seq> + struct apply : + boost::mpl::fold< + typename back<Seq>::type, + typename front<Seq>::type, + build_plus_impl + > + {}; +}; + +struct build_mult_impl +{ + template <class A, class B> + class _mult + { + public: + typedef _mult type; + + template <class T> + T operator()(T t) const + { + return _left(t) * _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class A, class B> + class _div + { + public: + typedef _div type; + + template <class T> + T operator()(T t) const + { + return _left(t) / _right(t); + } + private: + typename A::type _left; + typename B::type _right; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '*'>::type, + _mult<State, typename back<C>::type>, + _div<State, typename back<C>::type> + > + {}; +}; + +struct build_mult +{ + typedef build_mult type; + + template <class Seq> + struct apply : + boost::mpl::fold< + typename back<Seq>::type, + typename front<Seq>::type, + build_mult_impl + > + {}; +}; + +struct build_value +{ + typedef build_value type; + + template <class V> + struct apply + { + typedef apply type; + + template <class T> + int operator()(T) const + { + return V::type::value; + } + }; +}; + +struct build_arg +{ + typedef build_arg type; + + template <class> + struct apply + { + typedef apply type; + + template <class T> + T operator()(T t) const + { + return t; + } + }; +}; + +struct keep_front +{ + typedef keep_front type; + + template <class Seq> + struct apply : front<Seq> {}; +}; + +typedef + grammar<_STR("plus_exp")> + ::import<_STR("int_token"), token<transform<int_, build_value>>>::type + + ::rule<_STR("ws ::= (' ' | '\n' | '\r' | '\t')*")>::type + ::rule<_STR("plus_token ::= '+' ws"), keep_front>::type + ::rule<_STR("minus_token ::= '-' ws"), keep_front>::type + ::rule<_STR("mult_token ::= '*' ws"), keep_front>::type + ::rule<_STR("div_token ::= '/' ws"), keep_front>::type + ::rule<_STR("arg_token ::= '_' ws"), keep_front>::type + + ::rule<_STR("plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*"), build_plus>::type + ::rule<_STR("prod_exp ::= value_exp ((mult_token | div_token) value_exp)*"), build_mult>::type + ::rule<_STR("value_exp ::= int_token | arg_exp")>::type + ::rule<_STR("arg_exp ::= arg_token"), build_arg>::type + g; + +typedef build_parser<entire_input<g>> function_parser; + +#ifdef LAMBDA + #error LAMBDA already defined +#endif +#define LAMBDA(exp) apply_wrap1<function_parser, _STR(#exp)>::type + +LAMBDA(13) f1; +LAMBDA(2 + 3) f2; +LAMBDA(2 * 3) f3; +LAMBDA(1+ 2*4-6/2) f4; +LAMBDA(2 * _) f5; + +int main() +{ + using std::cout; + using std::endl; + + cout + << f1(11) << endl + << f2(11) << endl + << f3(11) << endl + << f4(11) << endl + << f5(11) << endl + << f5(1.1) << endl + ; +} + +#endif + + diff --git a/src/boost/libs/metaparse/example/minimal_rational/Jamfile.v2 b/src/boost/libs/metaparse/example/minimal_rational/Jamfile.v2 new file mode 100644 index 000000000..6f9000d56 --- /dev/null +++ b/src/boost/libs/metaparse/example/minimal_rational/Jamfile.v2 @@ -0,0 +1 @@ +exe minimal_rational : main.cpp ; diff --git a/src/boost/libs/metaparse/example/minimal_rational/README b/src/boost/libs/metaparse/example/minimal_rational/README new file mode 100644 index 000000000..6444e01d6 --- /dev/null +++ b/src/boost/libs/metaparse/example/minimal_rational/README @@ -0,0 +1,3 @@ +Parser for rational numbers. The aim is to present a very simple parser, +therefore error messages for invalid input can be improved. To see a more +advanced version, take a look at the rational example. diff --git a/src/boost/libs/metaparse/example/minimal_rational/main.cpp b/src/boost/libs/metaparse/example/minimal_rational/main.cpp new file mode 100644 index 000000000..3d6fd3ff6 --- /dev/null +++ b/src/boost/libs/metaparse/example/minimal_rational/main.cpp @@ -0,0 +1,79 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2015. +// Distributed under 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) + +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/sequence_apply.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/rational.hpp> + +#include <boost/config.hpp> + +#include <iostream> + +using boost::metaparse::sequence_apply2; +using boost::metaparse::last_of; +using boost::metaparse::int_; +using boost::metaparse::token; +using boost::metaparse::lit_c; +using boost::metaparse::entire_input; +using boost::metaparse::build_parser; + +template <class Num, class Denom> +struct rational +{ + typedef rational type; + + static boost::rational<int> run() + { + return boost::rational<int>(Num::type::value, Denom::type::value); + } +}; + +typedef + sequence_apply2< + rational, + + token<int_>, + last_of<lit_c<'/'>, token<int_> > + > + rational_grammar; + +typedef build_parser<entire_input<rational_grammar> > rational_parser; + +#ifdef RATIONAL +# error RATIONAL already defined +#endif +#define RATIONAL(s) \ + (::rational_parser::apply<BOOST_METAPARSE_STRING(s)>::type::run()) + +#if BOOST_METAPARSE_STD < 2011 + +int main() +{ + std::cout << "Please use a compiler that supports constexpr" << std::endl; +} + +#else + +int main() +{ + const boost::rational<int> r1 = RATIONAL("1/3"); + const boost::rational<int> r2 = RATIONAL("4/4"); + const boost::rational<int> r3 = RATIONAL("13/11"); + + std::cout + << r1 << std::endl + << r2 << std::endl + << r3 << std::endl; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/parsing_error/Jamfile.v2 b/src/boost/libs/metaparse/example/parsing_error/Jamfile.v2 new file mode 100644 index 000000000..c69580b84 --- /dev/null +++ b/src/boost/libs/metaparse/example/parsing_error/Jamfile.v2 @@ -0,0 +1 @@ +exe parsing_error : main.cpp ; diff --git a/src/boost/libs/metaparse/example/parsing_error/README b/src/boost/libs/metaparse/example/parsing_error/README new file mode 100644 index 000000000..6d7cc00d6 --- /dev/null +++ b/src/boost/libs/metaparse/example/parsing_error/README @@ -0,0 +1,17 @@ +This example shows how a compile-time parsing error can be debugged. +The commented code fails to compile and on some platforms the error report might +be difficult to understand. This example demonstrates how debug_parsing_error +can be used to get a user friendly error report about such thing. You need to +run the compiled code to get the error message: + +Compile-time parsing results +---------------------------- +Input text: +aaac + +Parsing failed: +line 1, col 4: Expected: b + +The col and line information refers to the location of the error in the string +literal. + diff --git a/src/boost/libs/metaparse/example/parsing_error/main.cpp b/src/boost/libs/metaparse/example/parsing_error/main.cpp new file mode 100644 index 000000000..4a1695519 --- /dev/null +++ b/src/boost/libs/metaparse/example/parsing_error/main.cpp @@ -0,0 +1,51 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2011. +// Distributed under 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) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/debug_parsing_error.hpp> + +#include <boost/metaparse/build_parser.hpp> +#include <boost/metaparse/string.hpp> + +#include <boost/mpl/apply.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::debug_parsing_error; + +using boost::mpl::apply; + +/* + * The grammar + * + * s ::= a*b + */ +typedef sequence<repeated<lit_c<'a'> >, lit_c<'b'> > s; + +typedef build_parser<s> test_parser; + +#if BOOST_METAPARSE_STD < 2011 + +typedef boost::metaparse::string<'a','a','a','c'> invalid_input; + +#else + +typedef BOOST_METAPARSE_STRING("aaac") invalid_input; + +#endif + +debug_parsing_error<test_parser, invalid_input> debug; + +int main() +{ + // This causes an error + // apply<test_parser, invalid_input>::type(); +} + + diff --git a/src/boost/libs/metaparse/example/rational/Jamfile.v2 b/src/boost/libs/metaparse/example/rational/Jamfile.v2 new file mode 100644 index 000000000..91886f701 --- /dev/null +++ b/src/boost/libs/metaparse/example/rational/Jamfile.v2 @@ -0,0 +1 @@ +exe rational : main.cpp ; diff --git a/src/boost/libs/metaparse/example/rational/README b/src/boost/libs/metaparse/example/rational/README new file mode 100644 index 000000000..72e9225f6 --- /dev/null +++ b/src/boost/libs/metaparse/example/rational/README @@ -0,0 +1 @@ +Parser for rational numbers. diff --git a/src/boost/libs/metaparse/example/rational/main.cpp b/src/boost/libs/metaparse/example/rational/main.cpp new file mode 100644 index 000000000..2de195222 --- /dev/null +++ b/src/boost/libs/metaparse/example/rational/main.cpp @@ -0,0 +1,97 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2015. +// Distributed under 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) + +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/sequence_apply.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/empty.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/rational.hpp> + +#include <boost/config.hpp> + +#include <boost/mpl/int.hpp> + +#include <iostream> + +using boost::metaparse::sequence_apply2; +using boost::metaparse::last_of; +using boost::metaparse::int_; +using boost::metaparse::token; +using boost::metaparse::lit_c; +using boost::metaparse::one_of; +using boost::metaparse::empty; +using boost::metaparse::entire_input; +using boost::metaparse::build_parser; + +template <class Num, class Denom> +struct rational +{ + typedef rational type; + + static boost::rational<int> run() + { + return boost::rational<int>(Num::type::value, Denom::type::value); + } +}; + +typedef + sequence_apply2< + rational, + + token<int_>, + one_of< + last_of<lit_c<'/'>, token<int_> >, + empty<boost::mpl::int_<1> > + > + > + rational_grammar; + +typedef build_parser<entire_input<rational_grammar> > rational_parser; + +#ifdef RATIONAL +# error RATIONAL already defined +#endif +#define RATIONAL(s) \ + (::rational_parser::apply<BOOST_METAPARSE_STRING(s)>::type::run()) + +#if BOOST_METAPARSE_STD < 2011 + +int main() +{ + std::cout << "Please use a compiler that supports constexpr" << std::endl; +} + +#else + +int main() +{ + const boost::rational<int> r1 = RATIONAL("1/3"); + const boost::rational<int> r2 = RATIONAL("4/4"); + const boost::rational<int> r3 = RATIONAL("1"); + const boost::rational<int> r4 = RATIONAL("13/11"); + + // Uncommenting the following line generates a compilation error. On a + // number of platforms the error report contains the following (or something + // similar): + // x__________________PARSING_FAILED__________________x<1, 3, digit_expected> + // where 1, 3 is the location of the error inside the string literal. +// const boost::rational<int> r5 = RATIONAL("7/"); + + std::cout + << r1 << std::endl + << r2 << std::endl + << r3 << std::endl + << r4 << std::endl; +} + +#endif + diff --git a/src/boost/libs/metaparse/example/regexp/Jamfile.v2 b/src/boost/libs/metaparse/example/regexp/Jamfile.v2 new file mode 100644 index 000000000..6650684fb --- /dev/null +++ b/src/boost/libs/metaparse/example/regexp/Jamfile.v2 @@ -0,0 +1 @@ +exe regexp : main.cpp ; diff --git a/src/boost/libs/metaparse/example/regexp/README b/src/boost/libs/metaparse/example/regexp/README new file mode 100644 index 000000000..57b68c848 --- /dev/null +++ b/src/boost/libs/metaparse/example/regexp/README @@ -0,0 +1,7 @@ +This example provides an interface in front of boost::xpressive. +A regular expression can be specified by a compile-time string +which is parsed (and verified) at compile-time. A boost::xpressive +object is constructed at runtime based on it. +This is just an example, it supports only a subset of the capabilities +of boost::xpressive. + diff --git a/src/boost/libs/metaparse/example/regexp/main.cpp b/src/boost/libs/metaparse/example/regexp/main.cpp new file mode 100644 index 000000000..cb8b8ab30 --- /dev/null +++ b/src/boost/libs/metaparse/example/regexp/main.cpp @@ -0,0 +1,158 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2011. +// Distributed under 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) + +#include <boost/metaparse/foldl_reject_incomplete.hpp> +#include <boost/metaparse/foldl_reject_incomplete1.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/one_char_except_c.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/always_c.hpp> +#include <boost/metaparse/build_parser.hpp> +#include <boost/metaparse/middle_of.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> + +#include <boost/detail/iterator.hpp> +#include <boost/xpressive/xpressive.hpp> + +#include <boost/mpl/bool.hpp> +#include <boost/mpl/string.hpp> + +using boost::metaparse::foldl_reject_incomplete; +using boost::metaparse::foldl_reject_incomplete1; +using boost::metaparse::lit_c; +using boost::metaparse::transform; +using boost::metaparse::build_parser; +using boost::metaparse::one_of; +using boost::metaparse::always_c; +using boost::metaparse::middle_of; +using boost::metaparse::one_char_except_c; +using boost::metaparse::entire_input; + +using boost::mpl::c_str; +using boost::mpl::true_; +using boost::mpl::false_; + +using boost::xpressive::sregex; +using boost::xpressive::as_xpr; + +/* + * Results of parsing + */ + +template <class T> +struct has_value +{ + typedef T type; + static const sregex value; +}; + +template <class T> +const sregex has_value<T>::value = T::run(); + +struct r_epsilon : has_value<r_epsilon> +{ + static sregex run() + { + return as_xpr(""); + } +}; + +struct r_any_char : has_value<r_any_char> +{ + static sregex run() + { + return boost::xpressive::_; + } +}; + +struct r_char_lit +{ + template <class C> + struct apply : has_value<apply<C> > + { + static sregex run() + { + return as_xpr(C::type::value); + } + }; +}; + +struct r_append +{ + template <class A, class B> + struct apply : has_value<apply<B, A> > + { + static sregex run() + { + return A::type::run() >> B::type::run(); + } + }; +}; + +/* + * The grammar + * + * regexp ::= (bracket_expr | non_bracket_expr)* + * non_bracket_expr ::= '.' | char_lit + * bracket_expr ::= '(' regexp ')' + * char_lit ::= any character except: . ( ) + */ + +typedef + foldl_reject_incomplete1< + one_of< + always_c<'.', r_any_char>, + transform<one_char_except_c<'.', '(', ')'>, r_char_lit> + >, + r_epsilon, + r_append + > + non_bracket_expr; + +typedef middle_of<lit_c<'('>, non_bracket_expr, lit_c<')'> > bracket_expr; + +typedef + foldl_reject_incomplete< + one_of<bracket_expr, non_bracket_expr>, + r_epsilon, + r_append + > + regexp; + +typedef build_parser<entire_input<regexp> > regexp_parser; + +void test_string(const std::string& s) +{ + using boost::xpressive::regex_match; + using boost::xpressive::smatch; + using boost::mpl::apply_wrap1; + + using std::cout; + using std::endl; + +#if BOOST_METAPARSE_STD < 2011 + typedef boost::metaparse::string<'.','(','b','c',')'> regexp; +#else + typedef BOOST_METAPARSE_STRING(".(bc)") regexp; +#endif + + const sregex re = apply_wrap1<regexp_parser, regexp>::type::value; + smatch w; + + cout + << s << (regex_match(s, w, re) ? " matches " : " doesn't match ") + << c_str<regexp>::type::value + << endl; +} + +int main() +{ + test_string("abc"); + test_string("aba"); +} + + |