Skip to content

Instantly share code, notes, and snippets.

@jamboree
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamboree/11133291 to your computer and use it in GitHub Desktop.
Save jamboree/11133291 to your computer and use it in GitHub Desktop.
replacement of boost/spirit/home/x3/nonterminal/grammar.hpp
/*=============================================================================
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)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_GRAMMAR_JAN_19_2012_0454PM)
#define BOOST_SPIRIT_X3_GRAMMAR_JAN_19_2012_0454PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/nonterminal/grammar.hpp>
#include <boost/fusion/support/pair.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/config.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename First, typename... Rest>
struct rule_map : First, Rest...
{
typedef typename First::second_type start_rule;
rule_map(First&& f, Rest&&... rs)
: First(std::move(f)), Rest(std::move(rs))...
{}
template <typename ID, typename T>
static T const& get_impl(fusion::pair<ID, T> const& pair)
{
return pair.second;
}
template <typename ID, typename T>
static mpl::true_ has_impl(fusion::pair<ID, T> const&);
template <typename ID>
static mpl::false_ has_impl(...);
template <typename ID>
auto get(mpl::identity<ID>) const->decltype(get_impl<ID>(*this))
{
return get_impl<ID>(*this);
}
template <typename ID>
auto has(mpl::identity<ID>) const->decltype(has_impl<ID>(*this))
{
return decltype(has_impl<ID>(*this))();
}
start_rule const& start() const
{
return First::second;
}
};
}}}}
namespace boost { namespace spirit { namespace x3
{
template <typename Elements, typename Next>
struct grammar_context
{
Elements const& elements;
Next const& next;
grammar_context(Elements const& elements, Next const& next)
: elements(elements), next(next) {}
template <typename ID>
struct get_result
{
typedef decltype(declval<grammar_context>().get(declval<ID>())) type;
};
template <typename ID>
auto get_impl(ID id, mpl::true_) const->decltype(elements.get(id))
{
return elements.get(id);
}
template <typename ID>
auto get_impl(ID id, mpl::false_) const->decltype(next.get(id))
{
return next.get(id);
}
template <typename ID>
auto get(ID id) const->decltype(this->get_impl(id, elements.has(id)))
{
return get_impl(id, elements.has(id));
}
};
template <typename... Elements>
struct grammar_parser : parser<grammar_parser<Elements...>>
{
typedef
detail::rule_map<fusion::pair<typename Elements::id, Elements>...>
rule_map;
typedef typename rule_map::start_rule start_rule;
grammar_parser(char const* name, Elements const&... elements)
: name(name)
, elements(fusion::pair<typename Elements::id, Elements>(elements)...)
{}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute_& attr) const
{
grammar_context<rule_map, Context> our_context(elements, context);
return elements.start().parse(first, last, our_context, attr);
}
char const* name;
rule_map elements;
};
template <typename... Elements>
grammar_parser<Elements...>
grammar(char const* name, Elements const&... elements)
{
return {name, elements...};
}
template <typename... Elements>
struct get_info<grammar_parser<Elements...>>
{
typedef std::string result_type;
std::string operator()(grammar_parser<Elements...> const& p) const
{
return p.name;
}
};
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename... Elements, typename Context>
struct attribute_of<x3::grammar_parser<Elements...>, Context>
: attribute_of<
typename x3::grammar_parser<Elements...>::start_rule, Context> {};
template <typename... Elements, typename Context>
struct has_attribute<x3::grammar_parser<Elements...>, Context>
: has_attribute<
typename x3::grammar_parser<Elements...>::start_rule, Context> {};
}}}}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment