// Copyright (c) 2001-2010 Hartmut Kaiser // Copyright (c) 2001-2010 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_ARGUMENT_JUNE_07_2009_1106AM) #define BOOST_SPIRIT_LEX_ARGUMENT_JUNE_07_2009_1106AM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// 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 4th 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 struct result { typedef typename remove_const< typename mpl::at_c::type >::type context_type; typedef typename context_type::state_name_type type; }; template typename result::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 4th 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 struct state_setter { typedef mpl::true_ no_nullary; template struct result { typedef void type; }; template void eval(Env const& env) const { 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 state_setter(phoenix::actor, Actor const& actor) : actor_(actor) {} Actor actor_; }; /////////////////////////////////////////////////////////////////////////// // 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; template struct result { typedef unused_type type; }; template unused_type eval(Env const& env) const { return unused; } }; /////////////////////////////////////////////////////////////////////////// // 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 struct result { typedef typename remove_const< typename mpl::at_c::type >::type context_type; typedef typename context_type::get_value_type type; }; template typename result::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 4th 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 struct value_setter { typedef mpl::true_ no_nullary; template struct result { typedef void type; }; template void eval(Env const& env) const { fusion::at_c<4>(env.args()).set_value(actor_.eval(env)); } value_setter(Actor const& actor) : actor_(actor) {} // see explanation for this constructor at the end of this file value_setter(phoenix::actor, Actor const& actor) : actor_(actor) {} Actor actor_; }; /////////////////////////////////////////////////////////////////////////// // 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; template struct result { typedef unused_type type; }; template unused_type eval(Env const& env) const { return unused; } }; /////////////////////////////////////////////////////////////////////////// // 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_(_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 struct result { typedef typename remove_const< typename mpl::at_c::type >::type context_type; typedef typename context_type::base_iterator_type const& type; }; template typename result::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 phoenix::actor > const _start = phoenix::argument<0>(); phoenix::actor > const _end = phoenix::argument<1>(); // We are reusing the placeholder '_pass' to access and change the pass // status of the current match (see support/argument.hpp for its // definition). using boost::spirit::_pass; // '_tokenid' may be used to access and change the tokenid of the current // token phoenix::actor > const _tokenid = phoenix::argument<3>(); // '_val' may be used to access and change the token value of the current // token phoenix::actor const _val = value_context(); // _state may be used to access and change the name of the current lexer // state phoenix::actor const _state = state_context(); // '_eoi' may be used to access the end of input iterator of the input // stream used by the lexer to match tokens from phoenix::actor const _eoi = eoi_getter(); }}} /////////////////////////////////////////////////////////////////////////////// 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 > { typedef spirit::lex::state_getter type; static spirit::lex::state_getter convert(actor) { 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 struct as_composite, 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::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 > { typedef spirit::lex::value_getter type; static spirit::lex::value_getter convert(actor) { 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 struct as_composite, 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::type> type; }; }} #undef SPIRIT_DECLARE_ARG #endif