diff options
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions.hpp | 206 |
1 files changed, 206 insertions, 0 deletions
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..eeae6c1 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/lex/lexer/support_functions.hpp @@ -0,0 +1,206 @@ +// 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/home/phoenix/core/actor.hpp> +#include <boost/spirit/home/phoenix/core/argument.hpp> +#include <boost/spirit/home/phoenix/core/compose.hpp> +#include <boost/spirit/home/phoenix/core/value.hpp> +#include <boost/spirit/home/phoenix/core/as_actor.hpp> +#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp> +#include <boost/spirit/home/lex/lexer/pass_flags.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 phoenix::actor<less_type<typename phoenix::as_actor<T>::type> > + less(T const& v) + { + typedef typename phoenix::as_actor<T>::type actor_type; + return less_type<actor_type>(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 phoenix::actor<more_type> + more() + { + return 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 phoenix::actor< + lookahead_type< + typename phoenix::as_actor<T>::type + , typename phoenix::as_actor<std::size_t>::type> > + 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 lookahead_type<id_actor_type, state_actor_type>( + 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 phoenix::actor< + lookahead_type< + typename phoenix::as_actor<Idtype>::type + , typename phoenix::as_actor<std::size_t>::type> > + 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 lookahead_type<id_actor_type, state_actor_type>( + 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 |