PageRenderTime 110ms CodeModel.GetById 16ms app.highlight 82ms RepoModel.GetById 4ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp

http://hadesmem.googlecode.com/
C++ Header | 552 lines | 360 code | 72 blank | 120 comment | 16 complexity | 9650bfa185e42cdd362b14808a3f2e8a MD5 | raw file
  1//  Copyright (c) 2001-2011 Hartmut Kaiser
  2// 
  3//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
  4//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5
  6#if !defined(BOOST_SPIRIT_LEX_LEXER_FUNCTOR_DATA_JUN_10_2009_0954AM)
  7#define BOOST_SPIRIT_LEX_LEXER_FUNCTOR_DATA_JUN_10_2009_0954AM
  8
  9#if defined(_MSC_VER)
 10#pragma once
 11#endif
 12
 13#include <boost/spirit/home/qi/detail/assign_to.hpp>
 14#include <boost/spirit/home/support/detail/lexer/generator.hpp>
 15#include <boost/spirit/home/support/detail/lexer/rules.hpp>
 16#include <boost/spirit/home/support/detail/lexer/state_machine.hpp>
 17#include <boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp>
 18#include <boost/spirit/home/lex/lexer/lexertl/semantic_action_data.hpp>
 19#include <boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp>
 20#include <boost/mpl/bool.hpp>
 21#include <boost/optional.hpp>
 22
 23namespace boost { namespace spirit { namespace lex { namespace lexertl
 24{ 
 25    namespace detail
 26    {
 27        ///////////////////////////////////////////////////////////////////////
 28        template <typename Iterator, typename HasActors, typename HasState
 29          , typename TokenValue>
 30        class data;    // no default specialization
 31
 32        ///////////////////////////////////////////////////////////////////////
 33        //  neither supports state, nor actors
 34        template <typename Iterator, typename TokenValue>
 35        class data<Iterator, mpl::false_, mpl::false_, TokenValue>
 36        {
 37        protected:
 38            typedef typename 
 39                boost::detail::iterator_traits<Iterator>::value_type 
 40            char_type;
 41
 42        public:
 43            typedef Iterator base_iterator_type;
 44            typedef iterator_range<Iterator> token_value_type;
 45            typedef token_value_type get_value_type;
 46            typedef std::size_t state_type;
 47            typedef char_type const* state_name_type;
 48            typedef unused_type semantic_actions_type;
 49            typedef detail::wrap_action<unused_type, Iterator, data, std::size_t>
 50                wrap_action_type;
 51
 52            typedef unused_type next_token_functor;
 53            typedef unused_type get_state_name_type;
 54
 55            // initialize the shared data 
 56            template <typename IterData>
 57            data (IterData const& data_, Iterator& first, Iterator const& last)
 58              : first_(first), last_(last)
 59              , state_machine_(data_.state_machine_)
 60              , rules_(data_.rules_)
 61              , bol_(data_.state_machine_.data()._seen_BOL_assertion) {}
 62
 63            // The following functions are used by the implementation of the 
 64            // placeholder '_state'.
 65            template <typename Char>
 66            void set_state_name (Char const*) 
 67            {
 68// some (random) versions of gcc instantiate this function even if it's not 
 69// needed leading to false static asserts
 70#if !defined(__GNUC__)
 71                // If you see a compile time assertion below you're probably 
 72                // using a token type not supporting lexer states (the 3rd 
 73                // template parameter of the token is mpl::false_), but your 
 74                // code uses state changes anyways.
 75                BOOST_STATIC_ASSERT(false);
 76#endif
 77            }
 78            char_type const* get_state_name() const { return rules_.initial(); }
 79            std::size_t get_state_id (char_type const*) const
 80            {
 81                return 0;
 82            }
 83
 84            // The function get_eoi() is used by the implementation of the 
 85            // placeholder '_eoi'.
 86            Iterator const& get_eoi() const { return last_; }
 87
 88            // The function less() is used by the implementation of the support
 89            // function lex::less(). Its functionality is equivalent to flex'
 90            // function yyless(): it returns an iterator positioned to the 
 91            // nth input character beyond the current start iterator (i.e. by
 92            // assigning the return value to the placeholder '_end' it is 
 93            // possible to return all but the first n characters of the current 
 94            // token back to the input stream. 
 95            //
 96            // This function does nothing as long as no semantic actions are 
 97            // used.
 98            Iterator const& less(Iterator const& it, int) 
 99            { 
100                // The following assertion fires most likely because you are 
101                // using lexer semantic actions without using the actor_lexer
102                // as the base class for your token definition class.
103                BOOST_ASSERT(false && 
104                    "Are you using lexer semantic actions without using the "
105                    "actor_lexer base?");
106                return it; 
107            }
108
109            // The function more() is used by the implementation of the support 
110            // function lex::more(). Its functionality is equivalent to flex'
111            // function yymore(): it tells the lexer that the next time it 
112            // matches a rule, the corresponding token should be appended onto 
113            // the current token value rather than replacing it.
114            // 
115            // These functions do nothing as long as no semantic actions are 
116            // used.
117            void more() 
118            { 
119                // The following assertion fires most likely because you are 
120                // using lexer semantic actions without using the actor_lexer
121                // as the base class for your token definition class.
122                BOOST_ASSERT(false && 
123                    "Are you using lexer semantic actions without using the "
124                    "actor_lexer base?"); 
125            }
126            bool adjust_start() { return false; }
127            void revert_adjust_start() {}
128
129            // The function lookahead() is used by the implementation of the 
130            // support function lex::lookahead. It can be used to implement 
131            // lookahead for lexer engines not supporting constructs like flex'
132            // a/b  (match a, but only when followed by b):
133            //
134            // This function does nothing as long as no semantic actions are 
135            // used.
136            bool lookahead(std::size_t, std::size_t /*state*/ = std::size_t(~0)) 
137            { 
138                // The following assertion fires most likely because you are 
139                // using lexer semantic actions without using the actor_lexer
140                // as the base class for your token definition class.
141                BOOST_ASSERT(false && 
142                    "Are you using lexer semantic actions without using the "
143                    "actor_lexer base?");
144                return false; 
145            }
146
147            // the functions next, invoke_actions, and get_state are used by 
148            // the functor implementation below
149
150            // The function next() tries to match the next token from the 
151            // underlying input sequence. 
152            std::size_t next(Iterator& end, std::size_t& unique_id, bool& prev_bol)
153            {
154                prev_bol = bol_;
155
156                typedef basic_iterator_tokeniser<Iterator> tokenizer;
157                return tokenizer::next(state_machine_, bol_, end, last_
158                  , unique_id);
159            }
160
161            // nothing to invoke, so this is empty
162            BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t
163              , std::size_t, std::size_t, Iterator const&) 
164            {
165                return pass_flags::pass_normal;    // always accept
166            }
167
168            std::size_t get_state() const { return 0; }
169            void set_state(std::size_t) {}
170
171            void set_end(Iterator const& it) {}
172
173            Iterator& get_first() { return first_; }
174            Iterator const& get_first() const { return first_; }
175            Iterator const& get_last() const { return last_; }
176
177            iterator_range<Iterator> get_value() const 
178            { 
179                return iterator_range<Iterator>(first_, last_); 
180            }
181            bool has_value() const { return false; }
182            void reset_value() {}
183
184            void reset_bol(bool bol) { bol_ = bol; }
185
186        protected:
187            Iterator& first_;
188            Iterator last_;
189
190            boost::lexer::basic_state_machine<char_type> const& state_machine_;
191            boost::lexer::basic_rules<char_type> const& rules_;
192
193            bool bol_;      // helper storing whether last character was \n
194
195        private:
196            // silence MSVC warning C4512: assignment operator could not be generated
197            data& operator= (data const&);
198        };
199
200        ///////////////////////////////////////////////////////////////////////
201        //  doesn't support lexer semantic actions, but supports state
202        template <typename Iterator, typename TokenValue>
203        class data<Iterator, mpl::false_, mpl::true_, TokenValue>
204          : public data<Iterator, mpl::false_, mpl::false_, TokenValue>
205        {
206        protected:
207            typedef data<Iterator, mpl::false_, mpl::false_, TokenValue> base_type;
208            typedef typename base_type::char_type char_type;
209
210        public:
211            typedef Iterator base_iterator_type;
212            typedef iterator_range<Iterator> token_value_type;
213            typedef token_value_type get_value_type;
214            typedef typename base_type::state_type state_type;
215            typedef typename base_type::state_name_type state_name_type;
216            typedef typename base_type::semantic_actions_type 
217                semantic_actions_type;
218
219            // initialize the shared data 
220            template <typename IterData>
221            data (IterData const& data_, Iterator& first, Iterator const& last)
222              : base_type(data_, first, last)
223              , state_(0) {}
224
225            // The following functions are used by the implementation of the 
226            // placeholder '_state'.
227            void set_state_name (char_type const* new_state) 
228            { 
229                std::size_t state_id = this->rules_.state(new_state);
230
231                // If the following assertion fires you've probably been using 
232                // a lexer state name which was not defined in your token 
233                // definition.
234                BOOST_ASSERT(state_id != boost::lexer::npos);
235
236                if (state_id != boost::lexer::npos)
237                    state_ = state_id;
238            }
239            char_type const* get_state_name() const
240            {
241                return this->rules_.state(state_);
242            }
243            std::size_t get_state_id (char_type const* state) const
244            {
245                return this->rules_.state(state);
246            }
247
248            // the functions next() and get_state() are used by the functor 
249            // implementation below
250
251            // The function next() tries to match the next token from the 
252            // underlying input sequence. 
253            std::size_t next(Iterator& end, std::size_t& unique_id, bool& prev_bol)
254            {
255                prev_bol = this->bol_;
256
257                typedef basic_iterator_tokeniser<Iterator> tokenizer;
258                return tokenizer::next(this->state_machine_, state_, 
259                    this->bol_, end, this->get_eoi(), unique_id);
260            }
261
262            std::size_t& get_state() { return state_; }
263            void set_state(std::size_t state) { state_ = state; }
264
265        protected:
266            std::size_t state_;
267
268        private:
269            // silence MSVC warning C4512: assignment operator could not be generated
270            data& operator= (data const&);
271        };
272
273        ///////////////////////////////////////////////////////////////////////
274        //  does support lexer semantic actions, may support state
275        template <typename Iterator, typename HasState, typename TokenValue>
276        class data<Iterator, mpl::true_, HasState, TokenValue> 
277          : public data<Iterator, mpl::false_, HasState, TokenValue>
278        {
279        public:
280            typedef semantic_actions<Iterator, HasState, data> 
281                semantic_actions_type;
282
283        protected:
284            typedef data<Iterator, mpl::false_, HasState, TokenValue> base_type;
285            typedef typename base_type::char_type char_type;
286            typedef typename semantic_actions_type::functor_wrapper_type
287                functor_wrapper_type;
288
289        public:
290            typedef Iterator base_iterator_type;
291            typedef TokenValue token_value_type;
292            typedef TokenValue const& get_value_type;
293            typedef typename base_type::state_type state_type;
294            typedef typename base_type::state_name_type state_name_type;
295
296            typedef detail::wrap_action<functor_wrapper_type
297              , Iterator, data, std::size_t> wrap_action_type;
298
299            template <typename IterData>
300            data (IterData const& data_, Iterator& first, Iterator const& last)
301              : base_type(data_, first, last)
302              , actions_(data_.actions_), hold_()
303              , value_(iterator_range<Iterator>(first, last))
304              , has_value_(false), has_hold_(false) {}
305
306            // invoke attached semantic actions, if defined
307            BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state
308              , std::size_t& id, std::size_t unique_id, Iterator& end)
309            {
310                return actions_.invoke_actions(state, id, unique_id, end, *this); 
311            }
312
313            // The function less() is used by the implementation of the support
314            // function lex::less(). Its functionality is equivalent to flex'
315            // function yyless(): it returns an iterator positioned to the 
316            // nth input character beyond the current start iterator (i.e. by
317            // assigning the return value to the placeholder '_end' it is 
318            // possible to return all but the first n characters of the current 
319            // token back to the input stream). 
320            Iterator const& less(Iterator& it, int n) 
321            {
322                it = this->get_first();
323                std::advance(it, n);
324                return it;
325            }
326
327            // The function more() is used by the implementation of the support 
328            // function lex::more(). Its functionality is equivalent to flex'
329            // function yymore(): it tells the lexer that the next time it 
330            // matches a rule, the corresponding token should be appended onto 
331            // the current token value rather than replacing it.
332            void more()
333            {
334                hold_ = this->get_first();
335                has_hold_ = true;
336            }
337
338            // The function lookahead() is used by the implementation of the 
339            // support function lex::lookahead. It can be used to implement 
340            // lookahead for lexer engines not supporting constructs like flex'
341            // a/b  (match a, but only when followed by b)
342            bool lookahead(std::size_t id, std::size_t state = std::size_t(~0))
343            {
344                Iterator end = end_;
345                std::size_t unique_id = boost::lexer::npos;
346                bool bol = this->bol_;
347
348                if (std::size_t(~0) == state)
349                    state = this->state_;
350
351                typedef basic_iterator_tokeniser<Iterator> tokenizer;
352                return id == tokenizer::next(this->state_machine_, state, 
353                    bol, end, this->get_eoi(), unique_id);
354            }
355
356            // The adjust_start() and revert_adjust_start() are helper 
357            // functions needed to implement the functionality required for 
358            // lex::more(). It is called from the functor body below.
359            bool adjust_start()
360            {
361                if (!has_hold_)
362                    return false;
363
364                std::swap(this->get_first(), hold_);
365                has_hold_ = false;
366                return true;
367            }
368            void revert_adjust_start()
369            {
370                // this will be called only if adjust_start above returned true
371                std::swap(this->get_first(), hold_);
372                has_hold_ = true;
373            }
374
375            TokenValue const& get_value() const 
376            {
377                if (!has_value_) {
378                    value_ = iterator_range<Iterator>(this->get_first(), end_);
379                    has_value_ = true;
380                }
381                return value_;
382            }
383            template <typename Value>
384            void set_value(Value const& val)
385            {
386                value_ = val;
387                has_value_ = true;
388            }
389            void set_end(Iterator const& it)
390            {
391                end_ = it;
392            }
393            bool has_value() const { return has_value_; }
394            void reset_value() { has_value_ = false; }
395
396        protected:
397            semantic_actions_type const& actions_;
398            Iterator hold_;     // iterator needed to support lex::more()
399            Iterator end_;      // iterator pointing to end of matched token
400            mutable TokenValue value_;  // token value to use
401            mutable bool has_value_;    // 'true' if value_ is valid
402            bool has_hold_;     // 'true' if hold_ is valid
403
404        private:
405            // silence MSVC warning C4512: assignment operator could not be generated
406            data& operator= (data const&);
407        };
408
409        ///////////////////////////////////////////////////////////////////////
410        //  does support lexer semantic actions, may support state, is used for
411        //  position_token exposing exactly one type
412        template <typename Iterator, typename HasState, typename TokenValue>
413        class data<Iterator, mpl::true_, HasState, boost::optional<TokenValue> > 
414          : public data<Iterator, mpl::false_, HasState, TokenValue>
415        {
416        public:
417            typedef semantic_actions<Iterator, HasState, data> 
418                semantic_actions_type;
419
420        protected:
421            typedef data<Iterator, mpl::false_, HasState, TokenValue> base_type;
422            typedef typename base_type::char_type char_type;
423            typedef typename semantic_actions_type::functor_wrapper_type
424                functor_wrapper_type;
425
426        public:
427            typedef Iterator base_iterator_type;
428            typedef boost::optional<TokenValue> token_value_type;
429            typedef boost::optional<TokenValue> const& get_value_type;
430            typedef typename base_type::state_type state_type;
431            typedef typename base_type::state_name_type state_name_type;
432
433            typedef detail::wrap_action<functor_wrapper_type
434              , Iterator, data, std::size_t> wrap_action_type;
435
436            template <typename IterData>
437            data (IterData const& data_, Iterator& first, Iterator const& last)
438              : base_type(data_, first, last)
439              , actions_(data_.actions_), hold_()
440              , has_value_(false), has_hold_(false) 
441            {
442                spirit::traits::assign_to(first, last, value_);
443                has_value_ = true;
444            }
445
446            // invoke attached semantic actions, if defined
447            BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state
448              , std::size_t& id, std::size_t unique_id, Iterator& end)
449            {
450                return actions_.invoke_actions(state, id, unique_id, end, *this); 
451            }
452
453            // The function less() is used by the implementation of the support
454            // function lex::less(). Its functionality is equivalent to flex'
455            // function yyless(): it returns an iterator positioned to the 
456            // nth input character beyond the current start iterator (i.e. by
457            // assigning the return value to the placeholder '_end' it is 
458            // possible to return all but the first n characters of the current 
459            // token back to the input stream). 
460            Iterator const& less(Iterator& it, int n) 
461            {
462                it = this->get_first();
463                std::advance(it, n);
464                return it;
465            }
466
467            // The function more() is used by the implementation of the support 
468            // function lex::more(). Its functionality is equivalent to flex'
469            // function yymore(): it tells the lexer that the next time it 
470            // matches a rule, the corresponding token should be appended onto 
471            // the current token value rather than replacing it.
472            void more()
473            {
474                hold_ = this->get_first();
475                has_hold_ = true;
476            }
477
478            // The function lookahead() is used by the implementation of the 
479            // support function lex::lookahead. It can be used to implement 
480            // lookahead for lexer engines not supporting constructs like flex'
481            // a/b  (match a, but only when followed by b)
482            bool lookahead(std::size_t id, std::size_t state = std::size_t(~0))
483            {
484                Iterator end = end_;
485                std::size_t unique_id = boost::lexer::npos;
486                bool bol = this->bol_;
487
488                if (std::size_t(~0) == state)
489                    state = this->state_;
490
491                typedef basic_iterator_tokeniser<Iterator> tokenizer;
492                return id == tokenizer::next(this->state_machine_, state, 
493                    bol, end, this->get_eoi(), unique_id);
494            }
495
496            // The adjust_start() and revert_adjust_start() are helper 
497            // functions needed to implement the functionality required for 
498            // lex::more(). It is called from the functor body below.
499            bool adjust_start()
500            {
501                if (!has_hold_)
502                    return false;
503
504                std::swap(this->get_first(), hold_);
505                has_hold_ = false;
506                return true;
507            }
508            void revert_adjust_start()
509            {
510                // this will be called only if adjust_start above returned true
511                std::swap(this->get_first(), hold_);
512                has_hold_ = true;
513            }
514
515            token_value_type const& get_value() const 
516            {
517                if (!has_value_) {
518                    spirit::traits::assign_to(this->get_first(), end_, value_);
519                    has_value_ = true;
520                }
521                return value_;
522            }
523            template <typename Value>
524            void set_value(Value const& val)
525            {
526                value_ = val;
527                has_value_ = true;
528            }
529            void set_end(Iterator const& it)
530            {
531                end_ = it;
532            }
533            bool has_value() const { return has_value_; }
534            void reset_value() { has_value_ = false; }
535
536        protected:
537            semantic_actions_type const& actions_;
538            Iterator hold_;     // iterator needed to support lex::more()
539            Iterator end_;      // iterator pointing to end of matched token
540            mutable token_value_type value_;  // token value to use
541            mutable bool has_value_;    // 'true' if value_ is valid
542            bool has_hold_;     // 'true' if hold_ is valid
543
544        private:
545            // silence MSVC warning C4512: assignment operator could not be generated
546            data& operator= (data const&);
547        };
548    }
549}}}}
550
551#endif
552