diff --git a/include/xo/reader2/ParserStack.hpp b/include/xo/reader2/ParserStack.hpp index b63be044..936c57e5 100644 --- a/include/xo/reader2/ParserStack.hpp +++ b/include/xo/reader2/ParserStack.hpp @@ -8,6 +8,7 @@ #include "SyntaxStateMachine.hpp" #include #include +#include namespace xo { namespace scm { @@ -21,6 +22,7 @@ namespace xo { class ParserStack { public: using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; public: ParserStack(DArena::Checkpoint ckp, @@ -42,6 +44,11 @@ namespace xo { obj top() const noexcept { return ssm_; } ParserStack * parent() const noexcept { return parent_; } + /** regular printing **/ + void print(std::ostream & os) const; + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + private: /** stack pointer: top of stack just before this instance created **/ DArena::Checkpoint ckp_; @@ -51,7 +58,32 @@ namespace xo { ParserStack * parent_ = nullptr; }; + inline std::ostream & operator<< (std::ostream & os, const ParserStack * x) { + if (x) { + x->print(os); + } else { + os << "nullptr"; + } + return os; + } + } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle ParserResult instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::ParserStack * p) { + if (p) + return p->pretty(ppii); + else + return ppii.pps()->print_upto("nullptr"); + } + }; + } + } /*namespace xo*/ /* end ParserStack.hpp */ diff --git a/include/xo/reader2/ParserStateMachine.hpp b/include/xo/reader2/ParserStateMachine.hpp index b333dd51..fbef2393 100644 --- a/include/xo/reader2/ParserStateMachine.hpp +++ b/include/xo/reader2/ParserStateMachine.hpp @@ -19,7 +19,8 @@ namespace xo { // class ASyntaxStateMachine; - // note: load-bearing to forward-declare ParserStack, + // note: it's load-bearing here to forward-declare ParserStack, + // see ParserStack.hpp for impl // because ASyntaxStateMachine.hpp includes ParserStateMachine.hpp; // before obj is defined. class ParserStack; diff --git a/include/xo/reader2/SchematikaParser.hpp b/include/xo/reader2/SchematikaParser.hpp index 81115239..300980fb 100644 --- a/include/xo/reader2/SchematikaParser.hpp +++ b/include/xo/reader2/SchematikaParser.hpp @@ -153,9 +153,10 @@ namespace xo { **/ class SchematikaParser { public: + using token_type = Token; using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; - using token_type = Token; + using ppindentinfo = xo::print::ppindentinfo; public: /** create parser in initial state; @@ -216,6 +217,8 @@ namespace xo { /** print human-readable representation on stream @p os **/ void print(std::ostream & os) const; + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; private: /** state machine **/ @@ -227,12 +230,31 @@ namespace xo { inline std::ostream & operator<< (std::ostream & os, - const SchematikaParser & x) { - x.print(os); + const SchematikaParser * x) { + if (x) { + x->print(os); + } else { + os << "nullptr"; + } return os; } } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle ParserResult instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::SchematikaParser* p) { + if (p) + return p->pretty(ppii); + else + return ppii.pps()->print_upto("nullptr"); + } + }; + } } /*namespace xo*/ /* end SchematikaParser.hpp */ diff --git a/src/reader2/DDefineSsm.cpp b/src/reader2/DDefineSsm.cpp index 3ae20286..c1e3f6a9 100644 --- a/src/reader2/DDefineSsm.cpp +++ b/src/reader2/DDefineSsm.cpp @@ -6,6 +6,9 @@ #include "DDefineSsm.hpp" #include "DExpectSymbolSsm.hpp" #include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" +#include "ssm/IPrintable_DDefineSsm.hpp" +#include +#include #ifdef NOT_YET #include "parserstatemachine.hpp" @@ -16,6 +19,7 @@ #endif namespace xo { + using xo::print::APrintable; using xo::facet::with_facet; using xo::facet::typeseq; @@ -497,10 +501,13 @@ namespace xo { bool DDefineSsm::pretty(const ppindentinfo & ppii) const { + auto expr = with_facet::mkobj(def_expr_.data()); + return ppii.pps()->pretty_struct (ppii, "DDefineSsm", - refrtag("defstate", defstate_)); + refrtag("defstate", defstate_), + refrtag("def_expr", expr)); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader2/ParserStack.cpp b/src/reader2/ParserStack.cpp index ba39517d..91d8bca9 100644 --- a/src/reader2/ParserStack.cpp +++ b/src/reader2/ParserStack.cpp @@ -5,8 +5,12 @@ #include "ParserStack.hpp" #include "SyntaxStateMachine.hpp" +#include +#include namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::facet::typeseq; namespace scm { @@ -41,6 +45,48 @@ namespace xo { return stack->parent(); } + void + ParserStack::print(std::ostream & os) const + { + os << ""; + os << xtag("ssm", "*placeholder*"); + os << xtag("parent", "*placeholder*"); + os << ">"; + } + + bool + ParserStack::pretty(const ppindentinfo & ppii) const + { + auto * pps = ppii.pps(); + + /* always use multiple lines */ + + if (ppii.upto()) + return false; + + pps->write(" (frame->top()); + + pps->newline_pretty_tag(ppii.ci1(), buf, ssm); + + ++i_frame; + frame = frame->parent_; + } + + pps->write(">"); + + return false; + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader2/SchematikaParser.cpp b/src/reader2/SchematikaParser.cpp index ac2d4520..d243de51 100644 --- a/src/reader2/SchematikaParser.cpp +++ b/src/reader2/SchematikaParser.cpp @@ -86,6 +86,28 @@ namespace xo { << xtag("has_stack", (psm_.stack() != nullptr)) << ">" << std::endl; } + + bool + SchematikaParser::pretty(const ppindentinfo & ppii) const { + auto * pps = ppii.pps(); + + if (ppii.upto()) + return false; + + // TODO: consider printing: + // psm.stringtable_ + // psm.parser_alloc_ + // psm.parser_alloc_ckp_ + // psm.expr_alloc_ + // psm.result_ + // psm.debug_flag_ + // + + return pps->pretty_struct + (ppii, + "SchematikaParser", + refrtag("stack", psm_.stack())); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/utest/SchematikaParser.test.cpp b/utest/SchematikaParser.test.cpp index e2a9023e..8cccfd7b 100644 --- a/utest/SchematikaParser.test.cpp +++ b/utest/SchematikaParser.test.cpp @@ -4,6 +4,7 @@ **/ #include +#include #include #include @@ -17,6 +18,8 @@ namespace xo { using xo::mm::DArena; using xo::facet::with_facet; + static InitEvidence s_init = (InitSubsys::require()); + namespace ut { TEST_CASE("SchematikaParser-ctor", "[reader2][SchematikaParser]") { @@ -92,6 +95,10 @@ namespace xo { // but is still "at toplevel" in the sense of ready for input REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(result.is_incomplete()); + + log && log("after def token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); } { @@ -100,6 +107,8 @@ namespace xo { REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(result.is_incomplete()); + log && log("after lhs symbol token:"); + log && log(xtag("parser", &parser)); log && log(xtag("result", result)); }