diff options
author | Kevin Smith <git@kismith.co.uk> | 2013-01-12 18:41:34 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2013-01-13 10:36:26 (GMT) |
commit | f3bc816af1b0d61452de973963e453bf3b3f95a2 (patch) | |
tree | e895f8afa3580e6cff6f5ad2017d45bf147a17c2 /3rdParty/Boost/src/boost/spirit/home/lex | |
parent | 188fc285c6555eadd3c9d50ab8a94adcade78d89 (diff) | |
download | swift-f3bc816af1b0d61452de973963e453bf3b3f95a2.zip swift-f3bc816af1b0d61452de973963e453bf3b3f95a2.tar.bz2 |
Adding in the spirit Boost stuff
Change-Id: I4f127ce61667243b64081b0aa309028d5077045f
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/lex')
36 files changed, 6754 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/argument.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/argument.hpp new file mode 100644 index 0000000..edfee0b --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/argument.hpp @@ -0,0 +1,362 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2010 Bryce Lelbach +// Copyright (c) 2011 Thomas Heller +// +// 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_LEX_ARGUMENT_JUNE_07_2009_1106AM) +#define BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/home/support/string_traits.hpp> +#include <boost/spirit/home/lex/argument_phoenix.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/remove_reference.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // The state_getter is a Phoenix actor used to access the name of the + // current lexer state by calling get_state_name() on the context (which + // is the 5th parameter to any lexer semantic actions). + // + // This Phoenix actor is invoked whenever the placeholder '_state' is used + // as a rvalue inside a lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier [ std::cout << _state ]; + // + // The example shows how to print the lexer state after matching a token + // 'identifier'. + struct state_getter + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c<typename Env::args_type, 4>::type + >::type + >::type + context_type; + + typedef typename context_type::state_name_type type; + }; + + template <typename Env> + typename result<Env>::type + eval(Env const& env) const + { + return fusion::at_c<4>(env.args()).get_state_name(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // The state_setter is a Phoenix actor used to change the name of the + // current lexer state by calling set_state_name() on the context (which + // is the 5th parameter to any lexer semantic actions). + // + // This Phoenix actor is invoked whenever the placeholder '_state' is used + // as a lvalue inside a lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier [ _state = "SOME_LEXER_STATE" ]; + // + // The example shows how to change the lexer state after matching a token + // 'identifier'. + template <typename Actor> + struct state_setter + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef void type; + }; + + template <typename Env> + void eval(Env const& env) const + { + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c<typename Env::args_type, 4>::type + >::type + >::type + context_type; + + typedef typename context_type::state_name_type string; + + fusion::at_c<4>(env.args()).set_state_name( + traits::get_c_string(actor_.eval(env))); + } + + state_setter(Actor const& actor) + : actor_(actor) {} + + // see explanation for this constructor at the end of this file +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + state_setter(phoenix::actor<state_getter>, Actor const& actor) + : actor_(actor) {} +#endif + + Actor actor_; + }; + + /////////////////////////////////////////////////////////////////////////// + // The value_getter is used to create the _val placeholder, which is a + // Phoenix actor used to access the value of the current token. + // + // This Phoenix actor is invoked whenever the placeholder '_val' is used + // as a rvalue inside a lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier [ std::cout << _val ]; + // + // The example shows how to use _val to print the identifier name (which + // is the initial token value). + struct value_getter + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c<typename Env::args_type, 4>::type + >::type + >::type + context_type; + + typedef typename context_type::get_value_type type; + }; + + template <typename Env> + typename result<Env>::type + eval(Env const& env) const + { + return fusion::at_c<4>(env.args()).get_value(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // The value_setter is a Phoenix actor used to change the name of the + // current lexer state by calling set_state_name() on the context (which + // is the 5th parameter to any lexer semantic actions). + // + // This Phoenix actor is invoked whenever the placeholder '_val' is used + // as a lvalue inside a lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier [ _val = "identifier" ]; + // + // The example shows how to change the token value after matching a token + // 'identifier'. + template <typename Actor> + struct value_setter + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef void type; + }; + + template <typename Env> + void eval(Env const& env) const + { + fusion::at_c<4>(env.args()).set_value(actor_.eval(env)); + } + + value_setter(Actor const& actor) + : actor_(actor) {} + +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + // see explanation for this constructor at the end of this file + value_setter(phoenix::actor<value_getter>, Actor const& actor) + : actor_(actor) {} +#endif + + Actor actor_; + }; + + /////////////////////////////////////////////////////////////////////////// + // The eoi_getter is used to create the _eoi placeholder, which is a + // Phoenix actor used to access the end of input iterator pointing to the + // end of the underlying input sequence. + // + // This actor is invoked whenever the placeholder '_eoi' is used in a + // lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier + // [ std::cout << construct_<std::string>(_end, _eoi) ]; + // + // The example shows how to use _eoi to print all remaining input after + // matching a token 'identifier'. + struct eoi_getter + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef + typename remove_reference< + typename remove_const< + typename mpl::at_c<typename Env::args_type, 4>::type + >::type + >::type + context_type; + + typedef typename context_type::base_iterator_type const& type; + }; + + template <typename Env> + typename result<Env>::type + eval(Env const& env) const + { + return fusion::at_c<4>(env.args()).get_eoi(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // '_start' and '_end' may be used to access the start and the end of + // the matched sequence of the current token + typedef phoenix::arg_names::_1_type _start_type; + typedef phoenix::arg_names::_2_type _end_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + _start_type const _start = _start_type(); + _end_type const _end = _end_type(); +#endif + + // We are reusing the placeholder '_pass' to access and change the pass + // status of the current match (see support/argument.hpp for its + // definition). + // typedef phoenix::arg_names::_3_type _pass_type; + using boost::spirit::_pass_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using boost::spirit::_pass; +#endif + + // '_tokenid' may be used to access and change the tokenid of the current + // token + typedef phoenix::arg_names::_4_type _tokenid_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + _tokenid_type const _tokenid = _tokenid_type(); +#endif + + typedef phoenix::actor<value_context> _val_type; + typedef phoenix::actor<state_context> _state_type; + typedef phoenix::actor<eoi_getter> _eoi_type; +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + // '_val' may be used to access and change the token value of the current + // token + _val_type const _val = _val_type(); + // _state may be used to access and change the name of the current lexer + // state + _state_type const _state = _state_type(); + // '_eoi' may be used to access the end of input iterator of the input + // stream used by the lexer to match tokens from + _eoi_type const _eoi = _eoi_type(); +#endif +}}} + +/////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 +namespace boost { namespace phoenix +{ + /////////////////////////////////////////////////////////////////////////// + // The specialization of as_actor_base<> below is needed to convert all + // occurrences of _state in places where it's used as a rvalue into the + // proper Phoenix actor (spirit::state_getter) accessing the lexer state. + template<> + struct as_actor_base<actor<spirit::lex::state_context> > + { + typedef spirit::lex::state_getter type; + + static spirit::lex::state_getter + convert(actor<spirit::lex::state_context>) + { + return spirit::lex::state_getter(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // The specialization of as_composite<> below is needed to convert all + // assignments to _state (places where it's used as a lvalue) into the + // proper Phoenix actor (spirit::state_setter) allowing to change the + // lexer state. + template <typename RHS> + struct as_composite<assign_eval, actor<spirit::lex::state_context>, RHS> + { + // For an assignment to _state (a spirit::state_context actor), this + // specialization makes Phoenix's compose() function construct a + // spirit::state_setter actor from 1. the LHS, a spirit::state_getter + // actor (due to the specialization of as_actor_base<> above), + // and 2. the RHS actor. + // This is why spirit::state_setter needs a constructor which takes + // a dummy spirit::state_getter as its first argument in addition + // to its real, second argument (the RHS actor). + typedef spirit::lex::state_setter<typename as_actor<RHS>::type> type; + }; + + /////////////////////////////////////////////////////////////////////////// + // The specialization of as_actor_base<> below is needed to convert all + // occurrences of _val in places where it's used as a rvalue into the + // proper Phoenix actor (spirit::value_getter) accessing the token value. + template<> + struct as_actor_base<actor<spirit::lex::value_context> > + { + typedef spirit::lex::value_getter type; + + static spirit::lex::value_getter + convert(actor<spirit::lex::value_context>) + { + return spirit::lex::value_getter(); + } + }; + + /////////////////////////////////////////////////////////////////////////// + // The specialization of as_composite<> below is needed to convert all + // assignments to _val (places where it's used as a lvalue) into the + // proper Phoenix actor (spirit::value_setter) allowing to change the + // token value. + template <typename RHS> + struct as_composite<assign_eval, actor<spirit::lex::value_context>, RHS> + { + // For an assignment to _val (a spirit::value_context actor), this + // specialization makes Phoenix's compose() function construct a + // spirit::value_setter actor from 1. the LHS, a spirit::value_getter + // actor (due to the specialization of as_actor_base<> above), + // and 2. the RHS actor. + // This is why spirit::value_setter needs a constructor which takes + // a dummy spirit::value_getter as its first argument in addition + // to its real, second argument (the RHS actor). + typedef spirit::lex::value_setter<typename as_actor<RHS>::type> type; + }; +}} +#endif + +#undef SPIRIT_DECLARE_ARG +#endif + diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/argument_phoenix.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/argument_phoenix.hpp new file mode 100644 index 0000000..da24503 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/argument_phoenix.hpp @@ -0,0 +1,251 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Thomas Heller +// +// 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_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM) +#define BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/include/phoenix_core.hpp> + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // The value_context is used as a noop Phoenix actor to create the + // placeholder '_val' (see below). It is a noop actor because it is used + // as a placeholder only, while it is being converted either to a + // value_getter (if used as a rvalue) or to a value_setter (if used as a + // lvalue). The conversion is achieved by specializing and overloading a + // couple of the Phoenix templates from the Phoenix expression composition + // engine (see the end of this file). + struct value_context + { + typedef mpl::true_ no_nullary; + + typedef unused_type result_type; + + template <typename Env> + struct result + { + typedef unused_type type; + }; + + template <typename Env> + unused_type + eval(Env const& env) const + { + return unused; + } + }; + + // forward declarations + struct value_getter; + template <typename> struct value_setter; + + /////////////////////////////////////////////////////////////////////////// + // The state_context is used as a noop Phoenix actor to create the + // placeholder '_state' (see below). It is a noop actor because it is used + // as a placeholder only, while it is being converted either to a + // state_getter (if used as a rvalue) or to a state_setter (if used as a + // lvalue). The conversion is achieved by specializing and overloading a + // couple of the Phoenix templates from the Phoenix expression composition + // engine (see the end of this file). + struct state_context + { + typedef mpl::true_ no_nullary; + + typedef unused_type result_type; + + template <typename Env> + struct result + { + typedef unused_type type; + }; + + template <typename Env> + unused_type + eval(Env const& env) const + { + return unused; + } + }; + + // forward declarations + struct state_getter; + template <typename> struct state_setter; + struct eoi_getter; +}}} + +/////////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_SPIRIT_USE_PHOENIX_V3 + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(value_setter) + , (boost::phoenix::meta_grammar) +) + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(state_setter) + , (boost::phoenix::meta_grammar) +) + +namespace boost { namespace phoenix +{ + namespace result_of + { + template <> + struct is_nullary<custom_terminal<boost::spirit::lex::value_context> > + : mpl::false_ + {}; + } + + template <typename Dummy> + struct is_custom_terminal<boost::spirit::lex::value_context, Dummy>: mpl::true_ {}; + + template <typename Dummy> + struct custom_terminal<boost::spirit::lex::value_context, Dummy> + : proto::call< + v2_eval( + proto::make<boost::spirit::lex::value_getter()> + , proto::call<functional::env(proto::_state)> + ) + > + {}; + + template <typename Dummy> + struct is_nullary::when<spirit::lex::rule::value_setter, Dummy> + : proto::make<mpl::false_()> + {}; + + template <typename Dummy> + struct default_actions::when<spirit::lex::rule::value_setter, Dummy> + : proto::call< + v2_eval( + proto::make< + spirit::lex::value_setter<proto::_child0>( + proto::_child0 + ) + > + , _env + ) + > + {}; + + template <> + struct actor<spirit::lex::value_context> + : boost::phoenix::actor<proto::terminal<spirit::lex::value_context>::type> + { + typedef boost::phoenix::actor< + proto::terminal<spirit::lex::value_context>::type + > base_type; + + actor(base_type const & base = base_type()) + : base_type(base) + {} + + template <typename Expr> + typename spirit::lex::expression::value_setter< + typename phoenix::as_actor<Expr>::type>::type const + operator=(Expr const & expr) const + { + return + spirit::lex::expression::value_setter< + typename phoenix::as_actor<Expr>::type + >::make(phoenix::as_actor<Expr>::convert(expr)); + } + }; + + namespace result_of + { + template <> + struct is_nullary<custom_terminal<boost::spirit::lex::state_context> > + : mpl::false_ + {}; + } + + template <typename Dummy> + struct is_custom_terminal<boost::spirit::lex::state_context, Dummy>: mpl::true_ {}; + + template <typename Dummy> + struct custom_terminal<boost::spirit::lex::state_context, Dummy> + : proto::call< + v2_eval( + proto::make<boost::spirit::lex::state_getter()> + , proto::call<functional::env(proto::_state)> + ) + > + {}; + + template <typename Dummy> + struct is_nullary::when<spirit::lex::rule::state_setter, Dummy> + : proto::make<mpl::false_()> + {}; + + template <typename Dummy> + struct default_actions::when<spirit::lex::rule::state_setter, Dummy> + : proto::call< + v2_eval( + proto::make< + spirit::lex::state_setter<proto::_child0>( + proto::_child0 + ) + > + , _env + ) + > + {}; + + template <> + struct actor<spirit::lex::state_context> + : boost::phoenix::actor<proto::terminal<spirit::lex::state_context>::type> + { + typedef boost::phoenix::actor< + proto::terminal<spirit::lex::state_context>::type + > base_type; + + actor(base_type const & base = base_type()) + : base_type(base) + {} + + template <typename Expr> + typename spirit::lex::expression::state_setter< + typename phoenix::as_actor<Expr>::type>::type const + operator=(Expr const & expr) const + { + return + spirit::lex::expression::state_setter< + typename phoenix::as_actor<Expr>::type + >::make(phoenix::as_actor<Expr>::convert(expr)); + } + }; + + namespace result_of + { + template <> + struct is_nullary<custom_terminal<boost::spirit::lex::eoi_getter> > + : mpl::false_ + {}; + } + + template <typename Dummy> + struct is_custom_terminal<boost::spirit::lex::eoi_getter, Dummy>: mpl::true_ {}; + + template <typename Dummy> + struct custom_terminal<boost::spirit::lex::eoi_getter, Dummy> + : proto::call< + v2_eval( + proto::make<boost::spirit::lex::eoi_getter()> + , proto::call<functional::env(proto::_state)> + ) + > + {}; +}} + +#endif // BOOST_SPIRIT_USE_PHOENIX_V3 + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/detail/sequence_function.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/detail/sequence_function.hpp new file mode 100644 index 0000000..0f52da8 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/detail/sequence_function.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_SEQUENCE_FUNCTION_FEB_28_2007_0249PM) +#define BOOST_SPIRIT_LEX_SEQUENCE_FUNCTION_FEB_28_2007_0249PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/domain.hpp> +#include <boost/spirit/home/support/unused.hpp> + +namespace boost { namespace spirit { namespace lex { namespace detail +{ + template <typename LexerDef, typename String> + struct sequence_collect_function + { + sequence_collect_function(LexerDef& def_, String const& state_ + , String const& targetstate_) + : def(def_), state(state_), targetstate(targetstate_) {} + + template <typename Component> + bool operator()(Component const& component) const + { + component.collect(def, state, targetstate); + return false; // execute for all sequence elements + } + + LexerDef& def; + String const& state; + String const& targetstate; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + sequence_collect_function& operator= (sequence_collect_function const&); + }; + + template <typename LexerDef> + struct sequence_add_actions_function + { + sequence_add_actions_function(LexerDef& def_) + : def(def_) {} + + template <typename Component> + bool operator()(Component const& component) const + { + component.add_actions(def); + return false; // execute for all sequence elements + } + + LexerDef& def; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + sequence_add_actions_function& operator= (sequence_add_actions_function const&); + }; + +}}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/domain.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/domain.hpp new file mode 100644 index 0000000..e5aec86 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/domain.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_DOMAIN_MAR_13_2007_0140PM) +#define BOOST_SPIRIT_LEX_DOMAIN_MAR_13_2007_0140PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/unused.hpp> +#include <boost/spirit/home/support/meta_compiler.hpp> +#include <boost/spirit/home/support/info.hpp> + +namespace boost { namespace spirit { namespace lex +{ + // lex's domain + struct domain {}; + + // bring in some of spirit parts into spirit::lex + using spirit::unused; + using spirit::unused_type; + using spirit::compile; + using spirit::info; + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer.hpp new file mode 100644 index 0000000..535ec28 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer.hpp @@ -0,0 +1,21 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEXER_MAR_22_2007_1008PM) +#define BOOST_SPIRIT_LEXER_MAR_22_2007_1008PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/lexer/terminals.hpp> +#include <boost/spirit/home/lex/lexer/token_def.hpp> +#include <boost/spirit/home/lex/lexer/char_token_def.hpp> +#include <boost/spirit/home/lex/lexer/string_token_def.hpp> +#include <boost/spirit/home/lex/lexer/sequence.hpp> +#include <boost/spirit/home/lex/lexer/action.hpp> +#include <boost/spirit/home/lex/lexer/lexer.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/action.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/action.hpp new file mode 100644 index 0000000..8de0c87 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/action.hpp @@ -0,0 +1,97 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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(SPIRIT_LEX_ACTION_NOV_18_2007_0743PM) +#define SPIRIT_LEX_ACTION_NOV_18_2007_0743PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/meta_compiler.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/lex/argument.hpp> +#include <boost/spirit/home/lex/lexer/support_functions.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/is_same.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Subject, typename Action> + struct action : unary_lexer<action<Subject, Action> > + { + action(Subject const& subject, Action f) + : subject(subject), f(f) {} + + template <typename LexerDef, typename String> + void collect(LexerDef& lexdef, String const& state + , String const& targetstate) const + { + // collect the token definition information for the token_def + // this action is attached to + subject.collect(lexdef, state, targetstate); + } + + template <typename LexerDef> + void add_actions(LexerDef& lexdef) const + { + // call to add all actions attached further down the hierarchy + subject.add_actions(lexdef); + + // retrieve the id of the associated token_def and register the + // given semantic action with the lexer instance + lexdef.add_action(subject.unique_id(), subject.state(), f); + } + + Subject subject; + Action f; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + action& operator= (action const&); + }; + +}}} + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Karma action meta-compiler + template <> + struct make_component<lex::domain, tag::action> + { + template <typename Sig> + struct result; + + template <typename This, typename Elements, typename Modifiers> + struct result<This(Elements, Modifiers)> + { + typedef typename + remove_const<typename Elements::car_type>::type + subject_type; + + typedef typename + remove_const<typename Elements::cdr_type::car_type>::type + action_type; + + typedef lex::action<subject_type, action_type> type; + }; + + template <typename Elements> + typename result<make_component(Elements, unused_type)>::type + operator()(Elements const& elements, unused_type) const + { + typename result<make_component(Elements, unused_type)>::type + result(elements.car, elements.cdr.car); + return result; + } + }; +}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/char_token_def.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/char_token_def.hpp new file mode 100644 index 0000000..aaba2e1 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/char_token_def.hpp @@ -0,0 +1,242 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_CHAR_TOKEN_DEF_MAR_28_2007_0626PM) +#define BOOST_SPIRIT_LEX_CHAR_TOKEN_DEF_MAR_28_2007_0626PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/string_traits.hpp> +#include <boost/spirit/home/lex/domain.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/lex/meta_compiler.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables 'x' + template <> + struct use_terminal<lex::domain, char> + : mpl::true_ {}; + + // enables "x" + template <> + struct use_terminal<lex::domain, char[2]> + : mpl::true_ {}; + + // enables wchar_t + template <> + struct use_terminal<lex::domain, wchar_t> + : mpl::true_ {}; + + // enables L"x" + template <> + struct use_terminal<lex::domain, wchar_t[2]> + : mpl::true_ {}; + + // enables char_('x'), char_("x") + template <typename CharEncoding, typename A0> + struct use_terminal<lex::domain + , terminal_ex< + tag::char_code<tag::char_, CharEncoding> + , fusion::vector1<A0> > > + : mpl::true_ {}; + + // enables char_('x', ID), char_("x", ID) + template <typename CharEncoding, typename A0, typename A1> + struct use_terminal<lex::domain + , terminal_ex< + tag::char_code<tag::char_, CharEncoding> + , fusion::vector2<A0, A1> > > + : mpl::true_ {}; +}} + +namespace boost { namespace spirit { namespace lex +{ + // use char_ from standard character set by default +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::standard::char_; +#endif + using spirit::standard::char_type; + + /////////////////////////////////////////////////////////////////////////// + // + // char_token_def + // represents a single character token definition + // + /////////////////////////////////////////////////////////////////////////// + template <typename CharEncoding = char_encoding::standard + , typename IdType = std::size_t> + struct char_token_def + : primitive_lexer<char_token_def<CharEncoding, IdType> > + { + typedef typename CharEncoding::char_type char_type; + + char_token_def(char_type ch, IdType const& id) + : ch(ch), id_(id), unique_id_(std::size_t(~0)) + , token_state_(std::size_t(~0)) + {} + + template <typename LexerDef, typename String> + void collect(LexerDef& lexdef, String const& state + , String const& targetstate) const + { + std::size_t state_id = lexdef.add_state(state.c_str()); + + // If the following assertion fires you are probably trying to use + // a single char_token_def instance in more than one lexer state. + // This is not possible. Please create a separate token_def instance + // from the same regular expression for each lexer state it needs + // to be associated with. + BOOST_ASSERT( + (std::size_t(~0) == token_state_ || state_id == token_state_) && + "Can't use single char_token_def with more than one lexer state"); + + char_type const* target = targetstate.empty() ? 0 : targetstate.c_str(); + if (target) + lexdef.add_state(target); + + token_state_ = state_id; + unique_id_ = lexdef.add_token (state.c_str(), ch, id_, target); + } + + template <typename LexerDef> + void add_actions(LexerDef&) const {} + + IdType id() const { return id_; } + std::size_t unique_id() const { return unique_id_; } + std::size_t state() const { return token_state_; } + + char_type ch; + mutable IdType id_; + mutable std::size_t unique_id_; + mutable std::size_t token_state_; + }; + + /////////////////////////////////////////////////////////////////////////// + // Lexer generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + template <typename CharEncoding> + struct basic_literal + { + typedef char_token_def<CharEncoding> result_type; + + template <typename Char> + result_type operator()(Char ch, unused_type) const + { + return result_type(ch, ch); + } + + template <typename Char> + result_type operator()(Char const* str, unused_type) const + { + return result_type(str[0], str[0]); + } + }; + } + + // literals: 'x', "x" + template <typename Modifiers> + struct make_primitive<char, Modifiers> + : detail::basic_literal<char_encoding::standard> {}; + + template <typename Modifiers> + struct make_primitive<char const(&)[2], Modifiers> + : detail::basic_literal<char_encoding::standard> {}; + + // literals: L'x', L"x" + template <typename Modifiers> + struct make_primitive<wchar_t, Modifiers> + : detail::basic_literal<char_encoding::standard_wide> {}; + + template <typename Modifiers> + struct make_primitive<wchar_t const(&)[2], Modifiers> + : detail::basic_literal<char_encoding::standard_wide> {}; + + // handle char_('x') + template <typename CharEncoding, typename Modifiers, typename A0> + struct make_primitive< + terminal_ex< + tag::char_code<tag::char_, CharEncoding> + , fusion::vector1<A0> + > + , Modifiers> + { + typedef char_token_def<CharEncoding> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args), fusion::at_c<0>(term.args)); + } + }; + + // handle char_("x") + template <typename CharEncoding, typename Modifiers, typename Char> + struct make_primitive< + terminal_ex< + tag::char_code<tag::char_, CharEncoding> + , fusion::vector1<Char(&)[2]> // single char strings + > + , Modifiers> + { + typedef char_token_def<CharEncoding> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + Char ch = fusion::at_c<0>(term.args)[0]; + return result_type(ch, ch); + } + }; + + // handle char_('x', ID) + template <typename CharEncoding, typename Modifiers, typename A0, typename A1> + struct make_primitive< + terminal_ex< + tag::char_code<tag::char_, CharEncoding> + , fusion::vector2<A0, A1> + > + , Modifiers> + { + typedef char_token_def<CharEncoding> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type( + fusion::at_c<0>(term.args), fusion::at_c<1>(term.args)); + } + }; + + // handle char_("x", ID) + template <typename CharEncoding, typename Modifiers, typename Char, typename A1> + struct make_primitive< + terminal_ex< + tag::char_code<tag::char_, CharEncoding> + , fusion::vector2<Char(&)[2], A1> // single char strings + > + , Modifiers> + { + typedef char_token_def<CharEncoding> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type( + fusion::at_c<0>(term.args)[0], fusion::at_c<1>(term.args)); + } + }; +}}} // namespace boost::spirit::lex + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexer.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexer.hpp new file mode 100644 index 0000000..93412ce --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexer.hpp @@ -0,0 +1,405 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXER_MAR_13_2007_0145PM) +#define BOOST_SPIRIT_LEX_LEXER_MAR_13_2007_0145PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/spirit/home/lex/reference.hpp> +#include <boost/spirit/home/lex/meta_compiler.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/lex/lexer/token_def.hpp> +#include <boost/assert.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/iterator.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/range/iterator_range.hpp> +#include <string> + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + /////////////////////////////////////////////////////////////////////// + template <typename LexerDef> + struct lexer_def_ + : proto::extends< + typename proto::terminal< + lex::reference<lexer_def_<LexerDef> const> + >::type + , lexer_def_<LexerDef> > + , qi::parser<lexer_def_<LexerDef> > + , lex::lexer_type<lexer_def_<LexerDef> > + { + private: + // avoid warnings about using 'this' in constructor + lexer_def_& this_() { return *this; } + + typedef typename LexerDef::char_type char_type; + typedef typename LexerDef::string_type string_type; + typedef typename LexerDef::id_type id_type; + + typedef lex::reference<lexer_def_ const> reference_; + typedef typename proto::terminal<reference_>::type terminal_type; + typedef proto::extends<terminal_type, lexer_def_> proto_base_type; + + reference_ alias() const + { + return reference_(*this); + } + + public: + // Qi interface: metafunction calculating parser attribute type + template <typename Context, typename Iterator> + struct attribute + { + // the return value of a token set contains the matched token + // id, and the corresponding pair of iterators + typedef typename Iterator::base_iterator_type iterator_type; + typedef + fusion::vector2<id_type, iterator_range<iterator_type> > + type; + }; + + // Qi interface: parse functionality + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + + token_type const& t = *first; + if (token_is_valid(t) && t.state() == first.get_state()) { + // any of the token definitions matched + spirit::traits::assign_to(t, attr); + ++first; + return true; + } + } + return false; + } + + // Qi interface: 'what' functionality + template <typename Context> + info what(Context& /*context*/) const + { + return info("lexer"); + } + + private: + // allow to use the lexer.self.add("regex1", id1)("regex2", id2); + // syntax + struct adder + { + adder(lexer_def_& def_) + : def(def_) {} + + // Add a token definition based on a single character as given + // by the first parameter, the second parameter allows to + // specify the token id to use for the new token. If no token + // id is given the character code is used. + adder const& operator()(char_type c + , id_type token_id = id_type()) const + { + if (id_type() == token_id) + token_id = static_cast<id_type>(c); + def.def.add_token (def.state.c_str(), c, token_id + , def.targetstate.empty() ? 0 : def.targetstate.c_str()); + return *this; + } + + // Add a token definition based on a character sequence as + // given by the first parameter, the second parameter allows to + // specify the token id to use for the new token. If no token + // id is given this function will generate a unique id to be + // used as the token's id. + adder const& operator()(string_type const& s + , id_type token_id = id_type()) const + { + if (id_type() == token_id) + token_id = def.def.get_next_id(); + def.def.add_token (def.state.c_str(), s, token_id + , def.targetstate.empty() ? 0 : def.targetstate.c_str()); + return *this; + } + + template <typename Attribute> + adder const& operator()( + token_def<Attribute, char_type, id_type>& tokdef + , id_type token_id = id_type()) const + { + // make sure we have a token id + if (id_type() == token_id) { + if (id_type() == tokdef.id()) { + token_id = def.def.get_next_id(); + tokdef.id(token_id); + } + else { + token_id = tokdef.id(); + } + } + else { + // the following assertion makes sure that the token_def + // instance has not been assigned a different id earlier + BOOST_ASSERT(id_type() == tokdef.id() + || token_id == tokdef.id()); + tokdef.id(token_id); + } + + def.define(tokdef); + return *this; + } + +// template <typename F> +// adder const& operator()(char_type c, id_type token_id, F act) const +// { +// if (id_type() == token_id) +// token_id = def.def.get_next_id(); +// std::size_t unique_id = +// def.def.add_token (def.state.c_str(), s, token_id); +// def.def.add_action(unique_id, def.state.c_str(), act); +// return *this; +// } + + lexer_def_& def; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + adder& operator= (adder const&); + }; + friend struct adder; + + // allow to use lexer.self.add_pattern("pattern1", "regex1")(...); + // syntax + struct pattern_adder + { + pattern_adder(lexer_def_& def_) + : def(def_) {} + + pattern_adder const& operator()(string_type const& p + , string_type const& s) const + { + def.def.add_pattern (def.state.c_str(), p, s); + return *this; + } + + lexer_def_& def; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + pattern_adder& operator= (pattern_adder const&); + }; + friend struct pattern_adder; + + private: + // Helper function to invoke the necessary 2 step compilation + // process on token definition expressions + template <typename TokenExpr> + void compile2pass(TokenExpr const& expr) + { + expr.collect(def, state, targetstate); + expr.add_actions(def); + } + + public: + /////////////////////////////////////////////////////////////////// + template <typename Expr> + void define(Expr const& expr) + { + compile2pass(compile<lex::domain>(expr)); + } + + lexer_def_(LexerDef& def_, string_type const& state_ + , string_type const& targetstate_ = string_type()) + : proto_base_type(terminal_type::make(alias())) + , add(this_()), add_pattern(this_()), def(def_) + , state(state_), targetstate(targetstate_) + {} + + // allow to switch states + lexer_def_ operator()(char_type const* state) const + { + return lexer_def_(def, state); + } + lexer_def_ operator()(char_type const* state + , char_type const* targetstate) const + { + return lexer_def_(def, state, targetstate); + } + lexer_def_ operator()(string_type const& state + , string_type const& targetstate = string_type()) const + { + return lexer_def_(def, state, targetstate); + } + + // allow to assign a token definition expression + template <typename Expr> + lexer_def_& operator= (Expr const& xpr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit lex + // expression. + BOOST_SPIRIT_ASSERT_MATCH(lex::domain, Expr); + + def.clear(state.c_str()); + define(xpr); + return *this; + } + + // explicitly tell the lexer that the given state will be defined + // (useful in conjunction with "*") + std::size_t add_state(char_type const* state = 0) + { + return def.add_state(state ? state : def.initial_state().c_str()); + } + + adder add; + pattern_adder add_pattern; + + private: + LexerDef& def; + string_type state; + string_type targetstate; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + lexer_def_& operator= (lexer_def_ const&); + }; + +#if defined(BOOST_NO_RVALUE_REFERENCES) + // allow to assign a token definition expression + template <typename LexerDef, typename Expr> + inline lexer_def_<LexerDef>& + operator+= (lexer_def_<LexerDef>& lexdef, Expr& xpr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit lex + // expression. + BOOST_SPIRIT_ASSERT_MATCH(lex::domain, Expr); + + lexdef.define(xpr); + return lexdef; + } +#else + // allow to assign a token definition expression + template <typename LexerDef, typename Expr> + inline lexer_def_<LexerDef>& + operator+= (lexer_def_<LexerDef>& lexdef, Expr&& xpr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit lex + // expression. + BOOST_SPIRIT_ASSERT_MATCH(lex::domain, Expr); + + lexdef.define(xpr); + return lexdef; + } +#endif + + template <typename LexerDef, typename Expr> + inline lexer_def_<LexerDef>& + operator+= (lexer_def_<LexerDef>& lexdef, Expr const& xpr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit lex + // expression. + BOOST_SPIRIT_ASSERT_MATCH(lex::domain, Expr); + + lexdef.define(xpr); + return lexdef; + } + } + + /////////////////////////////////////////////////////////////////////////// + // The match_flags flags are used to influence different matching + // modes of the lexer + struct match_flags + { + enum enum_type + { + match_default = 0, // no flags + match_not_dot_newline = 1, // the regex '.' doesn't match newlines + match_icase = 2 // all matching operations are case insensitive + }; + }; + + /////////////////////////////////////////////////////////////////////////// + // This represents a lexer object + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // This is the first token id automatically assigned by the library + // if needed + enum tokenids + { + min_token_id = 0x10000 + }; + + template <typename Lexer> + class lexer : public Lexer + { + private: + // avoid warnings about using 'this' in constructor + lexer& this_() { return *this; } + + std::size_t next_token_id; // has to be an integral type + + public: + typedef Lexer lexer_type; + typedef typename Lexer::id_type id_type; + typedef typename Lexer::char_type char_type; + typedef typename Lexer::iterator_type iterator_type; + typedef lexer base_type; + + typedef detail::lexer_def_<lexer> lexer_def; + typedef std::basic_string<char_type> string_type; + + lexer(unsigned int flags = match_flags::match_default + , id_type first_id = id_type(min_token_id)) + : lexer_type(flags) + , next_token_id(first_id) + , self(this_(), lexer_type::initial_state()) + {} + + // access iterator interface + template <typename Iterator> + iterator_type begin(Iterator& first, Iterator const& last + , char_type const* initial_state = 0) const + { return this->lexer_type::begin(first, last, initial_state); } + iterator_type end() const + { return this->lexer_type::end(); } + + std::size_t map_state(char_type const* state) + { return this->lexer_type::add_state(state); } + + // create a unique token id + id_type get_next_id() { return id_type(next_token_id++); } + + lexer_def self; // allow for easy token definition + }; + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/functor.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/functor.hpp new file mode 100644 index 0000000..79e5f07 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/functor.hpp @@ -0,0 +1,300 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXER_FUNCTOR_NOV_18_2007_1112PM) +#define BOOST_SPIRIT_LEX_LEXER_FUNCTOR_NOV_18_2007_1112PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/mpl/bool.hpp> +#include <boost/detail/iterator.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/spirit/home/lex/lexer/pass_flags.hpp> +#include <boost/assert.hpp> + +#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) +#define BOOST_SPIRIT_STATIC_EOF 1 +#define BOOST_SPIRIT_EOF_PREFIX static +#else +#define BOOST_SPIRIT_EOF_PREFIX +#endif + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + /////////////////////////////////////////////////////////////////////////// + // + // functor is a template usable as the functor object for the + // multi_pass iterator allowing to wrap a lexertl based dfa into a + // iterator based interface. + // + // Token: the type of the tokens produced by this functor + // this needs to expose a constructor with the following + // prototype: + // + // Token(std::size_t id, std::size_t state, + // Iterator start, Iterator end) + // + // where 'id' is the token id, state is the lexer state, + // this token has been matched in, and 'first' and 'end' + // mark the start and the end of the token with respect + // to the underlying character stream. + // FunctorData: + // this is expected to encapsulate the shared part of the + // functor (see lex/lexer/lexertl/functor_data.hpp for an + // example and documentation). + // Iterator: the type of the underlying iterator + // SupportsActors: + // this is expected to be a mpl::bool_, if mpl::true_ the + // functor invokes functors which (optionally) have + // been attached to the token definitions. + // SupportState: + // this is expected to be a mpl::bool_, if mpl::true_ the + // functor supports different lexer states, + // otherwise no lexer state is supported. + // + /////////////////////////////////////////////////////////////////////////// + template <typename Token + , template <typename, typename, typename, typename> class FunctorData + , typename Iterator = typename Token::iterator_type + , typename SupportsActors = mpl::false_ + , typename SupportsState = typename Token::has_state> + class functor + { + public: + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + char_type; + + private: + // Needed by compilers not implementing the resolution to DR45. For + // reference, see + // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45. + typedef typename Token::token_value_type token_value_type; + friend class FunctorData<Iterator, SupportsActors, SupportsState + , token_value_type>; + + // Helper template allowing to assign a value on exit + template <typename T> + struct assign_on_exit + { + assign_on_exit(T& dst, T const& src) + : dst_(dst), src_(src) {} + + ~assign_on_exit() + { + dst_ = src_; + } + + T& dst_; + T const& src_; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + assign_on_exit& operator= (assign_on_exit const&); + }; + + public: + functor() +#if defined(__PGI) + : eof() +#endif + {} + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) + // somehow VC7.1 needs this (meaningless) assignment operator + functor& operator=(functor const& rhs) + { + return *this; + } +#endif + + /////////////////////////////////////////////////////////////////////// + // interface to the iterator_policies::split_functor_input policy + typedef Token result_type; + typedef functor unique; + typedef FunctorData<Iterator, SupportsActors, SupportsState + , token_value_type> shared; + + BOOST_SPIRIT_EOF_PREFIX result_type const eof; + + /////////////////////////////////////////////////////////////////////// + typedef Iterator iterator_type; + typedef typename shared::semantic_actions_type semantic_actions_type; + typedef typename shared::next_token_functor next_token_functor; + typedef typename shared::get_state_name_type get_state_name_type; + + // this is needed to wrap the semantic actions in a proper way + typedef typename shared::wrap_action_type wrap_action_type; + + /////////////////////////////////////////////////////////////////////// + template <typename MultiPass> + static result_type& get_next(MultiPass& mp, result_type& result) + { + typedef typename result_type::id_type id_type; + + shared& data = mp.shared()->ftor; + for(;;) + { + if (data.get_first() == data.get_last()) +#if defined(BOOST_SPIRIT_STATIC_EOF) + return result = eof; +#else + return result = mp.ftor.eof; +#endif + + data.reset_value(); + Iterator end = data.get_first(); + std::size_t unique_id = boost::lexer::npos; + bool prev_bol = false; + + // lexer matching might change state + std::size_t state = data.get_state(); + std::size_t id = data.next(end, unique_id, prev_bol); + + if (boost::lexer::npos == id) { // no match +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) + std::string next; + Iterator it = data.get_first(); + for (std::size_t i = 0; i < 10 && it != data.get_last(); ++it, ++i) + next += *it; + + std::cerr << "Not matched, in state: " << state + << ", lookahead: >" << next << "<" << std::endl; +#endif + return result = result_type(0); + } + else if (0 == id) { // EOF reached +#if defined(BOOST_SPIRIT_STATIC_EOF) + return result = eof; +#else + return result = mp.ftor.eof; +#endif + } + +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) + { + std::string next; + Iterator it = end; + for (std::size_t i = 0; i < 10 && it != data.get_last(); ++it, ++i) + next += *it; + + std::cerr << "Matched: " << id << ", in state: " + << state << ", string: >" + << std::basic_string<char_type>(data.get_first(), end) << "<" + << ", lookahead: >" << next << "<" << std::endl; + if (data.get_state() != state) { + std::cerr << "Switched to state: " + << data.get_state() << std::endl; + } + } +#endif + // account for a possibly pending lex::more(), i.e. moving + // data.first_ back to the start of the previously matched token. + bool adjusted = data.adjust_start(); + + // set the end of the matched input sequence in the token data + data.set_end(end); + + // invoke attached semantic actions, if defined, might change + // state, id, data.first_, and/or end + BOOST_SCOPED_ENUM(pass_flags) pass = + data.invoke_actions(state, id, unique_id, end); + + if (data.has_value()) { + // return matched token using the token value as set before + // using data.set_value(), advancing 'data.first_' past the + // matched sequence + assign_on_exit<Iterator> on_exit(data.get_first(), end); + return result = result_type(id_type(id), state, data.get_value()); + } + else if (pass_flags::pass_normal == pass) { + // return matched token, advancing 'data.first_' past the + // matched sequence + assign_on_exit<Iterator> on_exit(data.get_first(), end); + return result = result_type(id_type(id), state, data.get_first(), end); + } + else if (pass_flags::pass_fail == pass) { +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) + std::cerr << "Matching forced to fail" << std::endl; +#endif + // if the data.first_ got adjusted above, revert this adjustment + if (adjusted) + data.revert_adjust_start(); + + // one of the semantic actions signaled no-match + data.reset_bol(prev_bol); + if (state != data.get_state()) + continue; // retry matching if state has changed + + // if the state is unchanged repeating the match wouldn't + // move the input forward, causing an infinite loop + return result = result_type(0); + } + +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) + std::cerr << "Token ignored, continuing matching" << std::endl; +#endif + // if this token needs to be ignored, just repeat the matching, + // while starting right after the current match + data.get_first() = end; + } + } + + // set_state are propagated up to the iterator interface, allowing to + // manipulate the current lexer state through any of the exposed + // iterators. + template <typename MultiPass> + static std::size_t set_state(MultiPass& mp, std::size_t state) + { + std::size_t oldstate = mp.shared()->ftor.get_state(); + mp.shared()->ftor.set_state(state); + +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) + std::cerr << "Switching state from: " << oldstate + << " to: " << state + << std::endl; +#endif + return oldstate; + } + + template <typename MultiPass> + static std::size_t get_state(MultiPass& mp) + { + return mp.shared()->ftor.get_state(); + } + + template <typename MultiPass> + static std::size_t + map_state(MultiPass const& mp, char_type const* statename) + { + return mp.shared()->ftor.get_state_id(statename); + } + + // we don't need this, but it must be there + template <typename MultiPass> + static void destroy(MultiPass const&) {} + }; + +#if defined(BOOST_SPIRIT_STATIC_EOF) + /////////////////////////////////////////////////////////////////////////// + // eof token + /////////////////////////////////////////////////////////////////////////// + template <typename Token + , template <typename, typename, typename, typename> class FunctorData + , typename Iterator, typename SupportsActors, typename SupportsState> + typename functor<Token, FunctorData, Iterator, SupportsActors, SupportsState>::result_type const + functor<Token, FunctorData, Iterator, SupportsActors, SupportsState>::eof = + typename functor<Token, FunctorData, Iterator, SupportsActors + , SupportsState>::result_type(); +#endif + +}}}} + +#undef BOOST_SPIRIT_EOF_PREFIX +#undef BOOST_SPIRIT_STATIC_EOF + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp new file mode 100644 index 0000000..207b374 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp @@ -0,0 +1,552 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXER_FUNCTOR_DATA_JUN_10_2009_0954AM) +#define BOOST_SPIRIT_LEX_LEXER_FUNCTOR_DATA_JUN_10_2009_0954AM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/spirit/home/support/detail/lexer/generator.hpp> +#include <boost/spirit/home/support/detail/lexer/rules.hpp> +#include <boost/spirit/home/support/detail/lexer/state_machine.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/semantic_action_data.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/optional.hpp> + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + namespace detail + { + /////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename HasActors, typename HasState + , typename TokenValue> + class data; // no default specialization + + /////////////////////////////////////////////////////////////////////// + // neither supports state, nor actors + template <typename Iterator, typename TokenValue> + class data<Iterator, mpl::false_, mpl::false_, TokenValue> + { + protected: + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + char_type; + + public: + typedef Iterator base_iterator_type; + typedef iterator_range<Iterator> token_value_type; + typedef token_value_type get_value_type; + typedef std::size_t state_type; + typedef char_type const* state_name_type; + typedef unused_type semantic_actions_type; + typedef detail::wrap_action<unused_type, Iterator, data, std::size_t> + wrap_action_type; + + typedef unused_type next_token_functor; + typedef unused_type get_state_name_type; + + // initialize the shared data + template <typename IterData> + data (IterData const& data_, Iterator& first, Iterator const& last) + : first_(first), last_(last) + , state_machine_(data_.state_machine_) + , rules_(data_.rules_) + , bol_(data_.state_machine_.data()._seen_BOL_assertion) {} + + // The following functions are used by the implementation of the + // placeholder '_state'. + template <typename Char> + void set_state_name (Char const*) + { +// some (random) versions of gcc instantiate this function even if it's not +// needed leading to false static asserts +#if !defined(__GNUC__) + // If you see a compile time assertion below you're probably + // using a token type not supporting lexer states (the 3rd + // template parameter of the token is mpl::false_), but your + // code uses state changes anyways. + BOOST_STATIC_ASSERT(false); +#endif + } + char_type const* get_state_name() const { return rules_.initial(); } + std::size_t get_state_id (char_type const*) const + { + return 0; + } + + // The function get_eoi() is used by the implementation of the + // placeholder '_eoi'. + Iterator const& get_eoi() const { return last_; } + + // The function less() is used by the implementation of the support + // function lex::less(). Its functionality is equivalent to flex' + // function yyless(): it returns an iterator positioned to the + // nth input character beyond the current start iterator (i.e. by + // assigning the return value to the placeholder '_end' it is + // possible to return all but the first n characters of the current + // token back to the input stream. + // + // This function does nothing as long as no semantic actions are + // used. + Iterator const& less(Iterator const& it, int) + { + // The following assertion fires most likely because you are + // using lexer semantic actions without using the actor_lexer + // as the base class for your token definition class. + BOOST_ASSERT(false && + "Are you using lexer semantic actions without using the " + "actor_lexer base?"); + return it; + } + + // The function more() is used by the implementation of the support + // function lex::more(). Its functionality is equivalent to flex' + // function yymore(): it tells the lexer that the next time it + // matches a rule, the corresponding token should be appended onto + // the current token value rather than replacing it. + // + // These functions do nothing as long as no semantic actions are + // used. + void more() + { + // The following assertion fires most likely because you are + // using lexer semantic actions without using the actor_lexer + // as the base class for your token definition class. + BOOST_ASSERT(false && + "Are you using lexer semantic actions without using the " + "actor_lexer base?"); + } + bool adjust_start() { return false; } + void revert_adjust_start() {} + + // The function lookahead() is used by the implementation of the + // support function lex::lookahead. It can be used to implement + // lookahead for lexer engines not supporting constructs like flex' + // a/b (match a, but only when followed by b): + // + // This function does nothing as long as no semantic actions are + // used. + bool lookahead(std::size_t, std::size_t /*state*/ = std::size_t(~0)) + { + // The following assertion fires most likely because you are + // using lexer semantic actions without using the actor_lexer + // as the base class for your token definition class. + BOOST_ASSERT(false && + "Are you using lexer semantic actions without using the " + "actor_lexer base?"); + return false; + } + + // the functions next, invoke_actions, and get_state are used by + // the functor implementation below + + // The function next() tries to match the next token from the + // underlying input sequence. + std::size_t next(Iterator& end, std::size_t& unique_id, bool& prev_bol) + { + prev_bol = bol_; + + typedef basic_iterator_tokeniser<Iterator> tokenizer; + return tokenizer::next(state_machine_, bol_, end, last_ + , unique_id); + } + + // nothing to invoke, so this is empty + BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t + , std::size_t, std::size_t, Iterator const&) + { + return pass_flags::pass_normal; // always accept + } + + std::size_t get_state() const { return 0; } + void set_state(std::size_t) {} + + void set_end(Iterator const& it) {} + + Iterator& get_first() { return first_; } + Iterator const& get_first() const { return first_; } + Iterator const& get_last() const { return last_; } + + iterator_range<Iterator> get_value() const + { + return iterator_range<Iterator>(first_, last_); + } + bool has_value() const { return false; } + void reset_value() {} + + void reset_bol(bool bol) { bol_ = bol; } + + protected: + Iterator& first_; + Iterator last_; + + boost::lexer::basic_state_machine<char_type> const& state_machine_; + boost::lexer::basic_rules<char_type> const& rules_; + + bool bol_; // helper storing whether last character was \n + + private: + // silence MSVC warning C4512: assignment operator could not be generated + data& operator= (data const&); + }; + + /////////////////////////////////////////////////////////////////////// + // doesn't support lexer semantic actions, but supports state + template <typename Iterator, typename TokenValue> + class data<Iterator, mpl::false_, mpl::true_, TokenValue> + : public data<Iterator, mpl::false_, mpl::false_, TokenValue> + { + protected: + typedef data<Iterator, mpl::false_, mpl::false_, TokenValue> base_type; + typedef typename base_type::char_type char_type; + + public: + typedef Iterator base_iterator_type; + typedef iterator_range<Iterator> token_value_type; + typedef token_value_type get_value_type; + typedef typename base_type::state_type state_type; + typedef typename base_type::state_name_type state_name_type; + typedef typename base_type::semantic_actions_type + semantic_actions_type; + + // initialize the shared data + template <typename IterData> + data (IterData const& data_, Iterator& first, Iterator const& last) + : base_type(data_, first, last) + , state_(0) {} + + // The following functions are used by the implementation of the + // placeholder '_state'. + void set_state_name (char_type const* new_state) + { + std::size_t state_id = this->rules_.state(new_state); + + // If the following assertion fires you've probably been using + // a lexer state name which was not defined in your token + // definition. + BOOST_ASSERT(state_id != boost::lexer::npos); + + if (state_id != boost::lexer::npos) + state_ = state_id; + } + char_type const* get_state_name() const + { + return this->rules_.state(state_); + } + std::size_t get_state_id (char_type const* state) const + { + return this->rules_.state(state); + } + + // the functions next() and get_state() are used by the functor + // implementation below + + // The function next() tries to match the next token from the + // underlying input sequence. + std::size_t next(Iterator& end, std::size_t& unique_id, bool& prev_bol) + { + prev_bol = this->bol_; + + typedef basic_iterator_tokeniser<Iterator> tokenizer; + return tokenizer::next(this->state_machine_, state_, + this->bol_, end, this->get_eoi(), unique_id); + } + + std::size_t& get_state() { return state_; } + void set_state(std::size_t state) { state_ = state; } + + protected: + std::size_t state_; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + data& operator= (data const&); + }; + + /////////////////////////////////////////////////////////////////////// + // does support lexer semantic actions, may support state + template <typename Iterator, typename HasState, typename TokenValue> + class data<Iterator, mpl::true_, HasState, TokenValue> + : public data<Iterator, mpl::false_, HasState, TokenValue> + { + public: + typedef semantic_actions<Iterator, HasState, data> + semantic_actions_type; + + protected: + typedef data<Iterator, mpl::false_, HasState, TokenValue> base_type; + typedef typename base_type::char_type char_type; + typedef typename semantic_actions_type::functor_wrapper_type + functor_wrapper_type; + + public: + typedef Iterator base_iterator_type; + typedef TokenValue token_value_type; + typedef TokenValue const& get_value_type; + typedef typename base_type::state_type state_type; + typedef typename base_type::state_name_type state_name_type; + + typedef detail::wrap_action<functor_wrapper_type + , Iterator, data, std::size_t> wrap_action_type; + + template <typename IterData> + data (IterData const& data_, Iterator& first, Iterator const& last) + : base_type(data_, first, last) + , actions_(data_.actions_), hold_() + , value_(iterator_range<Iterator>(first, last)) + , has_value_(false), has_hold_(false) {} + + // invoke attached semantic actions, if defined + BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state + , std::size_t& id, std::size_t unique_id, Iterator& end) + { + return actions_.invoke_actions(state, id, unique_id, end, *this); + } + + // The function less() is used by the implementation of the support + // function lex::less(). Its functionality is equivalent to flex' + // function yyless(): it returns an iterator positioned to the + // nth input character beyond the current start iterator (i.e. by + // assigning the return value to the placeholder '_end' it is + // possible to return all but the first n characters of the current + // token back to the input stream). + Iterator const& less(Iterator& it, int n) + { + it = this->get_first(); + std::advance(it, n); + return it; + } + + // The function more() is used by the implementation of the support + // function lex::more(). Its functionality is equivalent to flex' + // function yymore(): it tells the lexer that the next time it + // matches a rule, the corresponding token should be appended onto + // the current token value rather than replacing it. + void more() + { + hold_ = this->get_first(); + has_hold_ = true; + } + + // The function lookahead() is used by the implementation of the + // support function lex::lookahead. It can be used to implement + // lookahead for lexer engines not supporting constructs like flex' + // a/b (match a, but only when followed by b) + bool lookahead(std::size_t id, std::size_t state = std::size_t(~0)) + { + Iterator end = end_; + std::size_t unique_id = boost::lexer::npos; + bool bol = this->bol_; + + if (std::size_t(~0) == state) + state = this->state_; + + typedef basic_iterator_tokeniser<Iterator> tokenizer; + return id == tokenizer::next(this->state_machine_, state, + bol, end, this->get_eoi(), unique_id); + } + + // The adjust_start() and revert_adjust_start() are helper + // functions needed to implement the functionality required for + // lex::more(). It is called from the functor body below. + bool adjust_start() + { + if (!has_hold_) + return false; + + std::swap(this->get_first(), hold_); + has_hold_ = false; + return true; + } + void revert_adjust_start() + { + // this will be called only if adjust_start above returned true + std::swap(this->get_first(), hold_); + has_hold_ = true; + } + + TokenValue const& get_value() const + { + if (!has_value_) { + value_ = iterator_range<Iterator>(this->get_first(), end_); + has_value_ = true; + } + return value_; + } + template <typename Value> + void set_value(Value const& val) + { + value_ = val; + has_value_ = true; + } + void set_end(Iterator const& it) + { + end_ = it; + } + bool has_value() const { return has_value_; } + void reset_value() { has_value_ = false; } + + protected: + semantic_actions_type const& actions_; + Iterator hold_; // iterator needed to support lex::more() + Iterator end_; // iterator pointing to end of matched token + mutable TokenValue value_; // token value to use + mutable bool has_value_; // 'true' if value_ is valid + bool has_hold_; // 'true' if hold_ is valid + + private: + // silence MSVC warning C4512: assignment operator could not be generated + data& operator= (data const&); + }; + + /////////////////////////////////////////////////////////////////////// + // does support lexer semantic actions, may support state, is used for + // position_token exposing exactly one type + template <typename Iterator, typename HasState, typename TokenValue> + class data<Iterator, mpl::true_, HasState, boost::optional<TokenValue> > + : public data<Iterator, mpl::false_, HasState, TokenValue> + { + public: + typedef semantic_actions<Iterator, HasState, data> + semantic_actions_type; + + protected: + typedef data<Iterator, mpl::false_, HasState, TokenValue> base_type; + typedef typename base_type::char_type char_type; + typedef typename semantic_actions_type::functor_wrapper_type + functor_wrapper_type; + + public: + typedef Iterator base_iterator_type; + typedef boost::optional<TokenValue> token_value_type; + typedef boost::optional<TokenValue> const& get_value_type; + typedef typename base_type::state_type state_type; + typedef typename base_type::state_name_type state_name_type; + + typedef detail::wrap_action<functor_wrapper_type + , Iterator, data, std::size_t> wrap_action_type; + + template <typename IterData> + data (IterData const& data_, Iterator& first, Iterator const& last) + : base_type(data_, first, last) + , actions_(data_.actions_), hold_() + , has_value_(false), has_hold_(false) + { + spirit::traits::assign_to(first, last, value_); + has_value_ = true; + } + + // invoke attached semantic actions, if defined + BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state + , std::size_t& id, std::size_t unique_id, Iterator& end) + { + return actions_.invoke_actions(state, id, unique_id, end, *this); + } + + // The function less() is used by the implementation of the support + // function lex::less(). Its functionality is equivalent to flex' + // function yyless(): it returns an iterator positioned to the + // nth input character beyond the current start iterator (i.e. by + // assigning the return value to the placeholder '_end' it is + // possible to return all but the first n characters of the current + // token back to the input stream). + Iterator const& less(Iterator& it, int n) + { + it = this->get_first(); + std::advance(it, n); + return it; + } + + // The function more() is used by the implementation of the support + // function lex::more(). Its functionality is equivalent to flex' + // function yymore(): it tells the lexer that the next time it + // matches a rule, the corresponding token should be appended onto + // the current token value rather than replacing it. + void more() + { + hold_ = this->get_first(); + has_hold_ = true; + } + + // The function lookahead() is used by the implementation of the + // support function lex::lookahead. It can be used to implement + // lookahead for lexer engines not supporting constructs like flex' + // a/b (match a, but only when followed by b) + bool lookahead(std::size_t id, std::size_t state = std::size_t(~0)) + { + Iterator end = end_; + std::size_t unique_id = boost::lexer::npos; + bool bol = this->bol_; + + if (std::size_t(~0) == state) + state = this->state_; + + typedef basic_iterator_tokeniser<Iterator> tokenizer; + return id == tokenizer::next(this->state_machine_, state, + bol, end, this->get_eoi(), unique_id); + } + + // The adjust_start() and revert_adjust_start() are helper + // functions needed to implement the functionality required for + // lex::more(). It is called from the functor body below. + bool adjust_start() + { + if (!has_hold_) + return false; + + std::swap(this->get_first(), hold_); + has_hold_ = false; + return true; + } + void revert_adjust_start() + { + // this will be called only if adjust_start above returned true + std::swap(this->get_first(), hold_); + has_hold_ = true; + } + + token_value_type const& get_value() const + { + if (!has_value_) { + spirit::traits::assign_to(this->get_first(), end_, value_); + has_value_ = true; + } + return value_; + } + template <typename Value> + void set_value(Value const& val) + { + value_ = val; + has_value_ = true; + } + void set_end(Iterator const& it) + { + end_ = it; + } + bool has_value() const { return has_value_; } + void reset_value() { has_value_ = false; } + + protected: + semantic_actions_type const& actions_; + Iterator hold_; // iterator needed to support lex::more() + Iterator end_; // iterator pointing to end of matched token + mutable token_value_type value_; // token value to use + mutable bool has_value_; // 'true' if value_ is valid + bool has_hold_; // 'true' if hold_ is valid + + private: + // silence MSVC warning C4512: assignment operator could not be generated + data& operator= (data const&); + }; + } +}}}} + +#endif + diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/iterator.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/iterator.hpp new file mode 100644 index 0000000..f2793ba --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/iterator.hpp @@ -0,0 +1,121 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM) +#define BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#if defined(BOOST_SPIRIT_DEBUG) +#include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp> +#else +#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp> +#endif +#include <boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp> +#include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp> +#include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp> +#include <boost/spirit/home/support/iterators/multi_pass.hpp> + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + /////////////////////////////////////////////////////////////////////////// + template <typename FunctorData> + struct make_multi_pass + { + // Divide the given functor type into its components (unique and + // shared) and build a std::pair from these parts + typedef std::pair<typename FunctorData::unique + , typename FunctorData::shared> functor_data_type; + + // This is the result type returned from the iterator + typedef typename FunctorData::result_type result_type; + + // Compose the multi_pass iterator policy type from the appropriate + // policies + typedef iterator_policies::split_functor_input input_policy; + typedef iterator_policies::ref_counted ownership_policy; +#if defined(BOOST_SPIRIT_DEBUG) + typedef iterator_policies::buf_id_check check_policy; +#else + typedef iterator_policies::no_check check_policy; +#endif + typedef iterator_policies::split_std_deque storage_policy; + + typedef iterator_policies::default_policy< + ownership_policy, check_policy, input_policy, storage_policy> + policy_type; + + // Compose the multi_pass iterator from the policy + typedef spirit::multi_pass<functor_data_type, policy_type> type; + }; + + /////////////////////////////////////////////////////////////////////////// + // lexer_iterator exposes an iterator for a lexertl based dfa (lexer) + // The template parameters have the same semantics as described for the + // functor above. + /////////////////////////////////////////////////////////////////////////// + template <typename Functor> + class iterator : public make_multi_pass<Functor>::type + { + public: + typedef typename Functor::unique unique_functor_type; + typedef typename Functor::shared shared_functor_type; + + typedef typename Functor::iterator_type base_iterator_type; + typedef typename Functor::result_type token_type; + + private: + typedef typename make_multi_pass<Functor>::functor_data_type + functor_type; + typedef typename make_multi_pass<Functor>::type base_type; + typedef typename Functor::char_type char_type; + + public: + // create a new iterator encapsulating the lexer object to be used + // for tokenization + template <typename IteratorData> + iterator(IteratorData const& iterdata_, base_iterator_type& first + , base_iterator_type const& last, char_type const* state = 0) + : base_type(functor_type(unique_functor_type() + , shared_functor_type(iterdata_, first, last))) + { + set_state(map_state(state)); + } + + // create an end iterator usable for end of range checking + iterator() {} + + // (wash): < mgaunard> T it; T it2 = ++it; doesn't ocmpile + // < mgaunard> this gets fixed by adding + iterator(const base_type& base) + : base_type(base) { } + + // set the new required state for the underlying lexer object + std::size_t set_state(std::size_t state) + { + return unique_functor_type::set_state(*this, state); + } + + // get the curent state for the underlying lexer object + std::size_t get_state() + { + return unique_functor_type::get_state(*this); + } + + // map the given state name to a corresponding state id as understood + // by the underlying lexer object + std::size_t map_state(char_type const* statename) + { + return (0 != statename) + ? unique_functor_type::map_state(*this, statename) + : 0; + } + }; + +}}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp new file mode 100644 index 0000000..31dffce --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp @@ -0,0 +1,255 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEXERTL_ITERATOR_TOKENISER_MARCH_22_2007_0859AM) +#define BOOST_SPIRIT_LEXERTL_ITERATOR_TOKENISER_MARCH_22_2007_0859AM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/detail/iterator.hpp> +#include <boost/spirit/home/support/detail/lexer/state_machine.hpp> +#include <boost/spirit/home/support/detail/lexer/consts.hpp> +#include <boost/spirit/home/support/detail/lexer/size_t.hpp> +#include <boost/spirit/home/support/detail/lexer/char_traits.hpp> +#include <vector> + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + /////////////////////////////////////////////////////////////////////////// + template<typename Iterator> + class basic_iterator_tokeniser + { + public: + typedef std::vector<std::size_t> size_t_vector; + typedef typename boost::detail::iterator_traits<Iterator>::value_type + char_type; + + static std::size_t next ( + boost::lexer::basic_state_machine<char_type> const& state_machine_ + , std::size_t &dfa_state_, bool& bol_, Iterator &start_token_ + , Iterator const& end_, std::size_t& unique_id_) + { + if (start_token_ == end_) + { + unique_id_ = boost::lexer::npos; + return 0; + } + + bool bol = bol_; + boost::lexer::detail::internals const& internals_ = + state_machine_.data(); + + again: + std::size_t const* lookup_ = &internals_._lookup[dfa_state_]-> + front (); + std::size_t dfa_alphabet_ = internals_._dfa_alphabet[dfa_state_]; + std::size_t const* dfa_ = &internals_._dfa[dfa_state_]->front (); + + std::size_t const* ptr_ = dfa_ + dfa_alphabet_; + Iterator curr_ = start_token_; + bool end_state_ = *ptr_ != 0; + std::size_t id_ = *(ptr_ + boost::lexer::id_index); + std::size_t uid_ = *(ptr_ + boost::lexer::unique_id_index); + std::size_t end_start_state_ = dfa_state_; + bool end_bol_ = bol_; + Iterator end_token_ = start_token_; + + while (curr_ != end_) + { + std::size_t const BOL_state_ = ptr_[boost::lexer::bol_index]; + std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index]; + + if (BOL_state_ && bol) + { + ptr_ = &dfa_[BOL_state_ * dfa_alphabet_]; + } + else if (EOL_state_ && *curr_ == '\n') + { + ptr_ = &dfa_[EOL_state_ * dfa_alphabet_]; + } + else + { + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + value_type; + typedef typename + boost::lexer::char_traits<value_type>::index_type + index_type; + + index_type index = + boost::lexer::char_traits<value_type>::call(*curr_++); + bol = (index == '\n') ? true : false; + std::size_t const state_ = ptr_[ + lookup_[static_cast<std::size_t>(index)]]; + + if (state_ == 0) + { + break; + } + + ptr_ = &dfa_[state_ * dfa_alphabet_]; + } + + if (*ptr_) + { + end_state_ = true; + id_ = *(ptr_ + boost::lexer::id_index); + uid_ = *(ptr_ + boost::lexer::unique_id_index); + end_start_state_ = *(ptr_ + boost::lexer::state_index); + end_bol_ = bol; + end_token_ = curr_; + } + } + + std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index]; + + if (EOL_state_ && curr_ == end_) + { + ptr_ = &dfa_[EOL_state_ * dfa_alphabet_]; + + if (*ptr_) + { + end_state_ = true; + id_ = *(ptr_ + boost::lexer::id_index); + uid_ = *(ptr_ + boost::lexer::unique_id_index); + end_start_state_ = *(ptr_ + boost::lexer::state_index); + end_bol_ = bol; + end_token_ = curr_; + } + } + + if (end_state_) { + // return longest match + dfa_state_ = end_start_state_; + start_token_ = end_token_; + + if (id_ == 0) + { + bol = end_bol_; + goto again; + } + else + { + bol_ = end_bol_; + } + } + else { + bol_ = (*start_token_ == '\n') ? true : false; + id_ = boost::lexer::npos; + uid_ = boost::lexer::npos; + } + + unique_id_ = uid_; + return id_; + } + + /////////////////////////////////////////////////////////////////////// + static std::size_t next ( + boost::lexer::basic_state_machine<char_type> const& state_machine_ + , bool& bol_, Iterator &start_token_, Iterator const& end_ + , std::size_t& unique_id_) + { + if (start_token_ == end_) + { + unique_id_ = boost::lexer::npos; + return 0; + } + + bool bol = bol_; + std::size_t const* lookup_ = &state_machine_.data()._lookup[0]->front(); + std::size_t dfa_alphabet_ = state_machine_.data()._dfa_alphabet[0]; + std::size_t const* dfa_ = &state_machine_.data()._dfa[0]->front (); + std::size_t const* ptr_ = dfa_ + dfa_alphabet_; + + Iterator curr_ = start_token_; + bool end_state_ = *ptr_ != 0; + std::size_t id_ = *(ptr_ + boost::lexer::id_index); + std::size_t uid_ = *(ptr_ + boost::lexer::unique_id_index); + bool end_bol_ = bol_; + Iterator end_token_ = start_token_; + + while (curr_ != end_) + { + std::size_t const BOL_state_ = ptr_[boost::lexer::bol_index]; + std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index]; + + if (BOL_state_ && bol) + { + ptr_ = &dfa_[BOL_state_ * dfa_alphabet_]; + } + else if (EOL_state_ && *curr_ == '\n') + { + ptr_ = &dfa_[EOL_state_ * dfa_alphabet_]; + } + else + { + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + value_type; + typedef typename + boost::lexer::char_traits<value_type>::index_type + index_type; + + index_type index = + boost::lexer::char_traits<value_type>::call(*curr_++); + bol = (index == '\n') ? true : false; + std::size_t const state_ = ptr_[ + lookup_[static_cast<std::size_t>(index)]]; + + if (state_ == 0) + { + break; + } + + ptr_ = &dfa_[state_ * dfa_alphabet_]; + } + + if (*ptr_) + { + end_state_ = true; + id_ = *(ptr_ + boost::lexer::id_index); + uid_ = *(ptr_ + boost::lexer::unique_id_index); + end_bol_ = bol; + end_token_ = curr_; + } + } + + std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index]; + + if (EOL_state_ && curr_ == end_) + { + ptr_ = &dfa_[EOL_state_ * dfa_alphabet_]; + + if (*ptr_) + { + end_state_ = true; + id_ = *(ptr_ + boost::lexer::id_index); + uid_ = *(ptr_ + boost::lexer::unique_id_index); + end_bol_ = bol; + end_token_ = curr_; + } + } + + if (end_state_) { + // return longest match + bol_ = end_bol_; + start_token_ = end_token_; + } + else { + bol_ = *start_token_ == '\n'; + id_ = boost::lexer::npos; + uid_ = boost::lexer::npos; + } + + unique_id_ = uid_; + return id_; + } + }; + +}}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/lexer.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/lexer.hpp new file mode 100644 index 0000000..0f8af55 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/lexer.hpp @@ -0,0 +1,399 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXER_MAR_17_2007_0139PM) +#define BOOST_SPIRIT_LEX_LEXER_MAR_17_2007_0139PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <iosfwd> + +#include <boost/spirit/home/support/detail/lexer/generator.hpp> +#include <boost/spirit/home/support/detail/lexer/rules.hpp> +#include <boost/spirit/home/support/detail/lexer/consts.hpp> +#include <boost/spirit/home/support/unused.hpp> + +#include <boost/spirit/home/lex/lexer/lexertl/token.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/functor.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/functor_data.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/iterator.hpp> +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) +#include <boost/spirit/home/support/detail/lexer/debug.hpp> +#endif + +#include <boost/foreach.hpp> + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + /////////////////////////////////////////////////////////////////////// + // The must_escape function checks if the given character value needs + // to be preceded by a backslash character to disable its special + // meaning in the context of a regular expression + /////////////////////////////////////////////////////////////////////// + template <typename Char> + inline bool must_escape(Char c) + { + // FIXME: more needed? + switch (c) { + case '+': case '/': case '*': case '?': + case '|': + case '(': case ')': + case '[': case ']': + case '{': case '}': + case '.': + case '^': case '$': + case '\\': + case '"': + return true; + + default: + break; + } + return false; + } + + /////////////////////////////////////////////////////////////////////// + // The escape function returns the string representation of the given + // character value, possibly escaped with a backslash character, to + // allow it being safely used in a regular expression definition. + /////////////////////////////////////////////////////////////////////// + template <typename Char> + inline std::basic_string<Char> escape(Char ch) + { + std::basic_string<Char> result(1, ch); + if (detail::must_escape(ch)) + { + typedef typename std::basic_string<Char>::size_type size_type; + result.insert((size_type)0, 1, '\\'); + } + return result; + } + + /////////////////////////////////////////////////////////////////////// + // + /////////////////////////////////////////////////////////////////////// + inline boost::lexer::regex_flags map_flags(unsigned int flags) + { + unsigned int retval = boost::lexer::none; + if (flags & match_flags::match_not_dot_newline) + retval |= boost::lexer::dot_not_newline; + if (flags & match_flags::match_icase) + retval |= boost::lexer::icase; + + return boost::lexer::regex_flags(retval); + } + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Lexer, typename F> + bool generate_static(Lexer const& + , std::basic_ostream<typename Lexer::char_type>& + , typename Lexer::char_type const*, F); + + /////////////////////////////////////////////////////////////////////////// + // + // Every lexer type to be used as a lexer for Spirit has to conform to + // the following public interface: + // + // typedefs: + // iterator_type The type of the iterator exposed by this lexer. + // token_type The type of the tokens returned from the exposed + // iterators. + // + // functions: + // default constructor + // Since lexers are instantiated as base classes + // only it might be a good idea to make this + // constructor protected. + // begin, end Return a pair of iterators, when dereferenced + // returning the sequence of tokens recognized in + // the input stream given as the parameters to the + // begin() function. + // add_token Should add the definition of a token to be + // recognized by this lexer. + // clear Should delete all current token definitions + // associated with the given state of this lexer + // object. + // + // template parameters: + // Iterator The type of the iterator used to access the + // underlying character stream. + // Token The type of the tokens to be returned from the + // exposed token iterator. + // Functor The type of the InputPolicy to use to instantiate + // the multi_pass iterator type to be used as the + // token iterator (returned from begin()/end()). + // + /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // + // The lexer class is a implementation of a Spirit.Lex lexer on + // top of Ben Hanson's lexertl library as outlined above (For more + // information about lexertl go here: http://www.benhanson.net/lexertl.html). + // + // This class is supposed to be used as the first and only template + // parameter while instantiating instances of a lex::lexer class. + // + /////////////////////////////////////////////////////////////////////////// + template <typename Token = token<> + , typename Iterator = typename Token::iterator_type + , typename Functor = functor<Token, lexertl::detail::data, Iterator> > + class lexer + { + private: + struct dummy { void true_() {} }; + typedef void (dummy::*safe_bool)(); + + static std::size_t const all_states_id = static_cast<std::size_t>(-2); + + public: + operator safe_bool() const + { return initialized_dfa_ ? &dummy::true_ : 0; } + + typedef typename boost::detail::iterator_traits<Iterator>::value_type + char_type; + typedef std::basic_string<char_type> string_type; + + typedef boost::lexer::basic_rules<char_type> basic_rules_type; + + // Every lexer type to be used as a lexer for Spirit has to conform to + // a public interface . + typedef Token token_type; + typedef typename Token::id_type id_type; + typedef iterator<Functor> iterator_type; + + private: + // this type is purely used for the iterator_type construction below + struct iterator_data_type + { + typedef typename Functor::semantic_actions_type semantic_actions_type; + + iterator_data_type( + boost::lexer::basic_state_machine<char_type> const& sm + , boost::lexer::basic_rules<char_type> const& rules + , semantic_actions_type const& actions) + : state_machine_(sm), rules_(rules), actions_(actions) + {} + + boost::lexer::basic_state_machine<char_type> const& state_machine_; + boost::lexer::basic_rules<char_type> const& rules_; + semantic_actions_type const& actions_; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + iterator_data_type& operator= (iterator_data_type const&); + }; + + public: + // Return the start iterator usable for iterating over the generated + // tokens. + iterator_type begin(Iterator& first, Iterator const& last + , char_type const* initial_state = 0) const + { + if (!init_dfa()) // never minimize DFA for dynamic lexers + return iterator_type(); + + iterator_data_type iterator_data(state_machine_, rules_, actions_); + return iterator_type(iterator_data, first, last, initial_state); + } + + // Return the end iterator usable to stop iterating over the generated + // tokens. + iterator_type end() const + { + return iterator_type(); + } + + protected: + // Lexer instances can be created by means of a derived class only. + lexer(unsigned int flags) + : flags_(detail::map_flags(flags)) + , rules_(flags_) + , initialized_dfa_(false) + {} + + public: + // interface for token definition management + std::size_t add_token(char_type const* state, char_type tokendef, + std::size_t token_id, char_type const* targetstate) + { + add_state(state); + initialized_dfa_ = false; + if (state == all_states()) + return rules_.add(state, detail::escape(tokendef), token_id, rules_.dot()); + + if (0 == targetstate) + targetstate = state; + else + add_state(targetstate); + return rules_.add(state, detail::escape(tokendef), token_id, targetstate); + } + std::size_t add_token(char_type const* state, string_type const& tokendef, + std::size_t token_id, char_type const* targetstate) + { + add_state(state); + initialized_dfa_ = false; + if (state == all_states()) + return rules_.add(state, tokendef, token_id, rules_.dot()); + + if (0 == targetstate) + targetstate = state; + else + add_state(targetstate); + return rules_.add(state, tokendef, token_id, targetstate); + } + + // interface for pattern definition management + void add_pattern (char_type const* state, string_type const& name, + string_type const& patterndef) + { + add_state(state); + rules_.add_macro(name.c_str(), patterndef); + initialized_dfa_ = false; + } + + boost::lexer::rules const& get_rules() const { return rules_; } + + void clear(char_type const* state) + { + std::size_t s = rules_.state(state); + if (boost::lexer::npos != s) + rules_.clear(state); + initialized_dfa_ = false; + } + std::size_t add_state(char_type const* state) + { + if (state == all_states()) + return all_states_id; + + std::size_t stateid = rules_.state(state); + if (boost::lexer::npos == stateid) { + stateid = rules_.add_state(state); + initialized_dfa_ = false; + } + return stateid; + } + string_type initial_state() const + { + return string_type(rules_.initial()); + } + string_type all_states() const + { + return string_type(rules_.all_states()); + } + + // Register a semantic action with the given id + template <typename F> + void add_action(std::size_t unique_id, std::size_t state, F act) + { + // If you see an error here stating add_action is not a member of + // fusion::unused_type then you are probably having semantic actions + // attached to at least one token in the lexer definition without + // using the lex::lexertl::actor_lexer<> as its base class. + typedef typename Functor::wrap_action_type wrapper_type; + if (state == all_states_id) { + // add the action to all known states + typedef typename + basic_rules_type::string_size_t_map::value_type + state_type; + + std::size_t states = rules_.statemap().size(); + BOOST_FOREACH(state_type const& s, rules_.statemap()) { + for (std::size_t j = 0; j < states; ++j) + actions_.add_action(unique_id + j, s.second, wrapper_type::call(act)); + } + } + else { + actions_.add_action(unique_id, state, wrapper_type::call(act)); + } + } +// template <typename F> +// void add_action(std::size_t unique_id, char_type const* state, F act) +// { +// typedef typename Functor::wrap_action_type wrapper_type; +// actions_.add_action(unique_id, add_state(state), wrapper_type::call(act)); +// } + + // We do not minimize the state machine by default anymore because + // Ben said: "If you can afford to generate a lexer at runtime, there + // is little point in calling minimise." + // Go figure. + bool init_dfa(bool minimize = false) const + { + if (!initialized_dfa_) { + state_machine_.clear(); + typedef boost::lexer::basic_generator<char_type> generator; + generator::build (rules_, state_machine_); + if (minimize) + generator::minimise (state_machine_); + +#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) + boost::lexer::debug::dump(state_machine_, std::cerr); +#endif + initialized_dfa_ = true; + +// // release memory held by rules description +// basic_rules_type rules; +// rules.init_state_info(rules_); // preserve states +// std::swap(rules, rules_); + } + return true; + } + + private: + // lexertl specific data + mutable boost::lexer::basic_state_machine<char_type> state_machine_; + boost::lexer::regex_flags flags_; + /*mutable*/ basic_rules_type rules_; + + typename Functor::semantic_actions_type actions_; + mutable bool initialized_dfa_; + + // generator functions must be able to access members directly + template <typename Lexer, typename F> + friend bool generate_static(Lexer const& + , std::basic_ostream<typename Lexer::char_type>& + , typename Lexer::char_type const*, F); + }; + + /////////////////////////////////////////////////////////////////////////// + // + // The actor_lexer class is another implementation of a Spirit.Lex + // lexer on top of Ben Hanson's lexertl library as outlined above (For + // more information about lexertl go here: + // http://www.benhanson.net/lexertl.html). + // + // The only difference to the lexer class above is that token_def + // definitions may have semantic (lexer) actions attached while being + // defined: + // + // int w; + // token_def word = "[^ \t\n]+"; + // self = word[++ref(w)]; // see example: word_count_lexer + // + // This class is supposed to be used as the first and only template + // parameter while instantiating instances of a lex::lexer class. + // + /////////////////////////////////////////////////////////////////////////// + template <typename Token = token<> + , typename Iterator = typename Token::iterator_type + , typename Functor = functor<Token, lexertl::detail::data, Iterator, mpl::true_> > + class actor_lexer : public lexer<Token, Iterator, Functor> + { + protected: + // Lexer instances can be created by means of a derived class only. + actor_lexer(unsigned int flags) + : lexer<Token, Iterator, Functor>(flags) {} + }; + +}}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/semantic_action_data.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/semantic_action_data.hpp new file mode 100644 index 0000000..30748c5 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/semantic_action_data.hpp @@ -0,0 +1,121 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXER_SEMANTIC_ACTION_DATA_JUN_10_2009_0417PM) +#define BOOST_SPIRIT_LEX_LEXER_SEMANTIC_ACTION_DATA_JUN_10_2009_0417PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/lexer/pass_flags.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/function.hpp> +#include <vector> + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + namespace detail + { + /////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename SupportsState, typename Data> + struct semantic_actions; + + // This specialization of semantic_actions will be used if the token + // type (lexer definition) does not support states, which simplifies + // the data structures used to store the semantic action function + // objects. + template <typename Iterator, typename Data> + struct semantic_actions<Iterator, mpl::false_, Data> + { + typedef void functor_type(Iterator&, Iterator& + , BOOST_SCOPED_ENUM(pass_flags)&, std::size_t&, Data&); + typedef boost::function<functor_type> functor_wrapper_type; + + // add a semantic action function object + template <typename F> + void add_action(std::size_t unique_id, std::size_t, F act) + { + if (actions_.size() <= unique_id) + actions_.resize(unique_id + 1); + + actions_[unique_id] = act; + } + + // try to invoke a semantic action for the given token (unique_id) + BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t /*state*/ + , std::size_t& id, std::size_t unique_id, Iterator& end + , Data& data) const + { + // if there is nothing to invoke, continue with 'match' + if (unique_id >= actions_.size() || !actions_[unique_id]) + return pass_flags::pass_normal; + + // Note: all arguments might be changed by the invoked semantic + // action + BOOST_SCOPED_ENUM(pass_flags) match = pass_flags::pass_normal; + actions_[unique_id](data.get_first(), end, match, id, data); + return match; + } + + std::vector<functor_wrapper_type> actions_; + }; + + // This specialization of semantic_actions will be used if the token + // type (lexer definition) needs to support states, resulting in a more + // complex data structure needed for storing the semantic action + // function objects. + template <typename Iterator, typename Data> + struct semantic_actions<Iterator, mpl::true_, Data> + { + typedef void functor_type(Iterator&, Iterator& + , BOOST_SCOPED_ENUM(pass_flags)&, std::size_t&, Data&); + typedef boost::function<functor_type> functor_wrapper_type; + + // add a semantic action function object + template <typename F> + void add_action(std::size_t unique_id, std::size_t state, F act) + { + if (actions_.size() <= state) + actions_.resize(state + 1); + + std::vector<functor_wrapper_type>& actions (actions_[state]); + if (actions.size() <= unique_id) + actions.resize(unique_id + 1); + + actions[unique_id] = act; + } + + // try to invoke a semantic action for the given token (unique_id) + BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state + , std::size_t& id, std::size_t unique_id, Iterator& end + , Data& data) const + { + // if there is no action defined for this state, return match + if (state >= actions_.size()) + return pass_flags::pass_normal; + + // if there is nothing to invoke, continue with 'match' + std::vector<functor_wrapper_type> const& actions = actions_[state]; + if (unique_id >= actions.size() || !actions[unique_id]) + return pass_flags::pass_normal; + + // set token value + data.set_end(end); + + // Note: all arguments might be changed by the invoked semantic + // action + BOOST_SCOPED_ENUM(pass_flags) match = pass_flags::pass_normal; + actions[unique_id](data.get_first(), end, match, id, data); + return match; + } + + std::vector<std::vector<functor_wrapper_type> > actions_; + }; + } + +}}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/token.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/token.hpp new file mode 100644 index 0000000..90961af --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/token.hpp @@ -0,0 +1,654 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_TOKEN_FEB_10_2008_0751PM) +#define BOOST_SPIRIT_LEX_TOKEN_FEB_10_2008_0751PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/spirit/home/support/attributes.hpp> +#include <boost/spirit/home/support/argument.hpp> +#include <boost/spirit/home/support/detail/lexer/generator.hpp> +#include <boost/spirit/home/support/detail/lexer/rules.hpp> +#include <boost/spirit/home/support/detail/lexer/consts.hpp> +#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp> +#include <boost/spirit/home/lex/lexer/terminals.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/fusion/include/value_at.hpp> +#include <boost/detail/iterator.hpp> +#include <boost/variant.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/begin.hpp> +#include <boost/mpl/insert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/or.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/range/iterator_range.hpp> +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +#include <boost/static_assert.hpp> +#endif + +#if defined(BOOST_SPIRIT_DEBUG) +#include <iosfwd> +#endif + +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + /////////////////////////////////////////////////////////////////////////// + // + // The token is the type of the objects returned by default by the + // iterator. + // + // template parameters: + // Iterator The type of the iterator used to access the + // underlying character stream. + // AttributeTypes A mpl sequence containing the types of all + // required different token values to be supported + // by this token type. + // HasState A mpl::bool_ indicating, whether this token type + // should support lexer states. + // Idtype The type to use for the token id (defaults to + // std::size_t). + // + // It is possible to use other token types with the spirit::lex + // framework as well. If you plan to use a different type as your token + // type, you'll need to expose the following things from your token type + // to make it compatible with spirit::lex: + // + // typedefs + // iterator_type The type of the iterator used to access the + // underlying character stream. + // + // id_type The type of the token id used. + // + // methods + // default constructor + // This should initialize the token as an end of + // input token. + // constructors The prototype of the other required + // constructors should be: + // + // token(int) + // This constructor should initialize the token as + // an invalid token (not carrying any specific + // values) + // + // where: the int is used as a tag only and its value is + // ignored + // + // and: + // + // token(Idtype id, std::size_t state, + // iterator_type first, iterator_type last); + // + // where: id: token id + // state: lexer state this token was matched in + // first, last: pair of iterators marking the matched + // range in the underlying input stream + // + // accessors + // id() return the token id of the matched input sequence + // id(newid) set the token id of the token instance + // + // state() return the lexer state this token was matched in + // + // value() return the token value + // + // Additionally, you will have to implement a couple of helper functions + // in the same namespace as the token type: a comparison operator==() to + // compare your token instances, a token_is_valid() function and different + // specializations of the Spirit customization point + // assign_to_attribute_from_value as shown below. + // + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator = char const* + , typename AttributeTypes = mpl::vector0<> + , typename HasState = mpl::true_ + , typename Idtype = std::size_t> + struct token; + + /////////////////////////////////////////////////////////////////////////// + // This specialization of the token type doesn't contain any item data and + // doesn't support working with lexer states. + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Idtype> + struct token<Iterator, lex::omit, mpl::false_, Idtype> + { + typedef Iterator iterator_type; + typedef mpl::false_ has_state; + typedef Idtype id_type; + typedef unused_type token_value_type; + + // default constructed tokens correspond to EOI tokens + token() : id_(id_type(boost::lexer::npos)) {} + + // construct an invalid token + explicit token(int) : id_(id_type(0)) {} + + token(id_type id, std::size_t) : id_(id) {} + + token(id_type id, std::size_t, token_value_type) + : id_(id) {} + + token_value_type& value() { static token_value_type u; return u; } + token_value_type const& value() const { return unused; } + +#if defined(BOOST_SPIRIT_DEBUG) + token(id_type id, std::size_t, Iterator const& first + , Iterator const& last) + : matched_(first, last) + , id_(id) {} +#else + token(id_type id, std::size_t, Iterator const&, Iterator const&) + : id_(id) {} +#endif + + // this default conversion operator is needed to allow the direct + // usage of tokens in conjunction with the primitive parsers defined + // in Qi + operator id_type() const { return id_; } + + // Retrieve or set the token id of this token instance. + id_type id() const { return id_; } + void id(id_type newid) { id_ = newid; } + + std::size_t state() const { return 0; } // always '0' (INITIAL state) + + bool is_valid() const + { + return 0 != id_ && id_type(boost::lexer::npos) != id_; + } + +#if defined(BOOST_SPIRIT_DEBUG) +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + // workaround for MSVC10 which has problems copying a default + // constructed iterator_range + token& operator= (token const& rhs) + { + if (this != &rhs) + { + id_ = rhs.id_; + if (is_valid()) + matched_ = rhs.matched_; + } + return *this; + } +#endif + std::pair<Iterator, Iterator> matched_; +#endif + + protected: + id_type id_; // token id, 0 if nothing has been matched + }; + +#if defined(BOOST_SPIRIT_DEBUG) + template <typename Char, typename Traits, typename Iterator + , typename AttributeTypes, typename HasState, typename Idtype> + inline std::basic_ostream<Char, Traits>& + operator<< (std::basic_ostream<Char, Traits>& os + , token<Iterator, AttributeTypes, HasState, Idtype> const& t) + { + if (t.is_valid()) { + Iterator end = t.matched_.second; + for (Iterator it = t.matched_.first; it != end; ++it) + os << *it; + } + else { + os << "<invalid token>"; + } + return os; + } +#endif + + /////////////////////////////////////////////////////////////////////////// + // This specialization of the token type doesn't contain any item data but + // supports working with lexer states. + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Idtype> + struct token<Iterator, lex::omit, mpl::true_, Idtype> + : token<Iterator, lex::omit, mpl::false_, Idtype> + { + private: + typedef token<Iterator, lex::omit, mpl::false_, Idtype> base_type; + + public: + typedef typename base_type::id_type id_type; + typedef Iterator iterator_type; + typedef mpl::true_ has_state; + typedef unused_type token_value_type; + + // default constructed tokens correspond to EOI tokens + token() : state_(boost::lexer::npos) {} + + // construct an invalid token + explicit token(int) : base_type(0), state_(boost::lexer::npos) {} + + token(id_type id, std::size_t state) + : base_type(id, boost::lexer::npos), state_(state) {} + + token(id_type id, std::size_t state, token_value_type) + : base_type(id, boost::lexer::npos, unused) + , state_(state) {} + + token(id_type id, std::size_t state + , Iterator const& first, Iterator const& last) + : base_type(id, boost::lexer::npos, first, last) + , state_(state) {} + + std::size_t state() const { return state_; } + +#if defined(BOOST_SPIRIT_DEBUG) && BOOST_WORKAROUND(BOOST_MSVC, == 1600) + // workaround for MSVC10 which has problems copying a default + // constructed iterator_range + token& operator= (token const& rhs) + { + if (this != &rhs) + { + this->base_type::operator=(static_cast<base_type const&>(rhs)); + state_ = rhs.state_; + } + return *this; + } +#endif + + protected: + std::size_t state_; // lexer state this token was matched in + }; + + /////////////////////////////////////////////////////////////////////////// + // The generic version of the token type derives from the + // specialization above and adds a single data member holding the item + // data carried by the token instance. + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + /////////////////////////////////////////////////////////////////////// + // Meta-function to calculate the type of the variant data item to be + // stored with each token instance. + // + // Note: The iterator pair needs to be the first type in the list of + // types supported by the generated variant type (this is being + // used to identify whether the stored data item in a particular + // token instance needs to be converted from the pair of + // iterators (see the first of the assign_to_attribute_from_value + // specializations below). + /////////////////////////////////////////////////////////////////////// + template <typename IteratorPair, typename AttributeTypes> + struct token_value_typesequence + { + typedef typename mpl::insert< + AttributeTypes + , typename mpl::begin<AttributeTypes>::type + , IteratorPair + >::type sequence_type; + typedef typename make_variant_over<sequence_type>::type type; + }; + + /////////////////////////////////////////////////////////////////////// + // The type of the data item stored with a token instance is defined + // by the template parameter 'AttributeTypes' and may be: + // + // lex::omit: no data item is stored with the token + // instance (this is handled by the + // specializations of the token class + // below) + // mpl::vector0<>: each token instance stores a pair of + // iterators pointing to the matched input + // sequence + // mpl::vector<...>: each token instance stores a variant being + // able to store the pair of iterators pointing + // to the matched input sequence, or any of the + // types a specified in the mpl::vector<> + // + // All this is done to ensure the token type is as small (in terms + // of its byte-size) as possible. + /////////////////////////////////////////////////////////////////////// + template <typename IteratorPair, typename AttributeTypes> + struct token_value_type + : mpl::eval_if< + mpl::or_< + is_same<AttributeTypes, mpl::vector0<> > + , is_same<AttributeTypes, mpl::vector<> > > + , mpl::identity<IteratorPair> + , token_value_typesequence<IteratorPair, AttributeTypes> > + {}; + } + + template <typename Iterator, typename AttributeTypes, typename HasState + , typename Idtype> + struct token : token<Iterator, lex::omit, HasState, Idtype> + { + private: // precondition assertions +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_STATIC_ASSERT((mpl::is_sequence<AttributeTypes>::value || + is_same<AttributeTypes, lex::omit>::value)); +#endif + typedef token<Iterator, lex::omit, HasState, Idtype> base_type; + + protected: + // If no additional token value types are given, the the token will + // hold the plain pair of iterators pointing to the matched range + // in the underlying input sequence. Otherwise the token value is + // stored as a variant and will again hold the pair of iterators but + // is able to hold any of the given data types as well. The conversion + // from the iterator pair to the required data type is done when it is + // accessed for the first time. + typedef iterator_range<Iterator> iterpair_type; + + public: + typedef typename base_type::id_type id_type; + typedef typename detail::token_value_type< + iterpair_type, AttributeTypes + >::type token_value_type; + + typedef Iterator iterator_type; + + // default constructed tokens correspond to EOI tokens + token() : value_(iterpair_type(iterator_type(), iterator_type())) {} + + // construct an invalid token + explicit token(int) + : base_type(0) + , value_(iterpair_type(iterator_type(), iterator_type())) {} + + token(id_type id, std::size_t state, token_value_type const& value) + : base_type(id, state, value) + , value_(value) {} + + token(id_type id, std::size_t state, Iterator const& first + , Iterator const& last) + : base_type(id, state, first, last) + , value_(iterpair_type(first, last)) {} + + token_value_type& value() { return value_; } + token_value_type const& value() const { return value_; } + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + // workaround for MSVC10 which has problems copying a default + // constructed iterator_range + token& operator= (token const& rhs) + { + if (this != &rhs) + { + this->base_type::operator=(static_cast<base_type const&>(rhs)); + if (this->is_valid()) + value_ = rhs.value_; + } + return *this; + } +#endif + + protected: + token_value_type value_; // token value, by default a pair of iterators + }; + + /////////////////////////////////////////////////////////////////////////// + // tokens are considered equal, if their id's match (these are unique) + template <typename Iterator, typename AttributeTypes, typename HasState + , typename Idtype> + inline bool + operator== (token<Iterator, AttributeTypes, HasState, Idtype> const& lhs, + token<Iterator, AttributeTypes, HasState, Idtype> const& rhs) + { + return lhs.id() == rhs.id(); + } + + /////////////////////////////////////////////////////////////////////////// + // This overload is needed by the multi_pass/functor_input_policy to + // validate a token instance. It has to be defined in the same namespace + // as the token class itself to allow ADL to find it. + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename AttributeTypes, typename HasState + , typename Idtype> + inline bool + token_is_valid(token<Iterator, AttributeTypes, HasState, Idtype> const& t) + { + return t.is_valid(); + } +}}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + // We have to provide specializations for the customization point + // assign_to_attribute_from_value allowing to extract the needed value + // from the token. + /////////////////////////////////////////////////////////////////////////// + + // This is called from the parse function of token_def if the token_def + // has been defined to carry a special attribute type + template <typename Attribute, typename Iterator, typename AttributeTypes + , typename HasState, typename Idtype> + struct assign_to_attribute_from_value<Attribute + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + { + static void + call(lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> const& t + , Attribute& attr) + { + // The goal of this function is to avoid the conversion of the pair of + // iterators (to the matched character sequence) into the token value + // of the required type being done more than once. For this purpose it + // checks whether the stored value type is still the default one (pair + // of iterators) and if yes, replaces the pair of iterators with the + // converted value to be returned from subsequent calls. + + if (0 == t.value().which()) { + // first access to the token value + typedef iterator_range<Iterator> iterpair_type; + iterpair_type const& ip = boost::get<iterpair_type>(t.value()); + + // Interestingly enough we use the assign_to() framework defined in + // Spirit.Qi allowing to convert the pair of iterators to almost any + // required type (assign_to(), if available, uses the standard Spirit + // parsers to do the conversion). + spirit::traits::assign_to(ip.begin(), ip.end(), attr); + + // If you get an error during the compilation of the following + // assignment expression, you probably forgot to list one or more + // types used as token value types (in your token_def<...> + // definitions) in your definition of the token class. I.e. any token + // value type used for a token_def<...> definition has to be listed + // during the declaration of the token type to use. For instance let's + // assume we have two token_def's: + // + // token_def<int> number; number = "..."; + // token_def<std::string> identifier; identifier = "..."; + // + // Then you'll have to use the following token type definition + // (assuming you are using the token class): + // + // typedef mpl::vector<int, std::string> token_values; + // typedef token<base_iter_type, token_values> token_type; + // + // where: base_iter_type is the iterator type used to expose the + // underlying input stream. + // + // This token_type has to be used as the second template parameter + // to the lexer class: + // + // typedef lexer<base_iter_type, token_type> lexer_type; + // + // again, assuming you're using the lexer<> template for your + // tokenization. + + typedef lex::lexertl::token< + Iterator, AttributeTypes, HasState, Idtype> token_type; + spirit::traits::assign_to( + attr, const_cast<token_type&>(t).value()); // re-assign value + } + else { + // reuse the already assigned value + spirit::traits::assign_to(boost::get<Attribute>(t.value()), attr); + } + } + }; + + template <typename Attribute, typename Iterator, typename AttributeTypes + , typename HasState, typename Idtype> + struct assign_to_container_from_value<Attribute + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + : assign_to_attribute_from_value<Attribute + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + {}; + + template <typename Iterator, typename AttributeTypes + , typename HasState, typename Idtype> + struct assign_to_container_from_value<utree + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + : assign_to_attribute_from_value<utree + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + {}; + + template <typename Iterator> + struct assign_to_container_from_value< + iterator_range<Iterator>, iterator_range<Iterator> > + { + static void + call(iterator_range<Iterator> const& val, iterator_range<Iterator>& attr) + { + attr = val; + } + }; + + // These are called from the parse function of token_def if the token type + // has no special attribute type assigned + template <typename Attribute, typename Iterator, typename HasState + , typename Idtype> + struct assign_to_attribute_from_value<Attribute + , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> > + { + static void + call(lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> const& t + , Attribute& attr) + { + // The default type returned by the token_def parser component (if + // it has no token value type assigned) is the pair of iterators + // to the matched character sequence. + spirit::traits::assign_to(t.value().begin(), t.value().end(), attr); + } + }; + +// template <typename Attribute, typename Iterator, typename HasState +// , typename Idtype> +// struct assign_to_container_from_value<Attribute +// , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> > +// : assign_to_attribute_from_value<Attribute +// , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> > +// {}; + + // same as above but using mpl::vector<> instead of mpl::vector0<> + template <typename Attribute, typename Iterator, typename HasState + , typename Idtype> + struct assign_to_attribute_from_value<Attribute + , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> > + { + static void + call(lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> const& t + , Attribute& attr) + { + // The default type returned by the token_def parser component (if + // it has no token value type assigned) is the pair of iterators + // to the matched character sequence. + spirit::traits::assign_to(t.value().begin(), t.value().end(), attr); + } + }; + +// template <typename Attribute, typename Iterator, typename HasState +// , typename Idtype> +// struct assign_to_container_from_value<Attribute +// , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> > +// : assign_to_attribute_from_value<Attribute +// , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> > +// {}; + + // This is called from the parse function of token_def if the token type + // has been explicitly omitted (i.e. no attribute value is used), which + // essentially means that every attribute gets initialized using default + // constructed values. + template <typename Attribute, typename Iterator, typename HasState + , typename Idtype> + struct assign_to_attribute_from_value<Attribute + , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> > + { + static void + call(lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> const& t + , Attribute& attr) + { + // do nothing + } + }; + + template <typename Attribute, typename Iterator, typename HasState + , typename Idtype> + struct assign_to_container_from_value<Attribute + , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> > + : assign_to_attribute_from_value<Attribute + , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> > + {}; + + // This is called from the parse function of lexer_def_ + template <typename Iterator, typename AttributeTypes, typename HasState + , typename Idtype_, typename Idtype> + struct assign_to_attribute_from_value< + fusion::vector2<Idtype_, iterator_range<Iterator> > + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + { + static void + call(lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> const& t + , fusion::vector2<Idtype_, iterator_range<Iterator> >& attr) + { + // The type returned by the lexer_def_ parser components is a + // fusion::vector containing the token id of the matched token + // and the pair of iterators to the matched character sequence. + typedef iterator_range<Iterator> iterpair_type; + typedef fusion::vector2<Idtype_, iterator_range<Iterator> > + attribute_type; + + iterpair_type const& ip = boost::get<iterpair_type>(t.value()); + attr = attribute_type(t.id(), ip); + } + }; + + template <typename Iterator, typename AttributeTypes, typename HasState + , typename Idtype_, typename Idtype> + struct assign_to_container_from_value< + fusion::vector2<Idtype_, iterator_range<Iterator> > + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + : assign_to_attribute_from_value< + fusion::vector2<Idtype_, iterator_range<Iterator> > + , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> > + {}; + + /////////////////////////////////////////////////////////////////////////// + // Overload debug output for a single token, this integrates lexer tokens + // with Qi's simple_trace debug facilities + template <typename Iterator, typename Attribute, typename HasState + , typename Idtype> + struct token_printer_debug< + lex::lexertl::token<Iterator, Attribute, HasState, Idtype> > + { + typedef lex::lexertl::token<Iterator, Attribute, HasState, Idtype> token_type; + + template <typename Out> + static void print(Out& out, token_type const& val) + { + out << '['; + spirit::traits::print_token(out, val.value()); + out << ']'; + } + }; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp new file mode 100644 index 0000000..e128d27 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp @@ -0,0 +1,154 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + http://spirit.sourceforge.net/ + + 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_WRAP_ACTION_APR_19_2008_0103PM) +#define BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> +#include <boost/spirit/include/phoenix_scope.hpp> + +#include <boost/spirit/home/support/attributes.hpp> +#include <boost/spirit/home/lex/lexer/pass_flags.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace lex { namespace lexertl +{ + namespace detail + { + template <typename FunctionType, typename Iterator, typename Context + , typename IdType> + struct wrap_action + { + // plain functions with 5 arguments, function objects (including + // phoenix actors) are not touched at all + template <typename F> + static FunctionType call(F const& f) + { + return f; + } + + // semantic actions with 4 arguments + template <typename F> + static void arg4_action(F* f, Iterator& start, Iterator& end + , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType& id + , Context const&) + { + f(start, end, pass, id); + } + + template <typename A0, typename A1, typename A2, typename A3> + static FunctionType call(void (*f)(A0, A1, A2, A3)) + { + void (*pf)(void(*)(A0, A1, A2, A3) + , Iterator&, Iterator&, BOOST_SCOPED_ENUM(pass_flags)& + , IdType&, Context const&) = &wrap_action::arg4_action; + + using phoenix::arg_names::_1; + using phoenix::arg_names::_2; + using phoenix::arg_names::_3; + using phoenix::arg_names::_4; + using phoenix::arg_names::_5; + return phoenix::bind(pf, f, _1, _2, _3, _4, _5); + } + + // semantic actions with 3 arguments + template <typename F> + static void arg3_action(F* f, Iterator& start, Iterator& end + , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType + , Context const&) + { + f(start, end, pass); + } + + template <typename A0, typename A1, typename A2> + static FunctionType call(void (*f)(A0, A1, A2)) + { + void (*pf)(void(*)(A0, A1, A2), Iterator&, Iterator& + , BOOST_SCOPED_ENUM(pass_flags)&, IdType + , Context const&) = &wrap_action::arg3_action; + + using phoenix::arg_names::_1; + using phoenix::arg_names::_2; + using phoenix::arg_names::_3; + using phoenix::arg_names::_4; + using phoenix::arg_names::_5; + return phoenix::bind(pf, f, _1, _2, _3, _4, _5); + } + + // semantic actions with 2 arguments + template <typename F> + static void arg2_action(F* f, Iterator& start, Iterator& end + , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) + { + f (start, end); + } + + template <typename A0, typename A1> + static FunctionType call(void (*f)(A0, A1)) + { + void (*pf)(void(*)(A0, A1), Iterator&, Iterator& + , BOOST_SCOPED_ENUM(pass_flags)& + , IdType, Context const&) = &wrap_action::arg2_action; + + using phoenix::arg_names::_1; + using phoenix::arg_names::_2; + using phoenix::arg_names::_3; + using phoenix::arg_names::_4; + using phoenix::arg_names::_5; + return phoenix::bind(pf, f, _1, _2, _3, _4, _5); + } + + // we assume that either both iterators are to be passed to the + // semantic action or none iterator at all (i.e. it's not possible + // to have a lexer semantic action function taking one arguments). + + // semantic actions with 0 argument + template <typename F> + static void arg0_action(F* f, Iterator&, Iterator& + , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) + { + f(); + } + + static FunctionType call(void (*f)()) + { + void (*pf)(void(*)(), Iterator&, Iterator& + , BOOST_SCOPED_ENUM(pass_flags)& + , IdType, Context const&) = &arg0_action; + + using phoenix::arg_names::_1; + using phoenix::arg_names::_2; + using phoenix::arg_names::_3; + using phoenix::arg_names::_4; + using phoenix::arg_names::_5; + return phoenix::bind(pf, f, _1, _2, _3, _4, _5); + } + }; + + // specialization allowing to skip wrapping for lexer types not + // supporting semantic actions + template <typename Iterator, typename Context, typename Idtype> + struct wrap_action<unused_type, Iterator, Context, Idtype> + { + // plain function objects are not touched at all + template <typename F> + static F const& call(F const& f) + { + return f; + } + }; + } + +}}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/pass_flags.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/pass_flags.hpp new file mode 100644 index 0000000..6cda3ba --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/pass_flags.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_PASS_FLAGS_JUN_09_2009_0840PM) +#define BOOST_SPIRIT_LEX_PASS_FLAGS_JUN_09_2009_0840PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp> + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + BOOST_SCOPED_ENUM_START(pass_flags) + { + pass_fail = 0, // make the current match fail in retrospective + pass_normal = 1, // continue normal token matching, that's the default + pass_ignore = 2 // ignore the current token and start matching the next + }; + BOOST_SCOPED_ENUM_END + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/sequence.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/sequence.hpp new file mode 100644 index 0000000..b7fad61 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/sequence.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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(SPIRIT_LEX_SEQUENCE_MAR_28_2007_0610PM) +#define SPIRIT_LEX_SEQUENCE_MAR_28_2007_0610PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/domain.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/lex/meta_compiler.hpp> +#include <boost/spirit/home/lex/detail/sequence_function.hpp> +#include <boost/fusion/include/any.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + template <> + struct use_operator<lex::domain, proto::tag::bitwise_or> // enables | + : mpl::true_ {}; + + template <> + struct flatten_tree<lex::domain, proto::tag::bitwise_or> // flattens | + : mpl::true_ {}; + +}} + +namespace boost { namespace spirit { namespace lex +{ + template <typename Elements> + struct sequence : nary_lexer<sequence<Elements> > + { + sequence(Elements const& elements) + : elements(elements) {} + + template <typename LexerDef, typename String> + void collect(LexerDef& lexdef, String const& state + , String const& targetstate) const + { + typedef detail::sequence_collect_function<LexerDef, String> + collect_function_type; + collect_function_type f (lexdef, state, targetstate); + fusion::any(elements, f); + } + + template <typename LexerDef> + void add_actions(LexerDef& lexdef) const + { + detail::sequence_add_actions_function<LexerDef> f (lexdef); + fusion::any(elements, f); + } + + Elements elements; + }; + + /////////////////////////////////////////////////////////////////////////// + // Lexer generator: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Elements, typename Modifiers> + struct make_composite<proto::tag::bitwise_or, Elements, Modifiers> + : make_nary_composite<Elements, sequence> + {}; + +}}} // namespace boost::spirit::lex + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/string_token_def.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/string_token_def.hpp new file mode 100644 index 0000000..9eb9870 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/string_token_def.hpp @@ -0,0 +1,178 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_STRING_TOKEN_DEF_MAR_28_2007_0722PM) +#define BOOST_SPIRIT_LEX_STRING_TOKEN_DEF_MAR_28_2007_0722PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/string_traits.hpp> +#include <boost/spirit/home/lex/domain.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/lex/meta_compiler.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/add_reference.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables strings + template <typename T> + struct use_terminal<lex::domain, T + , typename enable_if<traits::is_string<T> >::type> + : mpl::true_ {}; + + // enables string(str) + template <typename CharEncoding, typename A0> + struct use_terminal<lex::domain + , terminal_ex< + tag::char_code<tag::string, CharEncoding> + , fusion::vector1<A0> > > + : traits::is_string<A0> {}; + + // enables string(str, ID) + template <typename CharEncoding, typename A0, typename A1> + struct use_terminal<lex::domain + , terminal_ex< + tag::char_code<tag::string, CharEncoding> + , fusion::vector2<A0, A1> > > + : traits::is_string<A0> {}; +}} + +namespace boost { namespace spirit { namespace lex +{ + // use string from standard character set by default +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::standard::string; +#endif + using spirit::standard::string_type; + + /////////////////////////////////////////////////////////////////////////// + // + // string_token_def + // represents a string based token definition + // + /////////////////////////////////////////////////////////////////////////// + template <typename String, typename IdType = std::size_t + , typename CharEncoding = char_encoding::standard> + struct string_token_def + : primitive_lexer<string_token_def<String, IdType, CharEncoding> > + { + typedef typename + remove_const<typename traits::char_type_of<String>::type>::type + char_type; + typedef std::basic_string<char_type> string_type; + + string_token_def(typename add_reference<String>::type str, IdType const& id) + : str_(str), id_(id), unique_id_(std::size_t(~0)) + , token_state_(std::size_t(~0)) + {} + + template <typename LexerDef, typename String_> + void collect(LexerDef& lexdef, String_ const& state + , String_ const& targetstate) const + { + std::size_t state_id = lexdef.add_state(state.c_str()); + + // If the following assertion fires you are probably trying to use + // a single string_token_def instance in more than one lexer state. + // This is not possible. Please create a separate token_def instance + // from the same regular expression for each lexer state it needs + // to be associated with. + BOOST_ASSERT( + (std::size_t(~0) == token_state_ || state_id == token_state_) && + "Can't use single string_token_def with more than one lexer state"); + + char_type const* target = targetstate.empty() ? 0 : targetstate.c_str(); + if (target) + lexdef.add_state(target); + + token_state_ = state_id; + + typedef typename LexerDef::id_type id_type; + if (IdType(~0) == id_) + id_ = IdType(lexdef.get_next_id()); + + unique_id_ = lexdef.add_token (state.c_str(), str_, id_, target); + } + + template <typename LexerDef> + void add_actions(LexerDef&) const {} + + std::size_t id() const { return id_; } + std::size_t unique_id() const { return unique_id_; } + std::size_t state() const { return token_state_; } + + string_type str_; + mutable IdType id_; + mutable std::size_t unique_id_; + mutable std::size_t token_state_; + }; + + /////////////////////////////////////////////////////////////////////////// + // Lex generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename T, typename Modifiers> + struct make_primitive<T, Modifiers + , typename enable_if<traits::is_string<T> >::type> + { + typedef typename add_const<T>::type const_string; + typedef string_token_def<const_string> result_type; + + result_type operator()( + typename add_reference<const_string>::type str, unused_type) const + { + return result_type(str, std::size_t(~0)); + } + }; + + template <typename Modifiers, typename CharEncoding, typename A0> + struct make_primitive< + terminal_ex< + tag::char_code<tag::string, CharEncoding> + , fusion::vector1<A0> > + , Modifiers> + { + typedef typename add_const<A0>::type const_string; + typedef string_token_def<const_string, std::size_t, CharEncoding> + result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args), std::size_t(~0)); + } + }; + + template <typename Modifiers, typename CharEncoding, typename A0, typename A1> + struct make_primitive< + terminal_ex< + tag::char_code<tag::string, CharEncoding> + , fusion::vector2<A0, A1> > + , Modifiers> + { + typedef typename add_const<A0>::type const_string; + typedef string_token_def<const_string, A1, CharEncoding> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type( + fusion::at_c<0>(term.args), fusion::at_c<1>(term.args)); + } + }; +}}} // namespace boost::spirit::lex + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions.hpp new file mode 100644 index 0000000..f3987c6 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions.hpp @@ -0,0 +1,205 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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(SPIRIT_LEX_SUPPORT_FUNCTIONS_JUN_08_2009_0211PM) +#define SPIRIT_LEX_SUPPORT_FUNCTIONS_JUN_08_2009_0211PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp> +#include <boost/spirit/home/lex/lexer/pass_flags.hpp> + +#include <boost/spirit/home/lex/lexer/support_functions_expression.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // The function object less_type is used by the implementation of the + // support function lex::less(). Its functionality is equivalent to flex' + // function yyless(): it returns an iterator positioned to the nth input + // character beyond the current start iterator (i.e. by assigning the + // return value to the placeholder '_end' it is possible to return all but + // the first n characters of the current token back to the input stream. + // + // This Phoenix actor is invoked whenever the function lex::less(n) is + // used inside a lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier [ _end = lex::less(4) ]; + // + // The example shows how to limit the length of the matched identifier to + // four characters. + // + // Note: the function lex::less() has no effect if used on it's own, you + // need to use the returned result in order to make use of its + // functionality. + template <typename Actor> + struct less_type + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef typename + remove_const< + typename mpl::at_c<typename Env::args_type, 4>::type + >::type + context_type; + typedef typename context_type::base_iterator_type type; + }; + + template <typename Env> + typename result<Env>::type + eval(Env const& env) const + { + typename result<Env>::type it; + return fusion::at_c<4>(env.args()).less(it, actor_()); + } + + less_type(Actor const& actor) + : actor_(actor) {} + + Actor actor_; + }; + + // The function lex::less() is used to create a Phoenix actor allowing to + // implement functionality similar to flex' function yyless(). + template <typename T> + inline typename expression::less< + typename phoenix::as_actor<T>::type + >::type const + less(T const& v) + { + return expression::less<T>::make(phoenix::as_actor<T>::convert(v)); + } + + /////////////////////////////////////////////////////////////////////////// + // The function object more_type is used by the implementation of the + // support function lex::more(). Its functionality is equivalent to flex' + // function yymore(): it tells the lexer that the next time it matches a + // rule, the corresponding token should be appended onto the current token + // value rather than replacing it. + // + // This Phoenix actor is invoked whenever the function lex::more(n) is + // used inside a lexer semantic action: + // + // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + // this->self = identifier [ lex::more() ]; + // + // The example shows how prefix the next matched token with the matched + // identifier. + struct more_type + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef void type; + }; + + template <typename Env> + void eval(Env const& env) const + { + fusion::at_c<4>(env.args()).more(); + } + }; + + // The function lex::more() is used to create a Phoenix actor allowing to + // implement functionality similar to flex' function yymore(). + //inline expression::more<mpl::void_>::type const + inline phoenix::actor<more_type> more() + { + return phoenix::actor<more_type>(); + } + + /////////////////////////////////////////////////////////////////////////// + // The function object lookahead_type is used by the implementation of the + // support function lex::lookahead(). Its functionality is needed to + // emulate the flex' lookahead operator a/b. Use lex::lookahead() inside + // of lexer semantic actions to test whether the argument to this function + // matches the current look ahead input. lex::lookahead() can be used with + // either a token id or a token_def instance as its argument. It returns + // a bool indicating whether the look ahead has been matched. + template <typename IdActor, typename StateActor> + struct lookahead_type + { + typedef mpl::true_ no_nullary; + + template <typename Env> + struct result + { + typedef bool type; + }; + + template <typename Env> + bool eval(Env const& env) const + { + return fusion::at_c<4>(env.args()). + lookahead(id_actor_(), state_actor_()); + } + + lookahead_type(IdActor const& id_actor, StateActor const& state_actor) + : id_actor_(id_actor), state_actor_(state_actor) {} + + IdActor id_actor_; + StateActor state_actor_; + }; + + // The function lex::lookahead() is used to create a Phoenix actor + // allowing to implement functionality similar to flex' lookahead operator + // a/b. + template <typename T> + inline typename expression::lookahead< + typename phoenix::as_actor<T>::type + , typename phoenix::as_actor<std::size_t>::type + >::type const + lookahead(T const& id) + { + typedef typename phoenix::as_actor<T>::type id_actor_type; + typedef typename phoenix::as_actor<std::size_t>::type state_actor_type; + + return expression::lookahead<id_actor_type, state_actor_type>::make( + phoenix::as_actor<T>::convert(id), + phoenix::as_actor<std::size_t>::convert(std::size_t(~0))); + } + + template <typename Attribute, typename Char, typename Idtype> + inline typename expression::lookahead< + typename phoenix::as_actor<Idtype>::type + , typename phoenix::as_actor<std::size_t>::type + >::type const + lookahead(token_def<Attribute, Char, Idtype> const& tok) + { + typedef typename phoenix::as_actor<Idtype>::type id_actor_type; + typedef typename phoenix::as_actor<std::size_t>::type state_actor_type; + + std::size_t state = tok.state(); + + // The following assertion fires if you pass a token_def instance to + // lex::lookahead without first associating this instance with the + // lexer. + BOOST_ASSERT(std::size_t(~0) != state && + "token_def instance not associated with lexer yet"); + + return expression::lookahead<id_actor_type, state_actor_type>::make( + phoenix::as_actor<Idtype>::convert(tok.id()), + phoenix::as_actor<std::size_t>::convert(state)); + } + + /////////////////////////////////////////////////////////////////////////// + inline BOOST_SCOPED_ENUM(pass_flags) ignore() + { + return pass_flags::pass_ignore; + } + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions_expression.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions_expression.hpp new file mode 100644 index 0000000..613a4a4 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions_expression.hpp @@ -0,0 +1,135 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Thomas Heller +// +// 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(SPIRIT_LEX_SUPPORT_FUNCTIONS_EXPRESSION_MAR_22_2011_0711PM) +#define SPIRIT_LEX_SUPPORT_FUNCTIONS_EXPRESSION_MAR_22_2011_0711PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/include/phoenix_core.hpp> + +namespace boost { namespace spirit { namespace lex +{ + template <typename> struct less_type; + struct more_type; + template <typename, typename> struct lookahead_type; +}}} + +/////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_SPIRIT_USE_PHOENIX_V3 + +namespace boost { namespace spirit { namespace lex +{ + namespace expression + { + template <typename Eval> + struct less + { + typedef phoenix::actor<lex::less_type<Eval> > type; + + static type make(Eval const & eval) + { + return lex::less_type<Eval>(eval); + } + }; + + template <typename IdType, typename State> + struct lookahead + { + typedef phoenix::actor<lex::lookahead_type<IdType, State> > type; + + static type make(IdType const & id_type, State const & state) + { + return lex::lookahead_type<IdType, State>(id_type, state); + } + }; + } +}}} + +#else // BOOST_SPIRIT_USE_PHOENIX_V3 + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(less) + , (boost::phoenix::meta_grammar) +) + +BOOST_PHOENIX_DEFINE_EXPRESSION( + (boost)(spirit)(lex)(lookahead) + , (boost::phoenix::meta_grammar) + (boost::phoenix::meta_grammar) +) + +namespace boost { namespace phoenix +{ + + namespace result_of + { + template <> + struct is_nullary<custom_terminal<boost::spirit::lex::more_type> > + : mpl::false_ + {}; + } + + template <typename Dummy> + struct is_custom_terminal<boost::spirit::lex::more_type, Dummy> : mpl::true_ {}; + + template <typename Dummy> + struct custom_terminal<boost::spirit::lex::more_type, Dummy> + : proto::call< + v2_eval( + proto::make<boost::spirit::lex::more_type()> + , proto::call<functional::env(proto::_state)> + ) + > + {}; + + + template <typename Dummy> + struct is_nullary::when<spirit::lex::rule::less, Dummy> + : proto::make<mpl::false_()> + {}; + + template <typename Dummy> + struct default_actions::when<spirit::lex::rule::less, Dummy> + : proto::call< + v2_eval( + proto::make< + spirit::lex::less_type<proto::_child0>(proto::_child0) + > + , _env + ) + > + {}; + + template <typename Dummy> + struct is_nullary::when<spirit::lex::rule::lookahead, Dummy> + : proto::make<mpl::false_()> + {}; + + template <typename Dummy> + struct default_actions::when<spirit::lex::rule::lookahead, Dummy> + : proto::call< + v2_eval( + proto::make< + spirit::lex::lookahead_type< + proto::_child0 + , proto::_child1 + >( + proto::_child0 + , proto::_child1 + ) + > + , _env + ) + > + {}; +}} + +#endif // BOOST_SPIRIT_USE_PHOENIX_V3 + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/terminals.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/terminals.hpp new file mode 100644 index 0000000..b5059cc --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/terminals.hpp @@ -0,0 +1,23 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_TERMINALS_APR_20_2009_0550PM) +#define BOOST_SPIRIT_LEX_TERMINALS_APR_20_2009_0550PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/common_terminals.hpp> + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // Define a more convenient name for an omitted token attribute type + typedef spirit::omit_type omit; + using spirit::omit_type; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer/token_def.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/token_def.hpp new file mode 100644 index 0000000..1bd2534 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/token_def.hpp @@ -0,0 +1,246 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_TOKEN_DEF_MAR_13_2007_0145PM) +#define BOOST_SPIRIT_LEX_TOKEN_DEF_MAR_13_2007_0145PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/unused.hpp> +#include <boost/spirit/home/support/argument.hpp> +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/detail/construct.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/spirit/home/lex/reference.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/lex/lexer/terminals.hpp> + +#include <boost/fusion/include/vector.hpp> +#include <boost/mpl/if.hpp> +#include <boost/detail/iterator.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/variant.hpp> + +#include <string> +#include <cstdlib> + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning +#endif + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // This component represents a token definition + /////////////////////////////////////////////////////////////////////////// + template<typename Attribute = unused_type + , typename Char = char + , typename Idtype = std::size_t> + struct token_def + : proto::extends< + typename proto::terminal< + lex::reference<token_def<Attribute, Char, Idtype> const, Idtype> + >::type + , token_def<Attribute, Char, Idtype> > + , qi::parser<token_def<Attribute, Char, Idtype> > + , lex::lexer_type<token_def<Attribute, Char, Idtype> > + { + private: + // initialize proto base class + typedef lex::reference<token_def const, Idtype> reference_; + typedef typename proto::terminal<reference_>::type terminal_type; + typedef proto::extends<terminal_type, token_def> proto_base_type; + + static std::size_t const all_states_id = static_cast<std::size_t>(-2); + + public: + // Qi interface: meta-function calculating parser return type + template <typename Context, typename Iterator> + struct attribute + { + // The return value of the token_def is either the specified + // attribute type, or the pair of iterators from the match of the + // corresponding token (if no attribute type has been specified), + // or unused_type (if omit has been specified). + typedef typename Iterator::base_iterator_type iterator_type; + typedef typename mpl::if_< + traits::not_is_unused<Attribute> + , typename mpl::if_< + is_same<Attribute, lex::omit>, unused_type, Attribute + >::type + , iterator_range<iterator_type> + >::type type; + }; + + public: + // Qi interface: parse functionality + template <typename Iterator, typename Context + , typename Skipper, typename Attribute_> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute_& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + + // If the following assertion fires you probably forgot to + // associate this token definition with a lexer instance. + BOOST_ASSERT(std::size_t(~0) != token_state_); + + token_type const& t = *first; + if (token_id_ == t.id() && + (all_states_id == token_state_ || token_state_ == t.state())) + { + spirit::traits::assign_to(t, attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + if (0 == def_.which()) + return info("token_def", boost::get<string_type>(def_)); + + return info("token_def", boost::get<char_type>(def_)); + } + + /////////////////////////////////////////////////////////////////////// + // Lex interface: collect token definitions and put it into the + // provided lexer def + template <typename LexerDef, typename String> + void collect(LexerDef& lexdef, String const& state + , String const& targetstate) const + { + std::size_t state_id = lexdef.add_state(state.c_str()); + + // If the following assertion fires you are probably trying to use + // a single token_def instance in more than one lexer state. This + // is not possible. Please create a separate token_def instance + // from the same regular expression for each lexer state it needs + // to be associated with. + BOOST_ASSERT( + (std::size_t(~0) == token_state_ || state_id == token_state_) && + "Can't use single token_def with more than one lexer state"); + + char_type const* target = targetstate.empty() ? 0 : targetstate.c_str(); + if (target) + lexdef.add_state(target); + + token_state_ = state_id; + if (0 == token_id_) + token_id_ = lexdef.get_next_id(); + + if (0 == def_.which()) { + unique_id_ = lexdef.add_token(state.c_str() + , boost::get<string_type>(def_), token_id_, target); + } + else { + unique_id_ = lexdef.add_token(state.c_str() + , boost::get<char_type>(def_), token_id_, target); + } + } + + template <typename LexerDef> + void add_actions(LexerDef&) const {} + + public: + typedef Char char_type; + typedef Idtype id_type; + typedef std::basic_string<char_type> string_type; + + // Lex interface: constructing token definitions + token_def() + : proto_base_type(terminal_type::make(reference_(*this))) + , def_('\0'), token_id_() + , unique_id_(std::size_t(~0)), token_state_(std::size_t(~0)) {} + + token_def(token_def const& rhs) + : proto_base_type(terminal_type::make(reference_(*this))) + , def_(rhs.def_), token_id_(rhs.token_id_) + , unique_id_(rhs.unique_id_), token_state_(rhs.token_state_) {} + + explicit token_def(char_type def_, Idtype id_ = Idtype()) + : proto_base_type(terminal_type::make(reference_(*this))) + , def_(def_) + , token_id_(Idtype() == id_ ? Idtype(def_) : id_) + , unique_id_(std::size_t(~0)), token_state_(std::size_t(~0)) {} + + explicit token_def(string_type const& def_, Idtype id_ = Idtype()) + : proto_base_type(terminal_type::make(reference_(*this))) + , def_(def_), token_id_(id_) + , unique_id_(std::size_t(~0)), token_state_(std::size_t(~0)) {} + + template <typename String> + token_def& operator= (String const& definition) + { + def_ = definition; + token_id_ = Idtype(); + unique_id_ = std::size_t(~0); + token_state_ = std::size_t(~0); + return *this; + } + token_def& operator= (token_def const& rhs) + { + def_ = rhs.def_; + token_id_ = rhs.token_id_; + unique_id_ = rhs.unique_id_; + token_state_ = rhs.token_state_; + return *this; + } + + // general accessors + Idtype const& id() const { return token_id_; } + void id(Idtype const& id) { token_id_ = id; } + std::size_t unique_id() const { return unique_id_; } + + string_type definition() const + { + return (0 == def_.which()) ? + boost::get<string_type>(def_) : + string_type(1, boost::get<char_type>(def_)); + } + std::size_t state() const { return token_state_; } + + private: + variant<string_type, char_type> def_; + mutable Idtype token_id_; + mutable std::size_t unique_id_; + mutable std::size_t token_state_; + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template<typename Attribute, typename Char, typename Idtype + , typename Attr, typename Context, typename Iterator> + struct handles_container< + lex::token_def<Attribute, Char, Idtype>, Attr, Context, Iterator> + : traits::is_container< + typename attribute_of< + lex::token_def<Attribute, Char, Idtype>, Context, Iterator + >::type> + {}; +}}} + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer_lexertl.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer_lexertl.hpp new file mode 100644 index 0000000..0706bd9 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer_lexertl.hpp @@ -0,0 +1,18 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_LEXERTL_MAR_17_2007_1008PM) +#define BOOST_SPIRIT_LEX_LEXERTL_MAR_17_2007_1008PM + +#if defined(_MSC_VER) +#pragma once +#endif + +// These includes make available everything needed to use lexertl either +// standalone or as a lexer component for spirit::qi +#include <boost/spirit/home/lex.hpp> +#include <boost/spirit/home/lex/lexer/lexertl/lexer.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/lexer_type.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/lexer_type.hpp new file mode 100644 index 0000000..e58bce0 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer_type.hpp @@ -0,0 +1,100 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 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_LEXER_TYPE_APR_20_2009_0759PM) +#define BOOST_SPIRIT_LEXER_TYPE_APR_20_2009_0759PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/mpl/has_xxx.hpp> +#include <boost/spirit/home/lex/domain.hpp> + +namespace boost { namespace spirit { namespace lex +{ + template <typename Derived> + struct lexer_type + { + struct lexer_id; + typedef Derived derived_type; + typedef lex::domain domain; + + // Requirement: l.collect(def, state, targetstate) -> void + // + // l: a lexer component + // def: token definition container + // state: lexer state this token definition needs to be added to + // targetstate: an optional lexer state the lexer should be switched + // into after matching this token + + Derived const& derived() const + { + return *static_cast<Derived const*>(this); + } + }; + + template <typename Derived> + struct primitive_lexer : lexer_type<Derived> + { + struct primitive_lexer_id; + }; + + template <typename Derived> + struct unary_lexer : lexer_type<Derived> + { + struct unary_lexer_id; + + // Requirement: l.subject -> subject lexer component + // + // l: a unary lexer component + + // Requirement: L::subject_type -> subject lexer component type + // + // L: a unary lexer component type + }; + + template <typename Derived> + struct nary_lexer : lexer_type<Derived> + { + struct nary_lexer_id; + + // Requirement: l.elements -> fusion sequence + // + // l: a composite lexer component + + // Requirement: L::elements_type -> fusion sequence + // + // L: a composite lexer component type + }; + +}}} + +namespace boost { namespace spirit { namespace traits // classification +{ + namespace detail + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(lexer_id) + BOOST_MPL_HAS_XXX_TRAIT_DEF(primitive_lexer_id) + BOOST_MPL_HAS_XXX_TRAIT_DEF(unary_lexer_id) + BOOST_MPL_HAS_XXX_TRAIT_DEF(nary_lexer_id) + } + + template <typename T> + struct is_lexer : detail::has_lexer_id<T> {}; + + template <typename T> + struct is_primitive_lexer : detail::has_primitive_lexer_id<T> {}; + + template <typename T> + struct is_unary_lexer : detail::has_unary_lexer_id<T> {}; + + template <typename T> + struct is_nary_lexer : detail::has_nary_lexer_id<T> {}; + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/meta_compiler.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/meta_compiler.hpp new file mode 100644 index 0000000..6e13d37 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/meta_compiler.hpp @@ -0,0 +1,104 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 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_LEX_META_COMPILER_APR_20_2009_0756PM) +#define BOOST_SPIRIT_LEX_META_COMPILER_APR_20_2009_0756PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/meta_compiler.hpp> +#include <boost/spirit/home/lex/domain.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/utility/enable_if.hpp> + +namespace boost { namespace spirit +{ + template <typename T> + struct use_terminal<lex::domain, T + , typename enable_if<traits::is_lexer<T> >::type> // enables lexers + : mpl::true_ {}; + + namespace lex + { + template <typename T, typename Modifiers, typename Enable = void> + struct make_primitive // by default, return it as-is + { + typedef T result_type; + + template <typename T_> + T_& operator()(T_& val, unused_type) const + { + return val; + } + + template <typename T_> + T_ const& operator()(T_ const& val, unused_type) const + { + return val; + } + }; + + template <typename Tag, typename Elements + , typename Modifiers, typename Enable = void> + struct make_composite; + } + + // Lex primitive meta-compiler + template <> + struct make_component<lex::domain, proto::tag::terminal> + { + template <typename Sig> + struct result; + + template <typename This, typename Elements, typename Modifiers> + struct result<This(Elements, Modifiers)> + { + typedef typename lex::make_primitive< + typename remove_const<typename Elements::car_type>::type, + typename remove_reference<Modifiers>::type>::result_type + type; + }; + + template <typename Elements, typename Modifiers> + typename result<make_component(Elements, Modifiers)>::type + operator()(Elements const& elements, Modifiers const& modifiers) const + { + typedef typename remove_const<typename Elements::car_type>::type term; + return lex::make_primitive<term, Modifiers>()(elements.car, modifiers); + } + }; + + // Lex composite meta-compiler + template <typename Tag> + struct make_component<lex::domain, Tag> + { + template <typename Sig> + struct result; + + template <typename This, typename Elements, typename Modifiers> + struct result<This(Elements, Modifiers)> + { + typedef typename + lex::make_composite<Tag, Elements + , typename remove_reference<Modifiers>::type>::result_type + type; + }; + + template <typename Elements, typename Modifiers> + typename result<make_component(Elements, Modifiers)>::type + operator()(Elements const& elements, Modifiers const& modifiers) const + { + return lex::make_composite<Tag, Elements, Modifiers>()( + elements, modifiers); + } + }; + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi.hpp new file mode 100644 index 0000000..3b4e704 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEXER_QI_APR_21_2009_0205PM) +#define BOOST_SPIRIT_LEXER_QI_APR_21_2009_0205PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/qi/state_switcher.hpp> +#include <boost/spirit/home/lex/qi/in_state.hpp> +#include <boost/spirit/home/lex/qi/plain_token.hpp> +#include <boost/spirit/home/lex/qi/plain_tokenid.hpp> +#include <boost/spirit/home/lex/qi/plain_tokenid_mask.hpp> +#include <boost/spirit/home/lex/qi/plain_raw_token.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi/in_state.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi/in_state.hpp new file mode 100644 index 0000000..fe7580b --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi/in_state.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_IN_STATE_OCT_09_2007_0748PM) +#define BOOST_SPIRIT_LEX_IN_STATE_OCT_09_2007_0748PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/proto/core.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace qi +{ + /////////////////////////////////////////////////////////////////////////// + // The following is a helper template allowing to use the in_state()[] as + // a skip parser + /////////////////////////////////////////////////////////////////////////// + template <typename Skipper, typename String = char const*> + struct in_state_skipper + : proto::subscript< + typename proto::terminal< + terminal_ex<tag::in_state, fusion::vector1<String> > + >::type + , Skipper + >::type {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_raw_token.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_raw_token.hpp new file mode 100644 index 0000000..ebe980d --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_raw_token.hpp @@ -0,0 +1,149 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_PLAIN_RAW_TOKEN_JUN_03_2011_0853PM) +#define BOOST_SPIRIT_LEX_PLAIN_RAW_TOKEN_JUN_03_2011_0853PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/qi/detail/attributes.hpp> +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/domain.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/meta_compiler.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/mpl/or.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/lexical_cast.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables raw_token + template <> + struct use_terminal<qi::domain, tag::raw_token> + : mpl::true_ {}; + + // enables raw_token(id) + template <typename A0> + struct use_terminal<qi::domain + , terminal_ex<tag::raw_token, fusion::vector1<A0> > + > : mpl::or_<is_integral<A0>, is_enum<A0> > {}; + + // enables *lazy* raw_token(id) + template <> + struct use_lazy_terminal< + qi::domain, tag::raw_token, 1 + > : mpl::true_ {}; +}} + +namespace boost { namespace spirit { namespace qi +{ +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::raw_token; +#endif + using spirit::raw_token_type; + + /////////////////////////////////////////////////////////////////////////// + template <typename TokenId> + struct plain_raw_token + : primitive_parser<plain_raw_token<TokenId> > + { + template <typename Context, typename Iterator> + struct attribute + { + typedef unused_type type; + }; + + plain_raw_token(TokenId const& id) + : id(id) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + // simply match the token id with the id this component has + // been initialized with + + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + typedef typename token_type::id_type id_type; + + token_type const& t = *first; + if (id_type(~0) == id_type(id) || id_type(id) == t.id()) { + spirit::traits::assign_to(t, attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("raw_token", + "raw_token(" + boost::lexical_cast<utf8_string>(id) + ")"); + } + + TokenId id; + }; + + /////////////////////////////////////////////////////////////////////////// + // Parser generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Modifiers> + struct make_primitive<tag::raw_token, Modifiers> + { + typedef plain_raw_token<std::size_t> result_type; + + result_type operator()(unused_type, unused_type) const + { + return result_type(std::size_t(~0)); + } + }; + + template <typename Modifiers, typename TokenId> + struct make_primitive<terminal_ex<tag::raw_token, fusion::vector1<TokenId> > + , Modifiers> + { + typedef plain_raw_token<TokenId> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args)); + } + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template<typename Idtype, typename Attr, typename Context, typename Iterator> + struct handles_container<qi::plain_raw_token<Idtype>, Attr, Context, Iterator> + : mpl::true_ + {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_token.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_token.hpp new file mode 100644 index 0000000..b77e2a9 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_token.hpp @@ -0,0 +1,242 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_PLAIN_TOKEN_NOV_11_2007_0451PM) +#define BOOST_SPIRIT_LEX_PLAIN_TOKEN_NOV_11_2007_0451PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/qi/detail/attributes.hpp> +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/domain.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/meta_compiler.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/and.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/lexical_cast.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables token + template <> + struct use_terminal<qi::domain, tag::token> + : mpl::true_ {}; + + // enables token(id) + template <typename A0> + struct use_terminal<qi::domain + , terminal_ex<tag::token, fusion::vector1<A0> > + > : mpl::or_<is_integral<A0>, is_enum<A0> > {}; + + // enables token(idmin, idmax) + template <typename A0, typename A1> + struct use_terminal<qi::domain + , terminal_ex<tag::token, fusion::vector2<A0, A1> > + > : mpl::and_< + mpl::or_<is_integral<A0>, is_enum<A0> > + , mpl::or_<is_integral<A1>, is_enum<A1> > + > {}; + + // enables *lazy* token(id) + template <> + struct use_lazy_terminal< + qi::domain, tag::token, 1 + > : mpl::true_ {}; + + // enables *lazy* token(idmin, idmax) + template <> + struct use_lazy_terminal< + qi::domain, tag::token, 2 + > : mpl::true_ {}; +}} + +namespace boost { namespace spirit { namespace qi +{ +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::token; +#endif + using spirit::token_type; + + /////////////////////////////////////////////////////////////////////////// + template <typename TokenId> + struct plain_token + : primitive_parser<plain_token<TokenId> > + { + template <typename Context, typename Iterator> + struct attribute + { + typedef typename Iterator::base_iterator_type iterator_type; + typedef iterator_range<iterator_type> type; + }; + + plain_token(TokenId const& id) + : id(id) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + // simply match the token id with the id this component has + // been initialized with + + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + typedef typename token_type::id_type id_type; + + token_type const& t = *first; + if (id_type(~0) == id_type(id) || id_type(id) == t.id()) { + spirit::traits::assign_to(t, attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("token", + "token(" + boost::lexical_cast<utf8_string>(id) + ")"); + } + + TokenId id; + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename TokenId> + struct plain_token_range + : primitive_parser<plain_token_range<TokenId> > + { + template <typename Context, typename Iterator> + struct attribute + { + typedef typename Iterator::base_iterator_type iterator_type; + typedef iterator_range<iterator_type> type; + }; + + plain_token_range(TokenId const& idmin, TokenId const& idmax) + : idmin(idmin), idmax(idmax) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + // simply match the token id with the id this component has + // been initialized with + + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + typedef typename token_type::id_type id_type; + + token_type const& t = *first; + if (id_type(idmin) >= t.id() && id_type(idmin) <= t.id()) + { + spirit::traits::assign_to(t, attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("token_range" + , "token(" + + boost::lexical_cast<utf8_string>(idmin) + ", " + + boost::lexical_cast<utf8_string>(idmax) + ")" + ); + return info("token_range"); + } + + TokenId idmin, idmax; + }; + + /////////////////////////////////////////////////////////////////////////// + // Parser generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Modifiers> + struct make_primitive<tag::token, Modifiers> + { + typedef plain_token<std::size_t> result_type; + + result_type operator()(unused_type, unused_type) const + { + return result_type(std::size_t(~0)); + } + }; + + template <typename Modifiers, typename TokenId> + struct make_primitive<terminal_ex<tag::token, fusion::vector1<TokenId> > + , Modifiers> + { + typedef plain_token<TokenId> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args)); + } + }; + + template <typename Modifiers, typename TokenId> + struct make_primitive<terminal_ex<tag::token, fusion::vector2<TokenId, TokenId> > + , Modifiers> + { + typedef plain_token_range<TokenId> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args) + , fusion::at_c<1>(term.args)); + } + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template<typename Idtype, typename Attr, typename Context, typename Iterator> + struct handles_container<qi::plain_token<Idtype>, Attr, Context, Iterator> + : mpl::true_ + {}; + + template<typename Idtype, typename Attr, typename Context, typename Iterator> + struct handles_container<qi::plain_token_range<Idtype>, Attr, Context, Iterator> + : mpl::true_ + {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_tokenid.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_tokenid.hpp new file mode 100644 index 0000000..7a70c77 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_tokenid.hpp @@ -0,0 +1,242 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_PLAIN_TOKENID_NOV_26_2010_0944AM) +#define BOOST_SPIRIT_LEX_PLAIN_TOKENID_NOV_26_2010_0944AM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/qi/detail/attributes.hpp> +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/domain.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/meta_compiler.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/and.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/lexical_cast.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables tokenid + template <> + struct use_terminal<qi::domain, tag::tokenid> + : mpl::true_ {}; + + // enables tokenid(id) + template <typename A0> + struct use_terminal<qi::domain + , terminal_ex<tag::tokenid, fusion::vector1<A0> > + > : mpl::or_<is_integral<A0>, is_enum<A0> > {}; + + // enables tokenid(idmin, idmax) + template <typename A0, typename A1> + struct use_terminal<qi::domain + , terminal_ex<tag::tokenid, fusion::vector2<A0, A1> > + > : mpl::and_< + mpl::or_<is_integral<A0>, is_enum<A0> > + , mpl::or_<is_integral<A1>, is_enum<A1> > + > {}; + + // enables *lazy* tokenid(id) + template <> + struct use_lazy_terminal< + qi::domain, tag::tokenid, 1 + > : mpl::true_ {}; + + // enables *lazy* tokenid(idmin, idmax) + template <> + struct use_lazy_terminal< + qi::domain, tag::tokenid, 2 + > : mpl::true_ {}; +}} + +namespace boost { namespace spirit { namespace qi +{ +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::tokenid; +#endif + using spirit::tokenid_type; + + /////////////////////////////////////////////////////////////////////////// + // The plain_tokenid represents a simple token defined by the lexer inside + // a Qi grammar. The difference to plain_token is that it exposes the + // matched token id instead of the iterator_range of the matched input. + template <typename TokenId> + struct plain_tokenid + : primitive_parser<plain_tokenid<TokenId> > + { + template <typename Context, typename Iterator> + struct attribute + { + typedef TokenId type; + }; + + plain_tokenid(TokenId const& id) + : id(id) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + // simply match the token id with the id this component has + // been initialized with + + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + typedef typename token_type::id_type id_type; + + token_type const& t = *first; + if (id_type(~0) == id_type(id) || id_type(id) == t.id()) { + spirit::traits::assign_to(id, attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("tokenid", + "tokenid(" + boost::lexical_cast<utf8_string>(id) + ")"); + } + + TokenId id; + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename TokenId> + struct plain_tokenid_range + : primitive_parser<plain_tokenid_range<TokenId> > + { + template <typename Context, typename Iterator> + struct attribute + { + typedef TokenId type; + }; + + plain_tokenid_range(TokenId const& idmin, TokenId const& idmax) + : idmin(idmin), idmax(idmax) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + // simply match the token id with the id this component has + // been initialized with + + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + typedef typename token_type::id_type id_type; + + token_type const& t = *first; + if (id_type(idmin) >= t.id() && id_type(idmin) <= t.id()) + { + spirit::traits::assign_to(t.id(), attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("tokenid_range" + , "token(" + + boost::lexical_cast<utf8_string>(idmin) + ", " + + boost::lexical_cast<utf8_string>(idmax) + ")" + ); + } + + TokenId idmin, idmax; + }; + + /////////////////////////////////////////////////////////////////////////// + // Parser generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Modifiers> + struct make_primitive<tag::tokenid, Modifiers> + { + typedef plain_tokenid<std::size_t> result_type; + + result_type operator()(unused_type, unused_type) const + { + return result_type(std::size_t(~0)); + } + }; + + template <typename Modifiers, typename TokenId> + struct make_primitive<terminal_ex<tag::tokenid, fusion::vector1<TokenId> > + , Modifiers> + { + typedef plain_tokenid<TokenId> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args)); + } + }; + + template <typename Modifiers, typename TokenId> + struct make_primitive<terminal_ex<tag::tokenid, fusion::vector2<TokenId, TokenId> > + , Modifiers> + { + typedef plain_tokenid_range<TokenId> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args) + , fusion::at_c<1>(term.args)); + } + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template<typename Idtype, typename Attr, typename Context, typename Iterator> + struct handles_container<qi::plain_tokenid<Idtype>, Attr, Context, Iterator> + : mpl::true_ + {}; + + template<typename Idtype, typename Attr, typename Context, typename Iterator> + struct handles_container<qi::plain_tokenid_range<Idtype>, Attr, Context, Iterator> + : mpl::true_ + {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_tokenid_mask.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_tokenid_mask.hpp new file mode 100644 index 0000000..92ac126 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi/plain_tokenid_mask.hpp @@ -0,0 +1,138 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEX_PLAIN_TOKENID_MASK_JUN_03_2011_0929PM) +#define BOOST_SPIRIT_LEX_PLAIN_TOKENID_MASK_JUN_03_2011_0929PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/qi/detail/attributes.hpp> +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/domain.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/meta_compiler.hpp> +#include <boost/spirit/home/qi/detail/assign_to.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/mpl/or.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/lexical_cast.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables tokenid_mask(id) + template <typename A0> + struct use_terminal<qi::domain + , terminal_ex<tag::tokenid_mask, fusion::vector1<A0> > + > : mpl::or_<is_integral<A0>, is_enum<A0> > {}; + + // enables *lazy* tokenid_mask(id) + template <> + struct use_lazy_terminal< + qi::domain, tag::tokenid_mask, 1 + > : mpl::true_ {}; +}} + +namespace boost { namespace spirit { namespace qi +{ +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::tokenid_mask; +#endif + using spirit::tokenid_mask_type; + + /////////////////////////////////////////////////////////////////////////// + // The plain_tokenid represents a simple token defined by the lexer inside + // a Qi grammar. The difference to plain_token is that it exposes the + // matched token id instead of the iterator_range of the matched input. + // Additionally it applies the given mask to the matched token id. + template <typename Mask> + struct plain_tokenid_mask + : primitive_parser<plain_tokenid_mask<Mask> > + { + template <typename Context, typename Iterator> + struct attribute + { + typedef Mask type; + }; + + plain_tokenid_mask(Mask const& mask) + : mask(mask) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + if (first != last) { + // simply match the token id with the mask this component has + // been initialized with + + typedef typename + boost::detail::iterator_traits<Iterator>::value_type + token_type; + typedef typename token_type::id_type id_type; + + token_type const& t = *first; + if ((t.id() & mask) == id_type(mask)) + { + spirit::traits::assign_to(t.id(), attr); + ++first; + return true; + } + } + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("tokenid_mask", + "tokenid_mask(" + boost::lexical_cast<utf8_string>(mask) + ")"); + } + + Mask mask; + }; + + /////////////////////////////////////////////////////////////////////////// + // Parser generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Modifiers, typename Mask> + struct make_primitive<terminal_ex<tag::tokenid_mask, fusion::vector1<Mask> > + , Modifiers> + { + typedef plain_tokenid_mask<Mask> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args)); + } + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template<typename Mask, typename Attr, typename Context, typename Iterator> + struct handles_container<qi::plain_tokenid_mask<Mask>, Attr, Context, Iterator> + : mpl::true_ + {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/qi/state_switcher.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/qi/state_switcher.hpp new file mode 100644 index 0000000..a8fd55a --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/qi/state_switcher.hpp @@ -0,0 +1,270 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2010 Bryce Lelbach +// +// 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_LEX_STATE_SWITCHER_SEP_23_2007_0714PM) +#define BOOST_SPIRIT_LEX_STATE_SWITCHER_SEP_23_2007_0714PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/qi/detail/attributes.hpp> +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/string_traits.hpp> +#include <boost/spirit/home/support/has_semantic_action.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/domain.hpp> +#include <boost/spirit/home/qi/parser.hpp> +#include <boost/spirit/home/qi/meta_compiler.hpp> +#include <boost/mpl/print.hpp> + +namespace boost { namespace spirit +{ + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + // enables set_state(s) + template <typename A0> + struct use_terminal<qi::domain + , terminal_ex<tag::set_state, fusion::vector1<A0> > + > : traits::is_string<A0> {}; + + // enables *lazy* set_state(s) + template <> + struct use_lazy_terminal< + qi::domain, tag::set_state, 1 + > : mpl::true_ {}; + + // enables in_state(s)[p] + template <typename A0> + struct use_directive<qi::domain + , terminal_ex<tag::in_state, fusion::vector1<A0> > + > : traits::is_string<A0> {}; + + // enables *lazy* in_state(s)[p] + template <> + struct use_lazy_directive< + qi::domain, tag::in_state, 1 + > : mpl::true_ {}; + +}} + +namespace boost { namespace spirit { namespace qi +{ +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::set_state; + using spirit::in_state; +#endif + using spirit::set_state_type; + using spirit::in_state_type; + + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + template <typename Iterator> + inline std::size_t + set_lexer_state(Iterator& it, std::size_t state) + { + return it.set_state(state); + } + + template <typename Iterator, typename Char> + inline std::size_t + set_lexer_state(Iterator& it, Char const* statename) + { + std::size_t state = it.map_state(statename); + + // If the following assertion fires you probably used the + // set_state(...) or in_state(...)[...] lexer state switcher with + // a lexer state name unknown to the lexer (no token definitions + // have been associated with this lexer state). + BOOST_ASSERT(std::size_t(~0) != state); + return it.set_state(state); + } + } + + /////////////////////////////////////////////////////////////////////////// + // Parser switching the state of the underlying lexer component. + // This parser gets used for the set_state(...) construct. + /////////////////////////////////////////////////////////////////////////// + template <typename State> + struct state_switcher + : primitive_parser<state_switcher<State> > + { + typedef typename + remove_const<typename traits::char_type_of<State>::type>::type + char_type; + typedef std::basic_string<char_type> string_type; + + template <typename Context, typename Iterator> + struct attribute + { + typedef unused_type type; + }; + + state_switcher(char_type const* state) + : state(state) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& /*attr*/) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + // just switch the state and return success + detail::set_lexer_state(first, state.c_str()); + return true; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("set_state"); + } + + string_type state; + }; + + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + template <typename Iterator> + struct reset_state_on_exit + { + template <typename State> + reset_state_on_exit(Iterator& it_, State state_) + : it(it_) + , state(set_lexer_state(it_, traits::get_c_string(state_))) + {} + + ~reset_state_on_exit() + { + // reset the state of the underlying lexer instance + set_lexer_state(it, state); + } + + Iterator& it; + std::size_t state; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + reset_state_on_exit& operator= (reset_state_on_exit const&); + }; + } + + /////////////////////////////////////////////////////////////////////////// + // Parser, which switches the state of the underlying lexer component + // for the execution of the embedded sub-parser, switching the state back + // afterwards. This parser gets used for the in_state(...)[p] construct. + /////////////////////////////////////////////////////////////////////////// + template <typename Subject, typename State> + struct state_switcher_context + : unary_parser<state_switcher_context<Subject, State> > + { + typedef Subject subject_type; + typedef typename traits::char_type_of<State>::type char_type; + typedef typename remove_const<char_type>::type non_const_char_type; + + template <typename Context, typename Iterator> + struct attribute + { + typedef typename + traits::attribute_of<subject_type, Context, Iterator>::type + type; + }; + + state_switcher_context(Subject const& subject + , typename add_reference<State>::type state) + : subject(subject), state(state) {} + + // The following conversion constructors are needed to make the + // in_state_switcher template usable + template <typename String> + state_switcher_context( + state_switcher_context<Subject, String> const& rhs) + : subject(rhs.subject), state(traits::get_c_string(rhs.state)) {} + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& context, Skipper const& skipper + , Attribute& attr) const + { + qi::skip_over(first, last, skipper); // always do a pre-skip + + // the state has to be reset at exit in any case + detail::reset_state_on_exit<Iterator> guard(first, state); + return subject.parse(first, last, context, skipper, attr); + } + + template <typename Context> + info what(Context& context) const + { + return info("in_state", subject.what(context)); + } + + Subject subject; + State state; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + state_switcher_context& operator= (state_switcher_context const&); + }; + + /////////////////////////////////////////////////////////////////////////// + // Parser generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Modifiers, typename State> + struct make_primitive<terminal_ex<tag::set_state, fusion::vector1<State> > + , Modifiers, typename enable_if<traits::is_string<State> >::type> + { + typedef typename add_const<State>::type const_string; + typedef state_switcher<const_string> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(traits::get_c_string(fusion::at_c<0>(term.args))); + } + }; + + template <typename State, typename Subject, typename Modifiers> + struct make_directive<terminal_ex<tag::in_state, fusion::vector1<State> > + , Subject, Modifiers> + { + typedef typename add_const<State>::type const_string; + typedef state_switcher_context<Subject, const_string> result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, Subject const& subject + , unused_type) const + { + return result_type(subject, fusion::at_c<0>(term.args)); + } + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Subject, typename State> + struct has_semantic_action<qi::state_switcher_context<Subject, State> > + : unary_has_semantic_action<Subject> {}; + + /////////////////////////////////////////////////////////////////////////// + template <typename Subject, typename State, typename Attribute + , typename Context, typename Iterator> + struct handles_container<qi::state_switcher_context<Subject, State> + , Attribute, Context, Iterator> + : unary_handles_container<Subject, Attribute, Context, Iterator> {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/reference.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/reference.hpp new file mode 100644 index 0000000..d1aaabf --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/reference.hpp @@ -0,0 +1,85 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 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_LEX_REFERENCE_APR_20_2009_0827AM) +#define BOOST_SPIRIT_LEX_REFERENCE_APR_20_2009_0827AM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/lex/meta_compiler.hpp> +#include <boost/spirit/home/lex/lexer_type.hpp> +#include <boost/spirit/home/qi/reference.hpp> +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/support/handles_container.hpp> +#include <boost/ref.hpp> + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // reference is a lexer that references another lexer (its Subject) + // all lexer components are at the same time + /////////////////////////////////////////////////////////////////////////// + template <typename Subject, typename IdType = unused_type> + struct reference; + + template <typename Subject> + struct reference<Subject, unused_type> + : qi::reference<Subject> + , lexer_type<reference<Subject> > + { + reference(Subject& subject) + : qi::reference<Subject>(subject) {} + + template <typename LexerDef, typename String> + void collect(LexerDef& lexdef, String const& state + , String const& targetstate) const + { + this->ref.get().collect(lexdef, state, targetstate); + } + + template <typename LexerDef> + void add_actions(LexerDef& lexdef) const + { + this->ref.get().add_actions(lexdef); + } + }; + + template <typename Subject, typename IdType> + struct reference : reference<Subject> + { + reference(Subject& subject) + : reference<Subject>(subject) {} + + IdType id() const + { + return this->ref.get().id(); + } + std::size_t unique_id() const + { + return this->ref.get().unique_id(); + } + std::size_t state() const + { + return this->ref.get().state(); + } + }; +}}} + +namespace boost { namespace spirit { namespace traits +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Subject, typename IdType + , typename Attribute, typename Context, typename Iterator> + struct handles_container<lex::reference<Subject, IdType> + , Attribute, Context, Iterator> + : handles_container< + typename remove_const<Subject>::type, Attribute, Context, Iterator> + {}; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/tokenize_and_parse.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/tokenize_and_parse.hpp new file mode 100644 index 0000000..db12935 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/tokenize_and_parse.hpp @@ -0,0 +1,325 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// 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_LEXER_PARSE_NOV_17_2007_0246PM) +#define BOOST_SPIRIT_LEXER_PARSE_NOV_17_2007_0246PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/qi/skip_over.hpp> +#include <boost/spirit/home/qi/parse.hpp> +#include <boost/spirit/home/qi/nonterminal/grammar.hpp> +#include <boost/spirit/home/support/unused.hpp> +#include <boost/spirit/home/lex/lexer.hpp> +#include <boost/mpl/assert.hpp> + +namespace boost { namespace spirit { namespace lex +{ + /////////////////////////////////////////////////////////////////////////// + // Import skip_flag enumerator type from Qi namespace + using qi::skip_flag; + + /////////////////////////////////////////////////////////////////////////// + // + // The tokenize_and_parse() function is one of the main Spirit API + // functions. It simplifies using a lexer as the underlying token source + // while parsing a given input sequence. + // + // The function takes a pair of iterators spanning the underlying input + // stream to parse, the lexer object (built from the token definitions) + // and a parser object (built from the parser grammar definition). + // + // The second version of this function additionally takes an attribute to + // be used as the top level data structure instance the parser should use + // to store the recognized input to. + // + // The function returns true if the parsing succeeded (the given input + // sequence has been successfully matched by the given grammar). + // + // first, last: The pair of iterators spanning the underlying input + // sequence to parse. These iterators must at least + // conform to the requirements of the std::intput_iterator + // category. + // On exit the iterator 'first' will be updated to the + // position right after the last successfully matched + // token. + // lex: The lexer object (encoding the token definitions) to be + // used to convert the input sequence into a sequence of + // tokens. This token sequence is passed to the parsing + // process. The LexerExpr type must conform to the + // lexer interface described in the corresponding section + // of the documentation. + // xpr: The grammar object (encoding the parser grammar) to be + // used to match the token sequence generated by the lex + // object instance. The ParserExpr type must conform to + // the grammar interface described in the corresponding + // section of the documentation. + // attr: The top level attribute passed to the parser. It will + // be populated during the parsing of the input sequence. + // On exit it will hold the 'parser result' corresponding + // to the matched input sequence. + // + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Lexer, typename ParserExpr> + inline bool + tokenize_and_parse(Iterator& first, Iterator last, Lexer const& lex, + ParserExpr const& xpr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit qi expression. + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, ParserExpr); + + typename Lexer::iterator_type iter = lex.begin(first, last); + return compile<qi::domain>(xpr).parse( + iter, lex.end(), unused, unused, unused); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Lexer, typename ParserExpr + , typename Attribute> + inline bool + tokenize_and_parse(Iterator& first, Iterator last, Lexer const& lex + , ParserExpr const& xpr, Attribute& attr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit qi expression. + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, ParserExpr); + + typename Lexer::iterator_type iter = lex.begin(first, last); + return compile<qi::domain>(xpr).parse( + iter, lex.end(), unused, unused, attr); + } + + /////////////////////////////////////////////////////////////////////////// + // + // The tokenize_and_phrase_parse() function is one of the main Spirit API + // functions. It simplifies using a lexer as the underlying token source + // while phrase parsing a given input sequence. + // + // The function takes a pair of iterators spanning the underlying input + // stream to parse, the lexer object (built from the token definitions) + // and a parser object (built from the parser grammar definition). The + // additional skipper parameter will be used as the skip parser during + // the parsing process. + // + // The second version of this function additionally takes an attribute to + // be used as the top level data structure instance the parser should use + // to store the recognized input to. + // + // The function returns true if the parsing succeeded (the given input + // sequence has been successfully matched by the given grammar). + // + // first, last: The pair of iterators spanning the underlying input + // sequence to parse. These iterators must at least + // conform to the requirements of the std::intput_iterator + // category. + // On exit the iterator 'first' will be updated to the + // position right after the last successfully matched + // token. + // lex: The lexer object (encoding the token definitions) to be + // used to convert the input sequence into a sequence of + // tokens. This token sequence is passed to the parsing + // process. The LexerExpr type must conform to the + // lexer interface described in the corresponding section + // of the documentation. + // xpr: The grammar object (encoding the parser grammar) to be + // used to match the token sequence generated by the lex + // object instance. The ParserExpr type must conform to + // the grammar interface described in the corresponding + // section of the documentation. + // skipper: The skip parser to be used while parsing the given + // input sequence. Note, the skip parser will have to + // act on the same token sequence as the main parser + // 'xpr'. + // post_skip: The post_skip flag controls whether the function will + // invoke an additional post skip after the main parser + // returned. + // attr: The top level attribute passed to the parser. It will + // be populated during the parsing of the input sequence. + // On exit it will hold the 'parser result' corresponding + // to the matched input sequence. + // + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Lexer, typename ParserExpr + , typename Skipper> + inline bool + tokenize_and_phrase_parse(Iterator& first, Iterator last + , Lexer const& lex, ParserExpr const& xpr, Skipper const& skipper + , BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit qi expression. + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, ParserExpr); + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper); + + typedef + typename spirit::result_of::compile<qi::domain, Skipper>::type + skipper_type; + skipper_type const skipper_ = compile<qi::domain>(skipper); + + typename Lexer::iterator_type iter = lex.begin(first, last); + typename Lexer::iterator_type end = lex.end(); + if (!compile<qi::domain>(xpr).parse( + iter, end, unused, skipper_, unused)) + return false; + + // do a final post-skip + if (post_skip == skip_flag::postskip) + qi::skip_over(iter, end, skipper_); + return true; + } + + template <typename Iterator, typename Lexer, typename ParserExpr + , typename Skipper, typename Attribute> + inline bool + tokenize_and_phrase_parse(Iterator& first, Iterator last + , Lexer const& lex, ParserExpr const& xpr, Skipper const& skipper + , BOOST_SCOPED_ENUM(skip_flag) post_skip, Attribute& attr) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit qi expression. + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, ParserExpr); + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper); + + typedef + typename spirit::result_of::compile<qi::domain, Skipper>::type + skipper_type; + skipper_type const skipper_ = compile<qi::domain>(skipper); + + typename Lexer::iterator_type iter = lex.begin(first, last); + typename Lexer::iterator_type end = lex.end(); + if (!compile<qi::domain>(xpr).parse( + iter, end, unused, skipper_, attr)) + return false; + + // do a final post-skip + if (post_skip == skip_flag::postskip) + qi::skip_over(iter, end, skipper_); + return true; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Lexer, typename ParserExpr + , typename Skipper, typename Attribute> + inline bool + tokenize_and_phrase_parse(Iterator& first, Iterator last + , Lexer const& lex, ParserExpr const& xpr, Skipper const& skipper + , Attribute& attr) + { + return tokenize_and_phrase_parse(first, last, lex, xpr, skipper + , skip_flag::postskip, attr); + } + + /////////////////////////////////////////////////////////////////////////// + // + // The tokenize() function is one of the main Spirit API functions. It + // simplifies using a lexer to tokenize a given input sequence. It's main + // purpose is to use the lexer to tokenize all the input. + // + // The second version below discards all generated tokens afterwards. + // This is useful whenever all the needed functionality has been + // implemented directly inside the lexer semantic actions, which are being + // executed while the tokens are matched. + // + // The function takes a pair of iterators spanning the underlying input + // stream to scan, the lexer object (built from the token definitions), + // and a (optional) functor being called for each of the generated tokens. + // + // The function returns true if the scanning of the input succeeded (the + // given input sequence has been successfully matched by the given token + // definitions). + // + // first, last: The pair of iterators spanning the underlying input + // sequence to parse. These iterators must at least + // conform to the requirements of the std::intput_iterator + // category. + // On exit the iterator 'first' will be updated to the + // position right after the last successfully matched + // token. + // lex: The lexer object (encoding the token definitions) to be + // used to convert the input sequence into a sequence of + // tokens. The LexerExpr type must conform to the + // lexer interface described in the corresponding section + // of the documentation. + // f: A functor (callable object) taking a single argument of + // the token type and returning a bool, indicating whether + // the tokenization should be canceled. + // initial_state: The name of the state the lexer should start matching. + // The default value is zero, causing the lexer to start + // in its 'INITIAL' state. + // + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + template <typename Token, typename F> + bool tokenize_callback(Token const& t, F f) + { + return f(t); + } + + template <typename Token, typename Eval> + bool tokenize_callback(Token const& t, phoenix::actor<Eval> const& f) + { + f(t); + return true; + } + + template <typename Token> + bool tokenize_callback(Token const& t, void (*f)(Token const&)) + { + f(t); + return true; + } + + template <typename Token> + bool tokenize_callback(Token const& t, bool (*f)(Token const&)) + { + return f(t); + } + } + + template <typename Iterator, typename Lexer, typename F> + inline bool + tokenize(Iterator& first, Iterator last, Lexer const& lex, F f + , typename Lexer::char_type const* initial_state = 0) + { + typedef typename Lexer::iterator_type iterator_type; + + iterator_type iter = lex.begin(first, last, initial_state); + iterator_type end = lex.end(); + for (/**/; iter != end && token_is_valid(*iter); ++iter) + { + if (!detail::tokenize_callback(*iter, f)) + return false; + } + return (iter == end) ? true : false; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Lexer> + inline bool + tokenize(Iterator& first, Iterator last, Lexer const& lex + , typename Lexer::char_type const* initial_state = 0) + { + typedef typename Lexer::iterator_type iterator_type; + + iterator_type iter = lex.begin(first, last, initial_state); + iterator_type end = lex.end(); + + while (iter != end && token_is_valid(*iter)) + ++iter; + + return (iter == end) ? true : false; + } + +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/lex/tokenize_and_parse_attr.hpp b/3rdParty/Boost/src/boost/spirit/home/lex/tokenize_and_parse_attr.hpp new file mode 100644 index 0000000..98d191d --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/tokenize_and_parse_attr.hpp @@ -0,0 +1,114 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2009 Carl Barron +// +// 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_PP_IS_ITERATING) + +#if !defined(BOOST_SPIRIT_LEXER_PARSE_ATTR_MAY_27_2009_0926AM) +#define BOOST_SPIRIT_LEXER_PARSE_ATTR_MAY_27_2009_0926AM + +#include <boost/spirit/home/lex/tokenize_and_parse.hpp> + +#include <boost/fusion/include/vector.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/iterate.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> + +#define BOOST_PP_FILENAME_1 <boost/spirit/home/lex/tokenize_and_parse_attr.hpp> +#define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT) +#include BOOST_PP_ITERATE() + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#else // defined(BOOST_PP_IS_ITERATING) + +#define N BOOST_PP_ITERATION() +#define BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE(z, n, A) BOOST_PP_CAT(A, n)& + +namespace boost { namespace spirit { namespace lex +{ + template <typename Iterator, typename Lexer, typename ParserExpr + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool + tokenize_and_parse(Iterator& first, Iterator last, Lexer const& lex + , ParserExpr const& expr, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr)) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit qi expression. + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, ParserExpr); + + typedef fusion::vector< + BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A) + > vector_type; + + vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr)); + typename Lexer::iterator_type iter = lex.begin(first, last); + return compile<qi::domain>(expr).parse( + iter, lex.end(), unused, unused, attr); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator, typename Lexer, typename ParserExpr + , typename Skipper, BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool + tokenize_and_phrase_parse(Iterator& first, Iterator last, Lexer const& lex + , ParserExpr const& expr, Skipper const& skipper + , BOOST_SCOPED_ENUM(skip_flag) post_skip + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr)) + { + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then either the expression (expr) or skipper is not a valid + // spirit qi expression. + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, ParserExpr); + BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper); + + typedef + typename spirit::result_of::compile<qi::domain, Skipper>::type + skipper_type; + skipper_type const skipper_ = compile<qi::domain>(skipper); + + typedef fusion::vector< + BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A) + > vector_type; + + vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr)); + typename Lexer::iterator_type iter = lex.begin(first, last); + if (!compile<qi::domain>(expr).parse( + iter, lex.end(), unused, skipper_, attr)) + return false; + + if (post_skip == skip_flag::postskip) + qi::skip_over(first, last, skipper_); + return true; + } + + template <typename Iterator, typename Lexer, typename ParserExpr + , typename Skipper, BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool + tokenize_and_phrase_parse(Iterator& first, Iterator last, Lexer const& lex + , ParserExpr const& expr, Skipper const& skipper + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr)) + { + return tokenize_and_phrase_parse(first, last, expr, skipper + , skip_flag::postskip, BOOST_PP_ENUM_PARAMS(N, attr)); + } + +}}} + +#undef BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE +#undef N + +#endif + |