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_LEXER_STATIC_FUNCTOR_DATA_FEB_10_2008_0755PM)
0007 #define BOOST_SPIRIT_LEX_LEXER_STATIC_FUNCTOR_DATA_FEB_10_2008_0755PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/support/detail/lexer/generator.hpp>
0014 #include <boost/spirit/home/support/detail/lexer/rules.hpp>
0015 #include <boost/spirit/home/support/detail/lexer/state_machine.hpp>
0016 #include <boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp>
0017 #include <boost/spirit/home/lex/lexer/lexertl/semantic_action_data.hpp>
0018 #include <boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp>
0019 #include <boost/spirit/home/support/assert_msg.hpp>
0020 #include <boost/mpl/bool.hpp>
0021 #include <iterator> // for std::iterator_traits
0022 
0023 #ifdef _MSC_VER
0024 #  pragma warning(push)
0025 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0026 #endif
0027 namespace boost { namespace spirit { namespace lex { namespace lexertl
0028 { 
0029     namespace detail
0030     {
0031         ///////////////////////////////////////////////////////////////////////
0032         template <typename Char>
0033         inline bool zstr_compare(Char const* s1, Char const* s2)
0034         {
0035             for (; *s1 || *s2; ++s1, ++s2)
0036                 if (*s1 != *s2)
0037                     return false;
0038             return true;
0039         }
0040 
0041         template <typename Char, typename F>
0042         inline std::size_t get_state_id(Char const* state, F f
0043           , std::size_t numstates)
0044         {
0045             for (std::size_t i = 0; i < numstates; ++i)
0046             {
0047                 if (zstr_compare(f(i), state))
0048                     return i;
0049             }
0050             return boost::lexer::npos;
0051         }
0052 
0053         ///////////////////////////////////////////////////////////////////////
0054         template <typename Iterator, typename HasActors, typename HasState
0055           , typename TokenValue>
0056         class static_data;    // no default specialization
0057 
0058         ///////////////////////////////////////////////////////////////////////
0059         //  doesn't support no state and no actors
0060         template <typename Iterator, typename TokenValue>
0061         class static_data<Iterator, mpl::false_, mpl::false_, TokenValue>
0062         {
0063         protected:
0064             typedef typename 
0065                 std::iterator_traits<Iterator>::value_type 
0066             char_type;
0067 
0068         public:
0069             typedef Iterator base_iterator_type;
0070             typedef iterator_range<Iterator> token_value_type;
0071             typedef token_value_type get_value_type;
0072             typedef std::size_t state_type;
0073             typedef char_type const* state_name_type;
0074             typedef unused_type semantic_actions_type;
0075             typedef detail::wrap_action<unused_type, Iterator, static_data
0076               , std::size_t> wrap_action_type;
0077  
0078             typedef std::size_t (*next_token_functor)(std::size_t&, 
0079                 bool&, Iterator&, Iterator const&, std::size_t&);
0080             typedef char_type const* (*get_state_name_type)(std::size_t);
0081 
0082             // initialize the shared data 
0083             template <typename IterData>
0084             static_data (IterData const& data, Iterator& first
0085                   , Iterator const& last)
0086               : first_(first), last_(last) 
0087               , next_token_(data.next_)
0088               , get_state_name_(data.get_state_name_)
0089               , bol_(data.bol_) {}
0090 
0091             // The following functions are used by the implementation of the 
0092             // placeholder '_state'.
0093             template <typename Char>
0094             void set_state_name (Char const*) 
0095             {
0096                 // If you see a compile time assertion below you're probably 
0097                 // using a token type not supporting lexer states (the 3rd 
0098                 // template parameter of the token is mpl::false_), but your 
0099                 // code uses state changes anyways.
0100                 BOOST_SPIRIT_ASSERT_FAIL(Char,
0101                     tried_to_set_state_of_stateless_token, ());
0102             }
0103             char_type const* get_state_name() const 
0104             { 
0105                 return get_state_name_(0); 
0106             }
0107             std::size_t get_state_id(char_type const*) const 
0108             { 
0109                 return 0; 
0110             }
0111 
0112             // The function get_eoi() is used by the implementation of the 
0113             // placeholder '_eoi'.
0114             Iterator const& get_eoi() const { return last_; }
0115 
0116             // The function less() is used by the implementation of the support
0117             // function lex::less(). Its functionality is equivalent to flex'
0118             // function yyless(): it returns an iterator positioned to the 
0119             // nth input character beyond the current start iterator (i.e. by
0120             // assigning the return value to the placeholder '_end' it is 
0121             // possible to return all but the first n characters of the current 
0122             // token back to the input stream. 
0123             //
0124             // This function does nothing as long as no semantic actions are 
0125             // used.
0126             Iterator const& less(Iterator const& it, int) 
0127             { 
0128                 // The following assertion fires most likely because you are 
0129                 // using lexer semantic actions without using the actor_lexer
0130                 // as the base class for your token definition class.
0131                 BOOST_ASSERT(false && 
0132                     "Are you using lexer semantic actions without using the "
0133                     "actor_lexer base?");
0134                 return it; 
0135             }
0136 
0137             // The function more() is used by the implementation of the support 
0138             // function lex::more(). Its functionality is equivalent to flex'
0139             // function yymore(): it tells the lexer that the next time it 
0140             // matches a rule, the corresponding token should be appended onto 
0141             // the current token value rather than replacing it.
0142             // 
0143             // These functions do nothing as long as no semantic actions are 
0144             // used.
0145             void more() 
0146             { 
0147                 // The following assertion fires most likely because you are 
0148                 // using lexer semantic actions without using the actor_lexer
0149                 // as the base class for your token definition class.
0150                 BOOST_ASSERT(false && 
0151                     "Are you using lexer semantic actions without using the "
0152                     "actor_lexer base?"); 
0153             }
0154             bool adjust_start() { return false; }
0155             void revert_adjust_start() {}
0156 
0157             // The function lookahead() is used by the implementation of the 
0158             // support function lex::lookahead. It can be used to implement 
0159             // lookahead for lexer engines not supporting constructs like flex'
0160             // a/b  (match a, but only when followed by b):
0161             //
0162             // This function does nothing as long as no semantic actions are 
0163             // used.
0164             bool lookahead(std::size_t, std::size_t /*state*/ = std::size_t(~0)) 
0165             { 
0166                 // The following assertion fires most likely because you are 
0167                 // using lexer semantic actions without using the actor_lexer
0168                 // as the base class for your token definition class.
0169                 BOOST_ASSERT(false && 
0170                     "Are you using lexer semantic actions without using the "
0171                     "actor_lexer base?");
0172                 return false; 
0173             }
0174 
0175             // the functions next, invoke_actions, and get_state are used by 
0176             // the functor implementation below
0177 
0178             // The function next() tries to match the next token from the 
0179             // underlying input sequence. 
0180             std::size_t next(Iterator& end, std::size_t& unique_id, bool& prev_bol)
0181             {
0182                 prev_bol = bol_;
0183 
0184                 std::size_t state = 0;
0185                 return next_token_(state, bol_, end, last_, unique_id);
0186             }
0187 
0188             // nothing to invoke, so this is empty
0189             BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t
0190               , std::size_t, std::size_t, Iterator const&) 
0191             {
0192                 return pass_flags::pass_normal;    // always accept
0193             }
0194 
0195             std::size_t get_state() const { return 0; }
0196             void set_state(std::size_t) {}
0197 
0198             void set_end(Iterator const&) {}
0199 
0200             Iterator& get_first() { return first_; }
0201             Iterator const& get_first() const { return first_; }
0202             Iterator const& get_last() const { return last_; }
0203 
0204             iterator_range<Iterator> get_value() const 
0205             { 
0206                 return iterator_range<Iterator>(first_, last_); 
0207             }
0208             bool has_value() const { return false; }
0209             void reset_value() {}
0210 
0211             void reset_bol(bool bol) { bol_ = bol; }
0212 
0213         protected:
0214             Iterator& first_;
0215             Iterator last_;
0216 
0217             next_token_functor next_token_;
0218             get_state_name_type get_state_name_;
0219 
0220             bool bol_;      // helper storing whether last character was \n
0221         };
0222 
0223         ///////////////////////////////////////////////////////////////////////
0224         //  doesn't support lexer semantic actions, but supports state
0225         template <typename Iterator, typename TokenValue>
0226         class static_data<Iterator, mpl::false_, mpl::true_, TokenValue>
0227           : public static_data<Iterator, mpl::false_, mpl::false_, TokenValue>
0228         {
0229         protected:
0230             typedef static_data<Iterator, mpl::false_, mpl::false_, TokenValue> base_type;
0231             typedef typename base_type::char_type char_type;
0232 
0233         public:
0234             typedef Iterator base_iterator_type;
0235             typedef iterator_range<Iterator> token_value_type;
0236             typedef token_value_type get_value_type;
0237             typedef typename base_type::state_type state_type;
0238             typedef typename base_type::state_name_type state_name_type;
0239             typedef typename base_type::semantic_actions_type 
0240                 semantic_actions_type;
0241 
0242             // initialize the shared data 
0243             template <typename IterData>
0244             static_data (IterData const& data, Iterator& first
0245                   , Iterator const& last)
0246               : base_type(data, first, last), state_(0)
0247               , num_states_(data.num_states_) {}
0248 
0249             // The following functions are used by the implementation of the 
0250             // placeholder '_state'.
0251             void set_state_name (char_type const* new_state) 
0252             { 
0253                 std::size_t state_id = lexertl::detail::get_state_id(new_state
0254                   , this->get_state_name_, num_states_);
0255 
0256                 // if the following assertion fires you've probably been using 
0257                 // a lexer state name which was not defined in your token 
0258                 // definition
0259                 BOOST_ASSERT(state_id != boost::lexer::npos);
0260 
0261                 if (state_id != boost::lexer::npos)
0262                     state_ = state_id;
0263             }
0264             char_type const* get_state_name() const
0265             {
0266                 return this->get_state_name_(state_);
0267             }
0268             std::size_t get_state_id(char_type const* state) const 
0269             { 
0270                 return lexertl::detail::get_state_id(state
0271                   , this->get_state_name_, num_states_); 
0272             }
0273 
0274             // the functions next() and get_state() are used by the functor 
0275             // implementation below
0276 
0277             // The function next() tries to match the next token from the 
0278             // underlying input sequence. 
0279             std::size_t next(Iterator& end, std::size_t& unique_id, bool& prev_bol)
0280             {
0281                 prev_bol = this->bol_;
0282                 return this->next_token_(state_, this->bol_, end, this->last_
0283                   , unique_id);
0284             }
0285 
0286             std::size_t& get_state() { return state_; }
0287             void set_state(std::size_t state) { state_ = state; }
0288 
0289         protected:
0290             std::size_t state_;
0291             std::size_t num_states_;
0292         };
0293 
0294         ///////////////////////////////////////////////////////////////////////
0295         //  does support actors, but may have no state
0296         template <typename Iterator, typename HasState, typename TokenValue>
0297         class static_data<Iterator, mpl::true_, HasState, TokenValue> 
0298           : public static_data<Iterator, mpl::false_, HasState, TokenValue>
0299         {
0300         public:
0301             typedef semantic_actions<Iterator, HasState, static_data>
0302                 semantic_actions_type;
0303 
0304         protected:
0305             typedef static_data<Iterator, mpl::false_, HasState, TokenValue> 
0306                 base_type;
0307             typedef typename base_type::char_type char_type;
0308             typedef typename semantic_actions_type::functor_wrapper_type
0309                 functor_wrapper_type;
0310 
0311         public:
0312             typedef Iterator base_iterator_type;
0313             typedef TokenValue token_value_type;
0314             typedef TokenValue const& get_value_type;
0315             typedef typename base_type::state_type state_type;
0316             typedef typename base_type::state_name_type state_name_type;
0317 
0318             typedef detail::wrap_action<functor_wrapper_type
0319               , Iterator, static_data, std::size_t> wrap_action_type;
0320 
0321             template <typename IterData>
0322             static_data (IterData const& data, Iterator& first
0323                   , Iterator const& last)
0324               : base_type(data, first, last)
0325               , actions_(data.actions_), hold_()
0326               , value_(iterator_range<Iterator>(first, last))
0327               , has_value_(false)
0328               , has_hold_(false)
0329             {}
0330 
0331             // invoke attached semantic actions, if defined
0332             BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state
0333               , std::size_t& id, std::size_t unique_id, Iterator& end)
0334             {
0335                 return actions_.invoke_actions(state, id, unique_id, end, *this); 
0336             }
0337 
0338             // The function less() is used by the implementation of the support
0339             // function lex::less(). Its functionality is equivalent to flex'
0340             // function yyless(): it returns an iterator positioned to the 
0341             // nth input character beyond the current start iterator (i.e. by
0342             // assigning the return value to the placeholder '_end' it is 
0343             // possible to return all but the first n characters of the current 
0344             // token back to the input stream). 
0345             Iterator const& less(Iterator& it, int n) 
0346             {
0347                 it = this->get_first();
0348                 std::advance(it, n);
0349                 return it;
0350             }
0351 
0352             // The function more() is used by the implementation of the support 
0353             // function lex::more(). Its functionality is equivalent to flex'
0354             // function yymore(): it tells the lexer that the next time it 
0355             // matches a rule, the corresponding token should be appended onto 
0356             // the current token value rather than replacing it.
0357             void more()
0358             {
0359                 hold_ = this->get_first();
0360                 has_hold_ = true;
0361             }
0362 
0363             // The function lookahead() is used by the implementation of the 
0364             // support function lex::lookahead. It can be used to implement 
0365             // lookahead for lexer engines not supporting constructs like flex'
0366             // a/b  (match a, but only when followed by b)
0367             bool lookahead(std::size_t id, std::size_t state = std::size_t(~0))
0368             {
0369                 Iterator end = end_;
0370                 std::size_t unique_id = boost::lexer::npos;
0371                 bool bol = this->bol_;
0372 
0373                 if (std::size_t(~0) == state)
0374                     state = this->state_;
0375 
0376                 return id == this->next_token_(
0377                     state, bol, end, this->get_eoi(), unique_id);
0378             }
0379 
0380             // The adjust_start() and revert_adjust_start() are helper 
0381             // functions needed to implement the functionality required for 
0382             // lex::more(). It is called from the functor body below.
0383             bool adjust_start()
0384             {
0385                 if (!has_hold_)
0386                     return false;
0387 
0388                 std::swap(this->get_first(), hold_);
0389                 has_hold_ = false;
0390                 return true;
0391             }
0392             void revert_adjust_start()
0393             {
0394                 // this will be called only if adjust_start above returned true
0395                 std::swap(this->get_first(), hold_);
0396                 has_hold_ = true;
0397             }
0398 
0399             TokenValue const& get_value() const 
0400             {
0401                 if (!has_value_) {
0402                     value_ = iterator_range<Iterator>(this->get_first(), end_);
0403                     has_value_ = true;
0404                 }
0405                 return value_;
0406             }
0407             template <typename Value>
0408             void set_value(Value const& val)
0409             {
0410                 value_ = val;
0411                 has_value_ = true;
0412             }
0413             void set_end(Iterator const& it)
0414             {
0415                 end_ = it;
0416             }
0417             bool has_value() const { return has_value_; }
0418             void reset_value() { has_value_ = false; }
0419 
0420         protected:
0421             semantic_actions_type const& actions_;
0422             Iterator hold_;     // iterator needed to support lex::more()
0423             Iterator end_;      // iterator pointing to end of matched token
0424             mutable TokenValue value_;  // token value to use
0425             mutable bool has_value_;    // 'true' if value_ is valid
0426             bool has_hold_;     // 'true' if hold_ is valid
0427         };
0428 
0429         ///////////////////////////////////////////////////////////////////////
0430         //  does support lexer semantic actions, may support state, is used for
0431         //  position_token exposing exactly one type
0432         template <typename Iterator, typename HasState, typename TokenValue>
0433         class static_data<Iterator, mpl::true_, HasState, boost::optional<TokenValue> > 
0434           : public static_data<Iterator, mpl::false_, HasState, TokenValue>
0435         {
0436         public:
0437             typedef semantic_actions<Iterator, HasState, static_data> 
0438                 semantic_actions_type;
0439 
0440         protected:
0441             typedef static_data<Iterator, mpl::false_, HasState, TokenValue> 
0442                 base_type;
0443             typedef typename base_type::char_type char_type;
0444             typedef typename semantic_actions_type::functor_wrapper_type
0445                 functor_wrapper_type;
0446 
0447         public:
0448             typedef Iterator base_iterator_type;
0449             typedef boost::optional<TokenValue> token_value_type;
0450             typedef boost::optional<TokenValue> const& get_value_type;
0451             typedef typename base_type::state_type state_type;
0452             typedef typename base_type::state_name_type state_name_type;
0453 
0454             typedef detail::wrap_action<functor_wrapper_type
0455               , Iterator, static_data, std::size_t> wrap_action_type;
0456 
0457             template <typename IterData>
0458             static_data (IterData const& data_, Iterator& first, Iterator const& last)
0459               : base_type(data_, first, last)
0460               , actions_(data_.actions_), hold_()
0461               , has_value_(false), has_hold_(false) 
0462             {
0463                 spirit::traits::assign_to(first, last, value_);
0464                 has_value_ = true;
0465             }
0466 
0467             // invoke attached semantic actions, if defined
0468             BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state
0469               , std::size_t& id, std::size_t unique_id, Iterator& end)
0470             {
0471                 return actions_.invoke_actions(state, id, unique_id, end, *this); 
0472             }
0473 
0474             // The function less() is used by the implementation of the support
0475             // function lex::less(). Its functionality is equivalent to flex'
0476             // function yyless(): it returns an iterator positioned to the 
0477             // nth input character beyond the current start iterator (i.e. by
0478             // assigning the return value to the placeholder '_end' it is 
0479             // possible to return all but the first n characters of the current 
0480             // token back to the input stream). 
0481             Iterator const& less(Iterator& it, int n) 
0482             {
0483                 it = this->get_first();
0484                 std::advance(it, n);
0485                 return it;
0486             }
0487 
0488             // The function more() is used by the implementation of the support 
0489             // function lex::more(). Its functionality is equivalent to flex'
0490             // function yymore(): it tells the lexer that the next time it 
0491             // matches a rule, the corresponding token should be appended onto 
0492             // the current token value rather than replacing it.
0493             void more()
0494             {
0495                 hold_ = this->get_first();
0496                 has_hold_ = true;
0497             }
0498 
0499             // The function lookahead() is used by the implementation of the 
0500             // support function lex::lookahead. It can be used to implement 
0501             // lookahead for lexer engines not supporting constructs like flex'
0502             // a/b  (match a, but only when followed by b)
0503             bool lookahead(std::size_t id, std::size_t state = std::size_t(~0))
0504             {
0505                 Iterator end = end_;
0506                 std::size_t unique_id = boost::lexer::npos;
0507                 bool bol = this->bol_;
0508 
0509                 if (std::size_t(~0) == state)
0510                     state = this->state_;
0511 
0512                 return id == this->next_token_(
0513                     state, bol, end, this->get_eoi(), unique_id);
0514             }
0515 
0516             // The adjust_start() and revert_adjust_start() are helper 
0517             // functions needed to implement the functionality required for 
0518             // lex::more(). It is called from the functor body below.
0519             bool adjust_start()
0520             {
0521                 if (!has_hold_)
0522                     return false;
0523 
0524                 std::swap(this->get_first(), hold_);
0525                 has_hold_ = false;
0526                 return true;
0527             }
0528             void revert_adjust_start()
0529             {
0530                 // this will be called only if adjust_start above returned true
0531                 std::swap(this->get_first(), hold_);
0532                 has_hold_ = true;
0533             }
0534 
0535             TokenValue const& get_value() const 
0536             {
0537                 if (!has_value_) {
0538                     spirit::traits::assign_to(this->get_first(), end_, value_);
0539                     has_value_ = true;
0540                 }
0541                 return value_;
0542             }
0543             template <typename Value>
0544             void set_value(Value const& val)
0545             {
0546                 value_ = val;
0547                 has_value_ = true;
0548             }
0549             void set_end(Iterator const& it)
0550             {
0551                 end_ = it;
0552             }
0553             bool has_value() const { return has_value_; }
0554             void reset_value() { has_value_ = false; }
0555 
0556         protected:
0557             semantic_actions_type const& actions_;
0558             Iterator hold_;     // iterator needed to support lex::more()
0559             Iterator end_;      // iterator pointing to end of matched token
0560             mutable token_value_type value_;  // token value to use
0561             mutable bool has_value_;    // 'true' if value_ is valid
0562             bool has_hold_;     // 'true' if hold_ is valid
0563         };
0564     }
0565 }}}}
0566 #ifdef _MSC_VER
0567 #  pragma warning(pop)
0568 #endif
0569 
0570 #endif