Chris@16: // Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: // Copyright (c) 2001-2011 Joel de Guzman Chris@16: // Copyright (c) 2010 Bryce Lelbach Chris@16: // Copyright (c) 2011 Thomas Heller Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #if !defined(BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM) Chris@16: #define BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit { namespace lex Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The state_getter is a Phoenix actor used to access the name of the Chris@16: // current lexer state by calling get_state_name() on the context (which Chris@16: // is the 5th parameter to any lexer semantic actions). Chris@16: // Chris@16: // This Phoenix actor is invoked whenever the placeholder '_state' is used Chris@16: // as a rvalue inside a lexer semantic action: Chris@16: // Chris@16: // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; Chris@16: // this->self = identifier [ std::cout << _state ]; Chris@16: // Chris@16: // The example shows how to print the lexer state after matching a token Chris@16: // 'identifier'. Chris@16: struct state_getter Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef Chris@16: typename remove_reference< Chris@16: typename remove_const< Chris@16: typename mpl::at_c::type Chris@16: >::type Chris@16: >::type Chris@16: context_type; Chris@16: Chris@16: typedef typename context_type::state_name_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return fusion::at_c<4>(env.args()).get_state_name(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The state_setter is a Phoenix actor used to change the name of the Chris@16: // current lexer state by calling set_state_name() on the context (which Chris@16: // is the 5th parameter to any lexer semantic actions). Chris@16: // Chris@16: // This Phoenix actor is invoked whenever the placeholder '_state' is used Chris@16: // as a lvalue inside a lexer semantic action: Chris@16: // Chris@16: // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; Chris@16: // this->self = identifier [ _state = "SOME_LEXER_STATE" ]; Chris@16: // Chris@16: // The example shows how to change the lexer state after matching a token Chris@16: // 'identifier'. Chris@16: template Chris@16: struct state_setter Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: template Chris@16: void eval(Env const& env) const Chris@16: { Chris@16: typedef Chris@16: typename remove_reference< Chris@16: typename remove_const< Chris@16: typename mpl::at_c::type Chris@16: >::type Chris@16: >::type Chris@16: context_type; Chris@16: Chris@16: typedef typename context_type::state_name_type string; Chris@16: Chris@16: fusion::at_c<4>(env.args()).set_state_name( Chris@16: traits::get_c_string(actor_.eval(env))); Chris@16: } Chris@16: Chris@16: state_setter(Actor const& actor) Chris@16: : actor_(actor) {} Chris@16: Chris@16: Actor actor_; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The value_getter is used to create the _val placeholder, which is a Chris@16: // Phoenix actor used to access the value of the current token. Chris@16: // Chris@16: // This Phoenix actor is invoked whenever the placeholder '_val' is used Chris@16: // as a rvalue inside a lexer semantic action: Chris@16: // Chris@16: // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; Chris@16: // this->self = identifier [ std::cout << _val ]; Chris@16: // Chris@16: // The example shows how to use _val to print the identifier name (which Chris@16: // is the initial token value). Chris@16: struct value_getter Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef Chris@16: typename remove_reference< Chris@16: typename remove_const< Chris@16: typename mpl::at_c::type Chris@16: >::type Chris@16: >::type Chris@16: context_type; Chris@16: Chris@16: typedef typename context_type::get_value_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return fusion::at_c<4>(env.args()).get_value(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The value_setter is a Phoenix actor used to change the name of the Chris@16: // current lexer state by calling set_state_name() on the context (which Chris@16: // is the 5th parameter to any lexer semantic actions). Chris@16: // Chris@16: // This Phoenix actor is invoked whenever the placeholder '_val' is used Chris@16: // as a lvalue inside a lexer semantic action: Chris@16: // Chris@16: // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; Chris@16: // this->self = identifier [ _val = "identifier" ]; Chris@16: // Chris@16: // The example shows how to change the token value after matching a token Chris@16: // 'identifier'. Chris@16: template Chris@16: struct value_setter Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: template Chris@16: void eval(Env const& env) const Chris@16: { Chris@16: fusion::at_c<4>(env.args()).set_value(actor_.eval(env)); Chris@16: } Chris@16: Chris@16: value_setter(Actor const& actor) Chris@16: : actor_(actor) {} Chris@16: Chris@16: Actor actor_; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The eoi_getter is used to create the _eoi placeholder, which is a Chris@16: // Phoenix actor used to access the end of input iterator pointing to the Chris@16: // end of the underlying input sequence. Chris@16: // Chris@16: // This actor is invoked whenever the placeholder '_eoi' is used in a Chris@16: // lexer semantic action: Chris@16: // Chris@16: // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; Chris@16: // this->self = identifier Chris@16: // [ std::cout << construct_(_end, _eoi) ]; Chris@16: // Chris@16: // The example shows how to use _eoi to print all remaining input after Chris@16: // matching a token 'identifier'. Chris@16: struct eoi_getter Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef Chris@16: typename remove_reference< Chris@16: typename remove_const< Chris@16: typename mpl::at_c::type Chris@16: >::type Chris@16: >::type Chris@16: context_type; Chris@16: Chris@16: typedef typename context_type::base_iterator_type const& type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return fusion::at_c<4>(env.args()).get_eoi(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // '_start' and '_end' may be used to access the start and the end of Chris@16: // the matched sequence of the current token Chris@16: typedef phoenix::arg_names::_1_type _start_type; Chris@16: typedef phoenix::arg_names::_2_type _end_type; Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: _start_type const _start = _start_type(); Chris@16: _end_type const _end = _end_type(); Chris@16: #endif Chris@16: Chris@16: // We are reusing the placeholder '_pass' to access and change the pass Chris@16: // status of the current match (see support/argument.hpp for its Chris@16: // definition). Chris@16: // typedef phoenix::arg_names::_3_type _pass_type; Chris@16: using boost::spirit::_pass_type; Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: using boost::spirit::_pass; Chris@16: #endif Chris@16: Chris@16: // '_tokenid' may be used to access and change the tokenid of the current Chris@16: // token Chris@16: typedef phoenix::arg_names::_4_type _tokenid_type; Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: _tokenid_type const _tokenid = _tokenid_type(); Chris@16: #endif Chris@16: Chris@16: typedef phoenix::actor _val_type; Chris@16: typedef phoenix::actor _state_type; Chris@16: typedef phoenix::actor _eoi_type; Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: // '_val' may be used to access and change the token value of the current Chris@16: // token Chris@16: _val_type const _val = _val_type(); Chris@16: // _state may be used to access and change the name of the current lexer Chris@16: // state Chris@16: _state_type const _state = _state_type(); Chris@16: // '_eoi' may be used to access the end of input iterator of the input Chris@16: // stream used by the lexer to match tokens from Chris@16: _eoi_type const _eoi = _eoi_type(); Chris@16: #endif Chris@16: }}} Chris@16: Chris@16: Chris@16: #undef SPIRIT_DECLARE_ARG Chris@16: #endif Chris@16: