1 // debug.hpp
2 // Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_LEXER_DEBUG_HPP
7 #define BOOST_LEXER_DEBUG_HPP
8 
9 #include <map>
10 #include <ostream>
11 #include "rules.hpp"
12 #include "size_t.hpp"
13 #include "state_machine.hpp"
14 #include "string_token.hpp"
15 #include <vector>
16 
17 namespace boost
18 {
19 namespace lexer
20 {
21 template<typename CharT>
22 class basic_debug
23 {
24 public:
25     typedef std::basic_ostream<CharT> ostream;
26     typedef std::basic_string<CharT> string;
27     typedef std::vector<std::size_t> size_t_vector;
28 
escape_control_chars(const string & in_,string & out_)29     static void escape_control_chars (const string &in_, string &out_)
30     {
31         const CharT *ptr_ = in_.c_str ();
32         std::size_t size_ = in_.size ();
33 
34         out_.clear ();
35 
36         while (size_)
37         {
38             basic_string_token<CharT>::escape_char (*ptr_, out_);
39             ++ptr_;
40             --size_;
41         }
42     }
43 
dump(const basic_state_machine<CharT> & state_machine_,basic_rules<CharT> & rules_,ostream & stream_)44     static void dump (const basic_state_machine<CharT> &state_machine_,
45         basic_rules<CharT> &rules_, ostream &stream_)
46     {
47         typename basic_state_machine<CharT>::iterator iter_ =
48             state_machine_.begin ();
49         typename basic_state_machine<CharT>::iterator end_ =
50             state_machine_.end ();
51 
52         for (std::size_t dfa_ = 0, dfas_ = state_machine_.size ();
53             dfa_ < dfas_; ++dfa_)
54         {
55             lexer_state (stream_);
56             stream_ << rules_.state (dfa_) << std::endl << std::endl;
57 
58             dump_ex (iter_, stream_);
59         }
60     }
61 
dump(const basic_state_machine<CharT> & state_machine_,ostream & stream_)62     static void dump (const basic_state_machine<CharT> &state_machine_,
63         ostream &stream_)
64     {
65         typename basic_state_machine<CharT>::iterator iter_ =
66             state_machine_.begin ();
67         typename basic_state_machine<CharT>::iterator end_ =
68             state_machine_.end ();
69 
70         for (std::size_t dfa_ = 0, dfas_ = state_machine_.size ();
71             dfa_ < dfas_; ++dfa_)
72         {
73             lexer_state (stream_);
74             stream_ << dfa_ << std::endl << std::endl;
75 
76             dump_ex (iter_, stream_);
77         }
78     }
79 
80 protected:
81     typedef std::basic_stringstream<CharT> stringstream;
82 
dump_ex(typename basic_state_machine<CharT>::iterator & iter_,ostream & stream_)83     static void dump_ex (typename basic_state_machine<CharT>::iterator &iter_,
84         ostream &stream_)
85     {
86         const std::size_t states_ = iter_->states;
87 
88         for (std::size_t i_ = 0; i_ < states_; ++i_)
89         {
90             state (stream_);
91             stream_ << i_ << std::endl;
92 
93             if (iter_->end_state)
94             {
95                 end_state (stream_);
96                 stream_ << iter_->id;
97                 unique_id (stream_);
98                 stream_ << iter_->unique_id;
99                 dfa (stream_);
100                 stream_ << iter_->goto_dfa;
101                 stream_ << std::endl;
102             }
103 
104             if (iter_->bol_index != npos)
105             {
106                 bol (stream_);
107                 stream_ << iter_->bol_index << std::endl;
108             }
109 
110             if (iter_->eol_index != npos)
111             {
112                 eol (stream_);
113                 stream_ << iter_->eol_index << std::endl;
114             }
115 
116             const std::size_t transitions_ = iter_->transitions;
117 
118             if (transitions_ == 0)
119             {
120                 ++iter_;
121             }
122 
123             for (std::size_t t_ = 0; t_ < transitions_; ++t_)
124             {
125                 std::size_t goto_state_ = iter_->goto_state;
126 
127                 if (iter_->token.any ())
128                 {
129                     any (stream_);
130                 }
131                 else
132                 {
133                     open_bracket (stream_);
134 
135                     if (iter_->token._negated)
136                     {
137                         negated (stream_);
138                     }
139 
140                     string charset_;
141                     CharT c_ = 0;
142 
143                     escape_control_chars (iter_->token._charset,
144                         charset_);
145                     c_ = *charset_.c_str ();
146 
147                     if (!iter_->token._negated &&
148                         (c_ == '^' || c_ == ']'))
149                     {
150                         stream_ << '\\';
151                     }
152 
153                     stream_ << charset_;
154                     close_bracket (stream_);
155                 }
156 
157                 stream_ << goto_state_ << std::endl;
158                 ++iter_;
159             }
160 
161             stream_ << std::endl;
162         }
163     }
164 
lexer_state(std::ostream & stream_)165     static void lexer_state (std::ostream &stream_)
166     {
167         stream_ << "Lexer state: ";
168     }
169 
lexer_state(std::wostream & stream_)170     static void lexer_state (std::wostream &stream_)
171     {
172         stream_ << L"Lexer state: ";
173     }
174 
state(std::ostream & stream_)175     static void state (std::ostream &stream_)
176     {
177         stream_ << "State: ";
178     }
179 
state(std::wostream & stream_)180     static void state (std::wostream &stream_)
181     {
182         stream_ << L"State: ";
183     }
184 
bol(std::ostream & stream_)185     static void bol (std::ostream &stream_)
186     {
187         stream_ << "  BOL -> ";
188     }
189 
bol(std::wostream & stream_)190     static void bol (std::wostream &stream_)
191     {
192         stream_ << L"  BOL -> ";
193     }
194 
eol(std::ostream & stream_)195     static void eol (std::ostream &stream_)
196     {
197         stream_ << "  EOL -> ";
198     }
199 
eol(std::wostream & stream_)200     static void eol (std::wostream &stream_)
201     {
202         stream_ << L"  EOL -> ";
203     }
204 
end_state(std::ostream & stream_)205     static void end_state (std::ostream &stream_)
206     {
207         stream_ << "  END STATE, Id = ";
208     }
209 
end_state(std::wostream & stream_)210     static void end_state (std::wostream &stream_)
211     {
212         stream_ << L"  END STATE, Id = ";
213     }
214 
unique_id(std::ostream & stream_)215     static void unique_id (std::ostream &stream_)
216     {
217         stream_ << ", Unique Id = ";
218     }
219 
unique_id(std::wostream & stream_)220     static void unique_id (std::wostream &stream_)
221     {
222         stream_ << L", Unique Id = ";
223     }
224 
any(std::ostream & stream_)225     static void any (std::ostream &stream_)
226     {
227         stream_ << "  . -> ";
228     }
229 
any(std::wostream & stream_)230     static void any (std::wostream &stream_)
231     {
232         stream_ << L"  . -> ";
233     }
234 
open_bracket(std::ostream & stream_)235     static void open_bracket (std::ostream &stream_)
236     {
237         stream_ << "  [";
238     }
239 
open_bracket(std::wostream & stream_)240     static void open_bracket (std::wostream &stream_)
241     {
242         stream_ << L"  [";
243     }
244 
negated(std::ostream & stream_)245     static void negated (std::ostream &stream_)
246     {
247         stream_ << "^";
248     }
249 
negated(std::wostream & stream_)250     static void negated (std::wostream &stream_)
251     {
252         stream_ << L"^";
253     }
254 
close_bracket(std::ostream & stream_)255     static void close_bracket (std::ostream &stream_)
256     {
257         stream_ << "] -> ";
258     }
259 
close_bracket(std::wostream & stream_)260     static void close_bracket (std::wostream &stream_)
261     {
262         stream_ << L"] -> ";
263     }
264 
dfa(std::ostream & stream_)265     static void dfa (std::ostream &stream_)
266     {
267         stream_ << ", dfa = ";
268     }
269 
dfa(std::wostream & stream_)270     static void dfa (std::wostream &stream_)
271     {
272         stream_ << L", dfa = ";
273     }
274 };
275 
276 typedef basic_debug<char> debug;
277 typedef basic_debug<wchar_t> wdebug;
278 }
279 }
280 
281 #endif
282