// debug.hpp // Copyright (c) 2005-2018 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 LEXERTL_DEBUG_HPP #define LEXERTL_DEBUG_HPP #include #include #include "rules.hpp" #include "sm_to_csm.hpp" #include "state_machine.hpp" #include "string_token.hpp" #include namespace lexertl { template class basic_debug { public: using char_state_machine = basic_char_state_machine; using ostream = std::basic_ostream; using rules = basic_rules; using string = std::basic_string; static void dump(const sm &sm_, rules &rules_, ostream &stream_) { char_state_machine csm_; sm_to_csm(sm_, csm_); dump(csm_, rules_, stream_); } static void dump(const sm &sm_, ostream &stream_) { char_state_machine csm_; sm_to_csm(sm_, csm_); dump(csm_, stream_); } static void dump(const char_state_machine &csm_, rules &rules_, ostream &stream_) { for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) { lexer_state(stream_); stream_ << rules_.state(dfa_) << std::endl << std::endl; dump_ex(csm_._sm_vector[dfa_], stream_); } } static void dump(const char_state_machine &csm_, ostream &stream_) { for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) { lexer_state(stream_); stream_ << dfa_ << std::endl << std::endl; dump_ex(csm_._sm_vector[dfa_], stream_); } } protected: using dfa_state = typename char_state_machine::state; using string_token = typename dfa_state::string_token; using stringstream = std::basic_stringstream; static void dump_ex(const typename char_state_machine::dfa &dfa_, ostream &stream_) { const std::size_t states_ = dfa_._states.size(); const id_type bol_index_ = dfa_._bol_index; for (std::size_t i_ = 0; i_ < states_; ++i_) { const dfa_state &state_ = dfa_._states[i_]; state(stream_); stream_ << i_ << std::endl; if (state_._end_state) { end_state(stream_); if (state_._push_pop_dfa == dfa_state::push_dfa) { push(stream_); stream_ << state_._push_dfa; } else if (state_._push_pop_dfa == dfa_state::pop_dfa) { pop(stream_); } id(stream_); stream_ << static_cast(state_._id); user_id(stream_); stream_ << static_cast(state_._user_id); dfa(stream_); stream_ << static_cast(state_._next_dfa); stream_ << std::endl; } if (i_ == 0 && bol_index_ != char_state_machine::npos()) { bol(stream_); stream_ << static_cast(bol_index_) << std::endl; } if (state_._eol_index != char_state_machine::npos()) { eol(stream_); stream_ << static_cast(state_._eol_index) << std::endl; } for (const auto &tran_ : state_._transitions) { string_token token_ = tran_.second; open_bracket(stream_); if (!tran_.second.any() && tran_.second.negatable()) { token_.negate(); negated(stream_); } string chars_; for (const auto &range_ : token_._ranges) { if (range_.first == '-' || range_.first == '^' || range_.first == ']') { stream_ << '\\'; } chars_ = string_token::escape_char (range_.first); if (range_.first != range_.second) { if (range_.first + 1 < range_.second) { chars_ += '-'; } if (range_.second == '-' || range_.second == '^' || range_.second == ']') { stream_ << '\\'; } chars_ += string_token::escape_char(range_.second); } stream_ << chars_; } close_bracket(stream_); stream_ << static_cast(tran_.first) << std::endl; } 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"; } static void end_state(std::wostream &stream_) { stream_ << L" END STATE"; } static void id(std::ostream &stream_) { stream_ << ", Id = "; } static void id(std::wostream &stream_) { stream_ << L", Id = "; } static void push(std::ostream &stream_) { stream_ << ", PUSH "; } static void push(std::wostream &stream_) { stream_ << L", PUSH "; } static void pop(std::ostream &stream_) { stream_ << ", POP"; } static void pop(std::wostream &stream_) { stream_ << L", POP"; } static void user_id(std::ostream &stream_) { stream_ << ", User Id = "; } static void user_id(std::wostream &stream_) { stream_ << L", User Id = "; } 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 = "; } }; using debug = basic_debug; using wdebug = basic_debug; } #endif