1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3 
4     A generic C++ lexer token definition
5 
6     http://www.boost.org/
7 
8     Copyright (c) 2001-2012 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(SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
14 #define SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED
15 
16 #include <iomanip>
17 #include <ios>
18 
19 #include <boost/wave/wave_config.hpp>
20 #include <boost/wave/token_ids.hpp>
21 #include <boost/wave/language_support.hpp>
22 #include <boost/wave/util/file_position.hpp>
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 namespace boost {
26 namespace wave {
27 namespace cpplexer {
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 //  forward declaration of the token type
31 template <typename PositionT = boost::wave::util::file_position_type>
32 class slex_token;
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 //
36 //  lex_token
37 //
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 template <typename PositionT>
41 class slex_token
42 {
43 public:
44     typedef BOOST_WAVE_STRINGTYPE   string_type;
45     typedef PositionT               position_type;
46 
slex_token()47     slex_token()
48     :   id(T_EOI)
49     {}
50 
51     //  construct an invalid token
slex_token(int)52     explicit slex_token(int)
53     :   id(T_UNKNOWN)
54     {}
55 
slex_token(token_id id_,string_type const & value_,PositionT const & pos_)56     slex_token(token_id id_, string_type const &value_, PositionT const &pos_)
57     :   id(id_), value(value_), pos(pos_)
58     {}
59 
60 // accessors
operator token_id() const61     operator token_id() const { return id; }
get_value() const62     string_type const &get_value() const { return value; }
get_position() const63     position_type const &get_position() const { return pos; }
is_eoi() const64     bool is_eoi() const { return id == T_EOI; }
is_valid() const65     bool is_valid() const { return id != T_UNKNOWN; }
66 
set_token_id(token_id id_)67     void set_token_id (token_id id_) { id = id_; }
set_value(string_type const & newval)68     void set_value (string_type const &newval) { value = newval; }
set_position(position_type const & pos_)69     void set_position (position_type const &pos_) { pos = pos_; }
70 
operator ==(slex_token const & lhs,slex_token const & rhs)71     friend bool operator== (slex_token const& lhs, slex_token const& rhs)
72     {
73         //  two tokens are considered equal even if they contain different
74         //  positions
75         return (lhs.id == rhs.id && lhs.value == rhs.value) ? true : false;
76     }
77 
78 // debug support
79 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
80 // access functions for the tree_to_xml functionality
get_token_id(slex_token const & t)81     static int get_token_id(slex_token const &t)
82         { return ID_FROM_TOKEN(token_id(t)); }
get_token_value(slex_token const & t)83     static string_type get_token_value(slex_token const &t)
84         { return t.get_value(); }
85 #endif
86 
87 // print support
print(std::ostream & stream) const88     void print (std::ostream &stream) const
89     {
90         using namespace std;
91         using namespace boost::wave;
92 
93         stream << std::setw(16)
94             << std::left << boost::wave::get_token_name(id) << " ("
95             << "#" << token_id(BASEID_FROM_TOKEN(*this))
96             << ") at " << get_position().get_file() << " ("
97             << std::setw(3) << std::right << get_position().get_line() << "/"
98             << std::setw(2) << std::right << get_position().get_column()
99             << "): >";
100 
101         for (std::size_t i = 0; i < value.size(); ++i) {
102             switch (value[i]) {
103             case '\r':  stream << "\\r"; break;
104             case '\n':  stream << "\\n"; break;
105             case '\t':  stream << "\\t"; break;
106             default:
107                 stream << value[i];
108                 break;
109             }
110         }
111         stream << "<";
112     }
113 
114 private:
115     boost::wave::token_id id;   // the token id
116     string_type value;             // the text, which was parsed into this token
117     PositionT pos;              // the original file position
118 };
119 
120 template <typename PositionT>
121 inline std::ostream &
operator <<(std::ostream & stream,slex_token<PositionT> const & object)122 operator<< (std::ostream &stream, slex_token<PositionT> const &object)
123 {
124     object.print(stream);
125     return stream;
126 }
127 
128 ///////////////////////////////////////////////////////////////////////////////
129 //  This overload is needed by the multi_pass/functor_input_policy to
130 //  validate a token instance. It has to be defined in the same namespace
131 //  as the token class itself to allow ADL to find it.
132 ///////////////////////////////////////////////////////////////////////////////
133 template <typename Position>
134 inline bool
token_is_valid(slex_token<Position> const & t)135 token_is_valid(slex_token<Position> const& t)
136 {
137     return t.is_valid();
138 }
139 
140 ///////////////////////////////////////////////////////////////////////////////
141 }   // namespace cpplexer
142 }   // namespace wave
143 }   // namespace boost
144 
145 #endif // !defined(SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
146