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(BOOST_SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
14 #define BOOST_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(BOOST_SLEX_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
146