You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							362 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
	
	
							362 lines
						
					
					
						
							13 KiB
						
					
					
				| //  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 | |
| 
 | |
| 
 |