Back to home page

EIC code displayed by LXR

 
 

    


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

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 #if !defined(BOOST_SPIRIT_LEX_STATIC_LEXER_FEB_10_2008_0753PM)
0007 #define BOOST_SPIRIT_LEX_STATIC_LEXER_FEB_10_2008_0753PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/lex/lexer/lexertl/token.hpp>
0014 #include <boost/spirit/home/lex/lexer/lexertl/functor.hpp>
0015 #include <boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp>
0016 #include <boost/spirit/home/lex/lexer/lexertl/iterator.hpp>
0017 #include <boost/spirit/home/lex/lexer/lexertl/static_version.hpp>
0018 #if defined(BOOST_SPIRIT_DEBUG)
0019 #include <boost/spirit/home/support/detail/lexer/debug.hpp>
0020 #endif
0021 #include <iterator> // for std::iterator_traits
0022 
0023 namespace boost { namespace spirit { namespace lex { namespace lexertl
0024 { 
0025     ///////////////////////////////////////////////////////////////////////////
0026     //  forward declaration
0027     ///////////////////////////////////////////////////////////////////////////
0028     namespace static_
0029     {
0030         struct lexer;
0031     }
0032 
0033     ///////////////////////////////////////////////////////////////////////////
0034     //
0035     //  Every lexer type to be used as a lexer for Spirit has to conform to 
0036     //  the following public interface:
0037     //
0038     //    typedefs: 
0039     //        iterator_type   The type of the iterator exposed by this lexer.
0040     //        token_type      The type of the tokens returned from the exposed 
0041     //                        iterators.
0042     //
0043     //    functions:
0044     //        default constructor
0045     //                        Since lexers are instantiated as base classes 
0046     //                        only it might be a good idea to make this 
0047     //                        constructor protected.
0048     //        begin, end      Return a pair of iterators, when dereferenced
0049     //                        returning the sequence of tokens recognized in 
0050     //                        the input stream given as the parameters to the 
0051     //                        begin() function.
0052     //        add_token       Should add the definition of a token to be 
0053     //                        recognized by this lexer.
0054     //        clear           Should delete all current token definitions
0055     //                        associated with the given state of this lexer 
0056     //                        object.
0057     //
0058     //    template parameters:
0059     //        Token           The type of the tokens to be returned from the
0060     //                        exposed token iterator.
0061     //        LexerTables     See explanations below.
0062     //        Iterator        The type of the iterator used to access the
0063     //                        underlying character stream.
0064     //        Functor         The type of the InputPolicy to use to instantiate
0065     //                        the multi_pass iterator type to be used as the 
0066     //                        token iterator (returned from begin()/end()).
0067     //
0068     //    Additionally, this implementation of a static lexer has a template
0069     //    parameter LexerTables allowing to customize the static lexer tables
0070     //    to be used. The LexerTables is expected to be a type exposing 
0071     //    the following functions:
0072     //
0073     //        static std::size_t const state_count()
0074     //
0075     //                This function needs toreturn the number of lexer states
0076     //                contained in the table returned from the state_names()
0077     //                function.
0078     //
0079     //        static char const* const* state_names()
0080     //
0081     //                This function needs to return a pointer to a table of
0082     //                names of all lexer states. The table needs to have as 
0083     //                much entries as the state_count() function returns
0084     //
0085     //        template<typename Iterator>
0086     //        std::size_t next(std::size_t &start_state_, Iterator const& start_
0087     //          , Iterator &start_token_, Iterator const& end_
0088     //          , std::size_t& unique_id_);
0089     //
0090     //                This function is expected to return the next matched
0091     //                token from the underlying input stream.
0092     //
0093     ///////////////////////////////////////////////////////////////////////////
0094 
0095     ///////////////////////////////////////////////////////////////////////////
0096     //
0097     //  The static_lexer class is a implementation of a Spirit.Lex 
0098     //  lexer on top of Ben Hanson's lexertl library (For more information 
0099     //  about lexertl go here: http://www.benhanson.net/lexertl.html). 
0100     //
0101     //  This class is designed to be used in conjunction with a generated, 
0102     //  static lexer. For more information see the documentation (The Static 
0103     //  Lexer Model).
0104     //
0105     //  This class is supposed to be used as the first and only template 
0106     //  parameter while instantiating instances of a lex::lexer class.
0107     //
0108     ///////////////////////////////////////////////////////////////////////////
0109     template <typename Token = token<>
0110       , typename LexerTables = static_::lexer
0111       , typename Iterator = typename Token::iterator_type
0112       , typename Functor = functor<Token, detail::static_data, Iterator> >
0113     class static_lexer 
0114     {
0115     private:
0116         struct dummy { void true_() {} };
0117         typedef void (dummy::*safe_bool)();
0118 
0119     public:
0120         // object is always valid
0121         operator safe_bool() const { return &dummy::true_; }
0122 
0123         typedef typename std::iterator_traits<Iterator>::value_type char_type;
0124         typedef std::basic_string<char_type> string_type;
0125 
0126         //  Every lexer type to be used as a lexer for Spirit has to conform to 
0127         //  a public interface 
0128         typedef Token token_type;
0129         typedef typename Token::id_type id_type;
0130         typedef iterator<Functor> iterator_type;
0131 
0132     private:
0133 #ifdef _MSC_VER
0134 #  pragma warning(push)
0135 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0136 #endif
0137         // this type is purely used for the iterator_type construction below
0138         struct iterator_data_type 
0139         {
0140             typedef typename Functor::next_token_functor next_token_functor;
0141             typedef typename Functor::semantic_actions_type semantic_actions_type;
0142             typedef typename Functor::get_state_name_type get_state_name_type;
0143 
0144             iterator_data_type(next_token_functor next
0145                   , semantic_actions_type const& actions
0146                   , get_state_name_type get_state_name, std::size_t num_states
0147                   , bool bol)
0148               : next_(next), actions_(actions), get_state_name_(get_state_name)
0149               , num_states_(num_states), bol_(bol)
0150             {}
0151 
0152             next_token_functor next_;
0153             semantic_actions_type const& actions_;
0154             get_state_name_type get_state_name_;
0155             std::size_t num_states_;
0156             bool bol_;
0157         };
0158 #ifdef _MSC_VER
0159 #  pragma warning(pop)
0160 #endif
0161 
0162         typedef LexerTables tables_type;
0163 
0164         // The following static assertion fires if the referenced static lexer 
0165         // tables are generated by a different static lexer version as used for
0166         // the current compilation unit. Please regenerate your static lexer
0167         // tables before trying to create a static_lexer<> instance.
0168         BOOST_SPIRIT_ASSERT_MSG(
0169             tables_type::static_version == SPIRIT_STATIC_LEXER_VERSION
0170           , incompatible_static_lexer_version, (LexerTables));
0171 
0172     public:
0173         //  Return the start iterator usable for iterating over the generated
0174         //  tokens, the generated function next_token(...) is called to match 
0175         //  the next token from the input.
0176         template <typename Iterator_>
0177         iterator_type begin(Iterator_& first, Iterator_ const& last
0178           , char_type const* initial_state = 0) const
0179         { 
0180             iterator_data_type iterator_data( 
0181                     &tables_type::template next<Iterator_>, actions_
0182                   , &tables_type::state_name, tables_type::state_count()
0183                   , tables_type::supports_bol
0184                 );
0185             return iterator_type(iterator_data, first, last, initial_state);
0186         }
0187 
0188         //  Return the end iterator usable to stop iterating over the generated 
0189         //  tokens.
0190         iterator_type end() const
0191         { 
0192             return iterator_type(); 
0193         }
0194 
0195     protected:
0196         //  Lexer instances can be created by means of a derived class only.
0197         static_lexer(unsigned int) : unique_id_(0) {}
0198 
0199     public:
0200         // interface for token definition management
0201         std::size_t add_token (char_type const*, char_type, std::size_t
0202           , char_type const*) 
0203         {
0204             return unique_id_++;
0205         }
0206         std::size_t add_token (char_type const*, string_type const&
0207           , std::size_t, char_type const*) 
0208         {
0209             return unique_id_++;
0210         }
0211 
0212         // interface for pattern definition management
0213         void add_pattern (char_type const*, string_type const&
0214           , string_type const&) {}
0215 
0216         void clear(char_type const*) {}
0217 
0218         std::size_t add_state(char_type const* state)
0219         {
0220             return detail::get_state_id(state, &tables_type::state_name
0221               , tables_type::state_count());
0222         }
0223         string_type initial_state() const 
0224         { 
0225             return tables_type::state_name(0);
0226         }
0227 
0228         // register a semantic action with the given id
0229         template <typename F>
0230         void add_action(id_type unique_id, std::size_t state, F act) 
0231         {
0232             typedef typename Functor::wrap_action_type wrapper_type;
0233             actions_.add_action(unique_id, state, wrapper_type::call(act));
0234         }
0235 
0236         bool init_dfa(bool /*minimize*/ = false) const { return true; }
0237 
0238     private:
0239         typename Functor::semantic_actions_type actions_;
0240         std::size_t unique_id_;
0241     };
0242 
0243     ///////////////////////////////////////////////////////////////////////////
0244     //
0245     //  The static_actor_lexer class is another implementation of a 
0246     //  Spirit.Lex lexer on top of Ben Hanson's lexertl library as outlined 
0247     //  above (For more information about lexertl go here: 
0248     //  http://www.benhanson.net/lexertl.html).
0249     //
0250     //  Just as the static_lexer class it is meant to be used with 
0251     //  a statically generated lexer as outlined above.
0252     //
0253     //  The only difference to the static_lexer class above is that 
0254     //  token_def definitions may have semantic (lexer) actions attached while 
0255     //  being defined:
0256     //
0257     //      int w;
0258     //      token_def<> word = "[^ \t\n]+";
0259     //      self = word[++ref(w)];        // see example: word_count_lexer
0260     //
0261     //  This class is supposed to be used as the first and only template 
0262     //  parameter while instantiating instances of a lex::lexer class.
0263     //
0264     ///////////////////////////////////////////////////////////////////////////
0265     template <typename Token = token<>
0266       , typename LexerTables = static_::lexer
0267       , typename Iterator = typename Token::iterator_type
0268       , typename Functor 
0269           = functor<Token, detail::static_data, Iterator, mpl::true_> >
0270     class static_actor_lexer 
0271       : public static_lexer<Token, LexerTables, Iterator, Functor>
0272     {
0273     protected:
0274         // Lexer instances can be created by means of a derived class only.
0275         static_actor_lexer(unsigned int flags) 
0276           : static_lexer<Token, LexerTables, Iterator, Functor>(flags) 
0277         {}
0278     };
0279 
0280 }}}}
0281 
0282 #endif