source: NonGTP/Boost/boost/wave/cpplexer/cpp_lex_iterator.hpp @ 857

Revision 857, 5.8 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3
4    Definition of the lexer iterator
5   
6    http://www.boost.org/
7
8    Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost
9    Software License, Version 1.0. (See accompanying file
10    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11=============================================================================*/
12
13#if !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)
14#define CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED
15
16#include <string>
17#include <iostream>
18
19#include <boost/assert.hpp>
20#include <boost/shared_ptr.hpp>
21#include <boost/spirit/iterator/multi_pass.hpp>
22
23#include <boost/wave/util/file_position.hpp>
24#include <boost/wave/util/functor_input.hpp>
25#include <boost/wave/cpplexer/cpp_lex_interface.hpp>
26
27#include <boost/wave/language_support.hpp>
28
29#if 0 != __COMO_VERSION__
30#define BOOST_WAVE_EOF_PREFIX static
31#else
32#define BOOST_WAVE_EOF_PREFIX
33#endif
34
35///////////////////////////////////////////////////////////////////////////////
36namespace boost {
37namespace wave {
38namespace cpplexer {
39namespace impl {
40
41///////////////////////////////////////////////////////////////////////////////
42// 
43//  lex_iterator_functor_shim
44//
45///////////////////////////////////////////////////////////////////////////////
46
47template <typename TokenT>
48class lex_iterator_functor_shim
49{
50public:
51    template <typename IteratorT>
52    lex_iterator_functor_shim(IteratorT const &first, IteratorT const &last,
53            typename TokenT::position_type const &pos,
54            boost::wave::language_support language)
55    :   functor_ptr(lex_input_interface<TokenT>
56            ::new_lexer(first, last, pos, language))
57#if 0 != __DECCXX_VER
58      , eof()
59#endif // 0 != __DECCXX_VER
60    {}
61
62// interface to the boost::spirit::multi_pass_policies::functor_input policy
63    typedef TokenT result_type;
64
65    BOOST_WAVE_EOF_PREFIX result_type const eof;
66   
67    result_type operator()()
68    {
69        BOOST_ASSERT(0 != functor_ptr.get());
70        return functor_ptr->get();
71    }
72    void set_position(typename TokenT::position_type const &pos)
73    {
74        BOOST_ASSERT(0 != functor_ptr.get());
75        functor_ptr->set_position(pos);
76    }
77   
78private:
79    boost::shared_ptr<lex_input_interface<TokenT> > functor_ptr;
80};
81
82///////////////////////////////////////////////////////////////////////////////
83//  eof token
84#if 0 != __COMO_VERSION__
85template <typename TokenT>
86typename lex_iterator_functor_shim<TokenT>::result_type const
87    lex_iterator_functor_shim<TokenT>::eof;
88#endif // 0 != __COMO_VERSION__
89
90///////////////////////////////////////////////////////////////////////////////
91}   // namespace impl
92
93///////////////////////////////////////////////////////////////////////////////
94// 
95//  lex_iterator
96//
97//      A generic C++ lexer interface class, which allows to plug in different
98//      lexer implementations. The interface between the lexer type used and
99//      the preprocessor component depends on the token type only (template
100//      parameter TokenT).
101//      Additionally, the following requirements apply:
102//
103//          - the lexer type should have a function implemented, which returnes
104//            the next lexed token from the input stream:
105//                typename TokenT get();
106//          - at the end of the input stream this function should return the
107//            eof token equivalent
108//          - the lexer should implement a constructor taking two iterators
109//            pointing to the beginning and the end of the input stream,
110//            a third parameter containing the name of the parsed input file
111//            and a 4th parameter of the type boost::wave::language_support
112//            which specifies, which language subset should be supported (C++,
113//            C99, C++0x etc.).
114//
115///////////////////////////////////////////////////////////////////////////////
116
117template <typename TokenT>
118class lex_iterator
119:   public boost::spirit::multi_pass<
120        impl::lex_iterator_functor_shim<TokenT>,
121        boost::wave::util::functor_input
122    >
123{
124    typedef impl::lex_iterator_functor_shim<TokenT> input_policy_type;
125    typedef
126        boost::spirit::multi_pass<input_policy_type,
127                boost::wave::util::functor_input>
128        base_type;
129   
130public:
131    typedef TokenT token_type;
132   
133    lex_iterator()
134    {}
135   
136    template <typename IteratorT>
137    lex_iterator(IteratorT const &first, IteratorT const &last,
138            typename TokenT::position_type const &pos,
139            boost::wave::language_support language)
140    :   base_type(input_policy_type(first, last, pos, language))
141    {}
142
143    void set_position(typename TokenT::position_type const &pos)
144    {
145        typedef typename TokenT::position_type position_type;
146       
147    // set the new position in the current token
148    token_type& currtoken = base_type::get_input();
149    position_type currpos = currtoken.get_position();
150
151        currpos.set_file(pos.get_file());
152        currpos.set_line(pos.get_line());
153        currtoken.set_position(currpos);
154       
155    // set the new position for future tokens as well
156        if (token_type::string_type::npos !=
157            currtoken.get_value().find_first_of('\n'))
158        {
159            currpos.set_line(pos.get_line() + 1);
160        }
161        base_type::get_functor().set_position(currpos);
162    }
163};
164
165///////////////////////////////////////////////////////////////////////////////
166}   // namespace cpplexer
167}   // namespace wave
168}   // namespace boost
169
170#undef BOOST_WAVE_EOF_PREFIX
171
172#endif // !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)
Note: See TracBrowser for help on using the repository browser.