diff options
Diffstat (limited to 'src/boost/libs/spirit/workbench/x3')
-rw-r--r-- | src/boost/libs/spirit/workbench/x3/context.cpp | 51 | ||||
-rw-r--r-- | src/boost/libs/spirit/workbench/x3/toy/toy.cpp | 247 |
2 files changed, 298 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/workbench/x3/context.cpp b/src/boost/libs/spirit/workbench/x3/context.cpp new file mode 100644 index 00000000..b7fa5637 --- /dev/null +++ b/src/boost/libs/spirit/workbench/x3/context.cpp @@ -0,0 +1,51 @@ +/*============================================================================= + Copyright (c) 2001-2013 Joel de Guzman + + 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/spirit/home/x3/support/context.hpp> +#include <iostream> + +using boost::spirit::x3::make_context; +using boost::spirit::x3::get; + +int bb; +int cc; + +struct b_ctx; +struct c_ctx; + +template <typename Context> +void a(Context const& context) +{ + bb = get<b_ctx>(context); + cc = get<c_ctx>(context); +} + +template <typename Context> +void b(Context const& context) +{ + int bi = 123; + a(make_context<b_ctx>(bi, context)); +} + +void c() +{ + int ci = 456; + b(make_context<c_ctx>(ci)); +} + +void test() +{ + c(); + +// MSVC generates this code: +// mov DWORD PTR ?bb@@3HA, 123 +// mov DWORD PTR ?cc@@3HA, 456 +// +// GCC generates this code: +// movl $123, _bb +// movl $456, _cc +} + diff --git a/src/boost/libs/spirit/workbench/x3/toy/toy.cpp b/src/boost/libs/spirit/workbench/x3/toy/toy.cpp new file mode 100644 index 00000000..dc0d8801 --- /dev/null +++ b/src/boost/libs/spirit/workbench/x3/toy/toy.cpp @@ -0,0 +1,247 @@ +#include <iostream> +#include <utility> +#include <cstring> +#include <boost/mpl/identity.hpp> + +namespace boost { namespace spirit { namespace x3 +{ + template <typename Derived> + struct parser + { + Derived const& derived() const + { + return *static_cast<Derived const*>(this); + } + }; + + template <typename Char> + struct char_parser : parser<char_parser<Char>> + { + char_parser(Char ch) : ch(ch) {} + + template <typename Iterator, typename Context> + bool parse(Iterator& first, Iterator last, Context const& ctx) const + { + if (first != last && *first == ch) + { + ++first; + return true; + } + return false; + } + + Char ch; + }; + + template <typename Char> + inline char_parser<Char> char_(Char ch) + { + return char_parser<Char>(ch); + }; + + template <typename Left, typename Right> + struct sequence_parser : parser<sequence_parser<Left, Right>> + { + sequence_parser(Left left, Right right) + : left(left), right(right) {} + + template <typename Iterator, typename Context> + bool parse(Iterator& first, Iterator last, Context const& ctx) const + { + return left.parse(first, last, ctx) + && right.parse(first, last, ctx); + } + + Left left; + Right right; + }; + + template <typename Left, typename Right> + inline sequence_parser<Left, Right> operator>>( + parser<Left> const& left, parser<Right> const& right) + { + return sequence_parser<Left, Right>( + left.derived(), right.derived()); + } + + template <typename Left, typename Right> + struct alternative_parser : parser<alternative_parser<Left, Right>> + { + alternative_parser(Left left, Right right) + : left(left), right(right) {} + + template <typename Iterator, typename Context> + bool parse(Iterator& first, Iterator last, Context const& ctx) const + { + if (left.parse(first, last, ctx)) + return true; + return right.parse(first, last, ctx); + } + + Left left; + Right right; + }; + + template <typename Left, typename Right> + inline alternative_parser<Left, Right> operator|( + parser<Left> const& left, parser<Right> const& right) + { + return alternative_parser<Left, Right>( + left.derived(), right.derived()); + } + + template <typename ID, typename T, typename NextContext> + struct context + { + context(T const& val, NextContext const& next_ctx) + : val(val), next_ctx(next_ctx) {} + + T const& get(mpl::identity<ID>) const + { + return val; + } + + template <typename Identity> + decltype(std::declval<NextContext>().get(Identity())) + get(Identity id) const + { + return next_ctx.get(id); + } + + T const& val; + NextContext const& next_ctx; + }; + + struct empty_context + { + struct undefined {}; + template <typename ID> + undefined get(ID) const + { + return undefined(); + } + }; + + template <typename ID, typename RHS> + struct rule_definition : parser<rule_definition<ID, RHS>> + { + rule_definition(RHS rhs) + : rhs(rhs) {} + + template <typename Iterator, typename Context> + bool parse(Iterator& first, Iterator last, Context const& ctx) const + { + context<ID, RHS, Context> this_ctx(rhs, ctx); + return rhs.parse(first, last, this_ctx); + } + + RHS rhs; + }; + + template <typename ID> + struct rule : parser<rule<ID>> + { + template <typename Derived> + rule_definition<ID, Derived> + operator=(parser<Derived> const& definition) const + { + return rule_definition<ID, Derived>(definition.derived()); + } + + template <typename Iterator, typename Context> + bool parse(Iterator& first, Iterator last, Context const& ctx) const + { + return ctx.get(mpl::identity<ID>()).parse(first, last, ctx); + } + }; + + template <typename Iterator, typename Derived> + inline bool parse(parser<Derived> const& p, Iterator& first, Iterator last) + { + empty_context ctx; + return p.derived().parse(first, last, ctx); + } + +}}} + +/////////////////////////////////////////////////////////////////////////////// +// test code + +template <typename Parser> +bool test_parse(Parser const& p, char const* in) +{ + return parse(p, in, in + std::strlen(in)); +} + +namespace parser +{ + using namespace boost::spirit::x3; + + namespace g_definition + { + auto const x = rule<class x>(); + auto const ax = char_('a') >> x; + + auto const g = + x = char_('x') | ax; + } + using g_definition::g; +} + +int main() +{ + + { // a non-recursive parser + using namespace boost::spirit::x3; + + auto abc = char_('a') >> char_('b') >> char_('c'); + std::cout << test_parse(abc, "abc") << std::endl; + std::cout << test_parse(abc, "abx") << std::endl; + std::cout << "==========================================" << std::endl; + } + + { // a recursive rule + using namespace boost::spirit::x3; + + auto const x = rule<class x>(); + auto const ax = char_('a') >> x; + auto const start = (x = char_('x') | ax); + + std::cout << test_parse(start, "x") << std::endl; + std::cout << test_parse(start, "ax") << std::endl; + std::cout << test_parse(start, "aaaaax") << std::endl; + std::cout << test_parse(start, "aaz") << std::endl; + std::cout << "==========================================" << std::endl; + } + + { // a grammar ( gcc and clang only: see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3582.html ) + + using namespace boost::spirit::x3; + auto g = []() + { + rule<class x> x; + auto ax = char_('a') >> x; + return x = char_('x') | ax; + + }(); + + std::cout << test_parse(g, "x") << std::endl; + std::cout << test_parse(g, "ax") << std::endl; + std::cout << test_parse(g, "aaaaax") << std::endl; + std::cout << test_parse(g, "aaz") << std::endl; + std::cout << "==========================================" << std::endl; + } + + { // another grammar using namespaces (standard c++, see grammar g definition above in namespace parser.) + using parser::g; + + std::cout << test_parse(g, "x") << std::endl; + std::cout << test_parse(g, "ax") << std::endl; + std::cout << test_parse(g, "aaaaax") << std::endl; + std::cout << test_parse(g, "aaz") << std::endl; + std::cout << "==========================================" << std::endl; + } + + return 0; +} + |