Back to home page

EIC code displayed by LXR

 
 

    


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

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