xo-reader2: + pretty-printing for ParserResult + use in utest

This commit is contained in:
Roland Conybeare 2026-01-20 12:40:26 -05:00
commit 3bdbb61eba
3 changed files with 121 additions and 1 deletions

View file

@ -7,6 +7,7 @@
#include <xo/expression2/Expression.hpp>
#include <xo/object2/DString.hpp>
#include <xo/indentlog/print/pretty.hpp>
#include <string_view>
namespace xo {
@ -21,7 +22,18 @@ namespace xo {
N
};
/** @return string representation for enum @p x **/
const char * parser_result_type_descr(parser_result_type x);
inline std::ostream & operator<<(std::ostream & os, parser_result_type x) {
os << parser_result_type_descr(x);
return os;
}
class ParserResult {
public:
using ppindentinfo = xo::print::ppindentinfo;
public:
ParserResult() = default;
ParserResult(parser_result_type type,
@ -44,15 +56,53 @@ namespace xo {
bool is_expression() const { return result_type_ == parser_result_type::expression; }
bool is_error() const { return result_type_ == parser_result_type::error; }
/** ordinary not-pretty printer **/
void print(std::ostream & os) const;
/** pretty-printing support **/
bool pretty(const ppindentinfo & ppii) const;
private:
/** none|expression|error_description
*
* @text
* result_type | error_src_function | error_description
* -------------+--------------------+-------------------
* none | nullptr | empty
* expression | nullptr | empty
* error | non-null | non-empty
* @endtext
**/
parser_result_type result_type_ = parser_result_type::none;
/** non-null iff @ref result_type_ is expression **/
obj<AExpression> result_expr_;
/** non-null iff @ref result_type_ is error.
* In which case gives parsing function detecting this error
**/
std::string_view error_src_fn_;
/** non-null iff @ref result_type_ is error
* Human-targeted error description.
**/
const DString * error_description_ = nullptr;
};
inline std::ostream & operator<<(std::ostream & os, const ParserResult & x) {
x.print(os);
return os;
}
} /*namespace scm*/
namespace print {
/** pretty printer in <xo/indentlog/print/pretty.hpp> relies on this specialization
* to handle ParserResult instances
**/
template <>
struct ppdetail<xo::scm::ParserResult> {
static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::ParserResult & x) {
return x.pretty(ppii);
}
};
}
} /*namespace xo*/
/* end ParserResult.hpp */

View file

@ -4,9 +4,28 @@
**/
#include "ParserResult.hpp"
#include <xo/printable2/Printable.hpp>
#include <xo/facet/FacetRegistry.hpp>
namespace xo {
using xo::print::APrintable;
using xo::facet::FacetRegistry;
namespace scm {
const char *
parser_result_type_descr(parser_result_type x)
{
switch (x) {
case parser_result_type::none: return "none";
case parser_result_type::expression: return "expression";
case parser_result_type::error: return "error";
case parser_result_type::N: break;
}
return "parser_result_type?";
}
ParserResult::ParserResult(parser_result_type type,
obj<AExpression> expr,
std::string_view error_src_fn,
@ -26,6 +45,53 @@ namespace xo {
ssm_name,
errmsg);
}
void
ParserResult::print(std::ostream & os) const
{
os << "<ParserResult" ;
os << xtag("type", result_type_);
os << xtag("expr", result_expr_);
os << xtag("src_fn", error_src_fn_);
if (error_description_)
os << xtag("error", error_description_);
os << ">";
}
bool
ParserResult::pretty(const ppindentinfo & ppii) const
{
switch (result_type_) {
case parser_result_type::none:
return ppii.pps()->pretty_struct
(ppii,
"ParserResult",
refrtag("type", result_type_));
case parser_result_type::expression:
{
auto expr = FacetRegistry::instance().variant<APrintable,AExpression>(result_expr_);
return ppii.pps()->pretty_struct
(ppii,
"ParserResult",
refrtag("type", result_type_),
refrtag("expr", expr));
}
break;
case parser_result_type::error:
return ppii.pps()->pretty_struct
(ppii,
"ParserResult",
refrtag("type", result_type_),
refrtag("src_fn", error_src_fn_),
refrtag("error", error_description_));
case parser_result_type::N:
assert(false);
break;
}
return false;
}
} /*namespace scm*/
} /*namespace xo*/

View file

@ -71,6 +71,9 @@ namespace xo {
TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]")
{
constexpr bool c_debug_flag = true;
scope log(XO_DEBUG(c_debug_flag));
ArenaConfig config;
config.name_ = "test-arena";
config.size_ = 16 * 1024;
@ -96,11 +99,12 @@ namespace xo {
REQUIRE(parser.has_incomplete_expr() == true);
REQUIRE(result.is_incomplete());
log && log(xtag("result", result));
}
// define-expressions not properly implemented
//REQUIRE(result.error_description());
}