// debug.hpp | |
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/) | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
#ifndef BOOST_LEXER_DEBUG_HPP | |
#define BOOST_LEXER_DEBUG_HPP | |
#include <map> | |
#include <ostream> | |
#include "rules.hpp" | |
#include "size_t.hpp" | |
#include "state_machine.hpp" | |
#include "string_token.hpp" | |
#include <vector> | |
namespace boost | |
{ | |
namespace lexer | |
{ | |
template<typename CharT> | |
class basic_debug | |
{ | |
public: | |
typedef std::basic_ostream<CharT> ostream; | |
typedef std::basic_string<CharT> string; | |
typedef std::vector<std::size_t> size_t_vector; | |
static void escape_control_chars (const string &in_, string &out_) | |
{ | |
const CharT *ptr_ = in_.c_str (); | |
std::size_t size_ = in_.size (); | |
#if defined _MSC_VER && _MSC_VER <= 1200 | |
out_.erase (); | |
#else | |
out_.clear (); | |
#endif | |
while (size_) | |
{ | |
basic_string_token<CharT>::escape_char (*ptr_, out_); | |
++ptr_; | |
--size_; | |
} | |
} | |
static void dump (const basic_state_machine<CharT> &state_machine_, | |
basic_rules<CharT> &rules_, ostream &stream_) | |
{ | |
typename basic_state_machine<CharT>::iterator iter_ = | |
state_machine_.begin (); | |
typename basic_state_machine<CharT>::iterator end_ = | |
state_machine_.end (); | |
for (std::size_t dfa_ = 0, dfas_ = state_machine_.size (); | |
dfa_ < dfas_; ++dfa_) | |
{ | |
lexer_state (stream_); | |
stream_ << rules_.state (dfa_) << std::endl << std::endl; | |
dump_ex (iter_, stream_); | |
} | |
} | |
static void dump (const basic_state_machine<CharT> &state_machine_, | |
ostream &stream_) | |
{ | |
typename basic_state_machine<CharT>::iterator iter_ = | |
state_machine_.begin (); | |
typename basic_state_machine<CharT>::iterator end_ = | |
state_machine_.end (); | |
for (std::size_t dfa_ = 0, dfas_ = state_machine_.size (); | |
dfa_ < dfas_; ++dfa_) | |
{ | |
lexer_state (stream_); | |
stream_ << dfa_ << std::endl << std::endl; | |
dump_ex (iter_, stream_); | |
} | |
} | |
protected: | |
typedef std::basic_stringstream<CharT> stringstream; | |
static void dump_ex (typename basic_state_machine<CharT>::iterator &iter_, | |
ostream &stream_) | |
{ | |
const std::size_t states_ = iter_->states; | |
for (std::size_t i_ = 0; i_ < states_; ++i_) | |
{ | |
state (stream_); | |
stream_ << i_ << std::endl; | |
if (iter_->end_state) | |
{ | |
end_state (stream_); | |
stream_ << iter_->id; | |
unique_id (stream_); | |
stream_ << iter_->unique_id; | |
dfa (stream_); | |
stream_ << iter_->goto_dfa; | |
stream_ << std::endl; | |
} | |
if (iter_->bol_index != npos) | |
{ | |
bol (stream_); | |
stream_ << iter_->bol_index << std::endl; | |
} | |
if (iter_->eol_index != npos) | |
{ | |
eol (stream_); | |
stream_ << iter_->eol_index << std::endl; | |
} | |
const std::size_t transitions_ = iter_->transitions; | |
if (transitions_ == 0) | |
{ | |
++iter_; | |
} | |
for (std::size_t t_ = 0; t_ < transitions_; ++t_) | |
{ | |
std::size_t goto_state_ = iter_->goto_state; | |
if (iter_->token.any ()) | |
{ | |
any (stream_); | |
} | |
else | |
{ | |
open_bracket (stream_); | |
if (iter_->token._negated) | |
{ | |
negated (stream_); | |
} | |
string charset_; | |
CharT c_ = 0; | |
escape_control_chars (iter_->token._charset, | |
charset_); | |
c_ = *charset_.c_str (); | |
if (!iter_->token._negated && | |
(c_ == '^' || c_ == ']')) | |
{ | |
stream_ << '\\'; | |
} | |
stream_ << charset_; | |
close_bracket (stream_); | |
} | |
stream_ << goto_state_ << std::endl; | |
++iter_; | |
} | |
stream_ << std::endl; | |
} | |
} | |
static void lexer_state (std::ostream &stream_) | |
{ | |
stream_ << "Lexer state: "; | |
} | |
static void lexer_state (std::wostream &stream_) | |
{ | |
stream_ << L"Lexer state: "; | |
} | |
static void state (std::ostream &stream_) | |
{ | |
stream_ << "State: "; | |
} | |
static void state (std::wostream &stream_) | |
{ | |
stream_ << L"State: "; | |
} | |
static void bol (std::ostream &stream_) | |
{ | |
stream_ << " BOL -> "; | |
} | |
static void bol (std::wostream &stream_) | |
{ | |
stream_ << L" BOL -> "; | |
} | |
static void eol (std::ostream &stream_) | |
{ | |
stream_ << " EOL -> "; | |
} | |
static void eol (std::wostream &stream_) | |
{ | |
stream_ << L" EOL -> "; | |
} | |
static void end_state (std::ostream &stream_) | |
{ | |
stream_ << " END STATE, Id = "; | |
} | |
static void end_state (std::wostream &stream_) | |
{ | |
stream_ << L" END STATE, Id = "; | |
} | |
static void unique_id (std::ostream &stream_) | |
{ | |
stream_ << ", Unique Id = "; | |
} | |
static void unique_id (std::wostream &stream_) | |
{ | |
stream_ << L", Unique Id = "; | |
} | |
static void any (std::ostream &stream_) | |
{ | |
stream_ << " . -> "; | |
} | |
static void any (std::wostream &stream_) | |
{ | |
stream_ << L" . -> "; | |
} | |
static void open_bracket (std::ostream &stream_) | |
{ | |
stream_ << " ["; | |
} | |
static void open_bracket (std::wostream &stream_) | |
{ | |
stream_ << L" ["; | |
} | |
static void negated (std::ostream &stream_) | |
{ | |
stream_ << "^"; | |
} | |
static void negated (std::wostream &stream_) | |
{ | |
stream_ << L"^"; | |
} | |
static void close_bracket (std::ostream &stream_) | |
{ | |
stream_ << "] -> "; | |
} | |
static void close_bracket (std::wostream &stream_) | |
{ | |
stream_ << L"] -> "; | |
} | |
static void dfa (std::ostream &stream_) | |
{ | |
stream_ << ", dfa = "; | |
} | |
static void dfa (std::wostream &stream_) | |
{ | |
stream_ << L", dfa = "; | |
} | |
}; | |
typedef basic_debug<char> debug; | |
typedef basic_debug<wchar_t> wdebug; | |
} | |
} | |
#endif |