Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:17

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 // 
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_SPIRIT_LEX_LEXER_SUPPORT_FUNCTIONS_HPP
0007 #define BOOST_SPIRIT_LEX_LEXER_SUPPORT_FUNCTIONS_HPP
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
0014 #include <boost/spirit/home/lex/lexer/pass_flags.hpp>
0015 #include <boost/spirit/home/lex/lexer/support_functions_expression.hpp>
0016 #include <boost/phoenix/core/actor.hpp>
0017 #include <boost/phoenix/core/as_actor.hpp>
0018 #include <boost/phoenix/core/value.hpp> // includes as_actor specialization
0019 
0020 ///////////////////////////////////////////////////////////////////////////////
0021 namespace boost { namespace spirit { namespace lex
0022 {
0023     ///////////////////////////////////////////////////////////////////////////
0024     // The function object less_type is used by the implementation of the 
0025     // support function lex::less(). Its functionality is equivalent to flex' 
0026     // function yyless(): it returns an iterator positioned to the nth input 
0027     // character beyond the current start iterator (i.e. by assigning the 
0028     // return value to the placeholder '_end' it is possible to return all but
0029     // the first n characters of the current token back to the input stream. 
0030     //
0031     //  This Phoenix actor is invoked whenever the function lex::less(n) is 
0032     //  used inside a lexer semantic action:
0033     //
0034     //      lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
0035     //      this->self = identifier [ _end = lex::less(4) ];
0036     //
0037     //  The example shows how to limit the length of the matched identifier to 
0038     //  four characters.
0039     //
0040     //  Note: the function lex::less() has no effect if used on it's own, you 
0041     //        need to use the returned result in order to make use of its 
0042     //        functionality.
0043     template <typename Actor>
0044     struct less_type
0045     {
0046         typedef mpl::true_ no_nullary;
0047 
0048         template <typename Env>
0049         struct result
0050         {
0051             typedef typename remove_reference< 
0052                 typename remove_const<
0053                     typename mpl::at_c<typename Env::args_type, 4>::type
0054                 >::type
0055             >::type context_type;
0056             typedef typename context_type::base_iterator_type type;
0057         };
0058 
0059         template <typename Env>
0060         typename result<Env>::type 
0061         eval(Env const& env) const
0062         {
0063             typename result<Env>::type it;
0064             return fusion::at_c<4>(env.args()).less(it, actor_());
0065         }
0066 
0067         less_type(Actor const& actor)
0068           : actor_(actor) {}
0069 
0070         Actor actor_;
0071     };
0072 
0073     //  The function lex::less() is used to create a Phoenix actor allowing to
0074     //  implement functionality similar to flex' function yyless().
0075     template <typename T>
0076     inline typename expression::less<
0077         typename phoenix::as_actor<T>::type
0078     >::type const
0079     less(T const& v)
0080     {
0081         return expression::less<T>::make(phoenix::as_actor<T>::convert(v));
0082     }
0083 
0084     ///////////////////////////////////////////////////////////////////////////
0085     // The function object more_type is used by the implementation of the  
0086     // support function lex::more(). Its functionality is equivalent to flex' 
0087     // function yymore(): it tells the lexer that the next time it matches a 
0088     // rule, the corresponding token should be appended onto the current token 
0089     // value rather than replacing it.
0090     //
0091     //  This Phoenix actor is invoked whenever the function lex::more(n) is 
0092     //  used inside a lexer semantic action:
0093     //
0094     //      lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
0095     //      this->self = identifier [ lex::more() ];
0096     //
0097     //  The example shows how prefix the next matched token with the matched
0098     //  identifier.
0099     struct more_type
0100     {
0101         typedef mpl::true_ no_nullary;
0102 
0103         template <typename Env>
0104         struct result
0105         {
0106             typedef void type;
0107         };
0108 
0109         template <typename Env>
0110         void eval(Env const& env) const
0111         {
0112             fusion::at_c<4>(env.args()).more();
0113         }
0114     };
0115 
0116     //  The function lex::more() is used to create a Phoenix actor allowing to
0117     //  implement functionality similar to flex' function yymore(). 
0118     //inline expression::more<mpl::void_>::type const
0119     inline phoenix::actor<more_type> more()
0120     {
0121         return phoenix::actor<more_type>();
0122     }
0123 
0124     ///////////////////////////////////////////////////////////////////////////
0125     // The function object lookahead_type is used by the implementation of the  
0126     // support function lex::lookahead(). Its functionality is needed to 
0127     // emulate the flex' lookahead operator a/b. Use lex::lookahead() inside
0128     // of lexer semantic actions to test whether the argument to this function
0129     // matches the current look ahead input. lex::lookahead() can be used with
0130     // either a token id or a token_def instance as its argument. It returns
0131     // a bool indicating whether the look ahead has been matched.
0132     template <typename IdActor, typename StateActor>
0133     struct lookahead_type
0134     {
0135         typedef mpl::true_ no_nullary;
0136 
0137         template <typename Env>
0138         struct result
0139         {
0140             typedef bool type;
0141         };
0142 
0143         template <typename Env>
0144         bool eval(Env const& env) const
0145         {
0146             return fusion::at_c<4>(env.args()).
0147                 lookahead(id_actor_(), state_actor_());
0148         }
0149 
0150         lookahead_type(IdActor const& id_actor, StateActor const& state_actor)
0151           : id_actor_(id_actor), state_actor_(state_actor) {}
0152 
0153         IdActor id_actor_;
0154         StateActor state_actor_;
0155     };
0156 
0157     //  The function lex::lookahead() is used to create a Phoenix actor 
0158     //  allowing to implement functionality similar to flex' lookahead operator
0159     //  a/b.
0160     template <typename T>
0161     inline typename expression::lookahead<
0162         typename phoenix::as_actor<T>::type
0163       , typename phoenix::as_actor<std::size_t>::type
0164     >::type const
0165     lookahead(T const& id)
0166     {
0167         typedef typename phoenix::as_actor<T>::type id_actor_type;
0168         typedef typename phoenix::as_actor<std::size_t>::type state_actor_type;
0169 
0170         return expression::lookahead<id_actor_type, state_actor_type>::make(
0171             phoenix::as_actor<T>::convert(id),
0172             phoenix::as_actor<std::size_t>::convert(std::size_t(~0)));
0173     }
0174 
0175     template <typename Attribute, typename Char, typename Idtype>
0176     inline typename expression::lookahead<
0177         typename phoenix::as_actor<Idtype>::type
0178       , typename phoenix::as_actor<std::size_t>::type
0179     >::type const
0180     lookahead(token_def<Attribute, Char, Idtype> const& tok)
0181     {
0182         typedef typename phoenix::as_actor<Idtype>::type id_actor_type;
0183         typedef typename phoenix::as_actor<std::size_t>::type state_actor_type;
0184 
0185         std::size_t state = tok.state();
0186 
0187         // The following assertion fires if you pass a token_def instance to 
0188         // lex::lookahead without first associating this instance with the 
0189         // lexer.
0190         BOOST_ASSERT(std::size_t(~0) != state && 
0191             "token_def instance not associated with lexer yet");
0192 
0193         return expression::lookahead<id_actor_type, state_actor_type>::make(
0194             phoenix::as_actor<Idtype>::convert(tok.id()),
0195             phoenix::as_actor<std::size_t>::convert(state));
0196     }
0197 
0198     ///////////////////////////////////////////////////////////////////////////
0199     inline BOOST_SCOPED_ENUM(pass_flags) ignore()
0200     {
0201         return pass_flags::pass_ignore;
0202     }
0203 
0204 }}}
0205 
0206 #endif