xo-reader2: + pretty-printing for ParserResult + use in utest
This commit is contained in:
parent
d39dab185a
commit
ca2be0172a
6 changed files with 147 additions and 3 deletions
|
|
@ -115,7 +115,7 @@ namespace xo {
|
|||
* obj<AFoo> foo
|
||||
* = ...; // Foo instance with variant impl
|
||||
* obj<ABar> bar
|
||||
* = FacetRegistry::variant<ABar,AFoo>(foo);
|
||||
* = FacetRegistry::instance().variant<ABar,AFoo>(foo);
|
||||
*
|
||||
* // exception thrown if bar has null data
|
||||
*
|
||||
|
|
@ -140,7 +140,7 @@ namespace xo {
|
|||
* obj<AFoo> foo
|
||||
* = ...; // Foo instance with variant impl
|
||||
* obj<ABar> bar
|
||||
* = FacetRegistry::try_variant<ABar,AFoo>(foo);
|
||||
* = FacetRegistry::instance().try_variant<ABar,AFoo>(foo);
|
||||
* if (bar) {
|
||||
* // success
|
||||
* } else {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,21 @@ namespace xo {
|
|||
* Need one read-only instance of this to invoke pretty printer
|
||||
**/
|
||||
struct ppconfig {
|
||||
/** @defgroup ppconfig-ctors ppconfig constructors **/
|
||||
///@{
|
||||
|
||||
/** config to use pretty printer in degenerate form:
|
||||
* In this form right margin is absurdly far away,
|
||||
* so should not be forced to use multiple lines.
|
||||
*
|
||||
* Note this won't prevent a printer from returning -1
|
||||
**/
|
||||
static inline ppconfig ugly() {
|
||||
return ppconfig { .right_margin_ = 99999999, .indent_width_ = 0, .assert_indent_threshold = 10 };
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
/** @defgroup ppconfig-instance-vars ppconfig instance variables **/
|
||||
///@{
|
||||
|
||||
|
|
|
|||
|
|
@ -279,6 +279,15 @@ namespace xo {
|
|||
///@}
|
||||
};
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & os, const DString * x) {
|
||||
if (x) {
|
||||
os << std::string_view(*x);
|
||||
} else {
|
||||
os << "nullptr";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
inline bool operator==(const DString & lhs, const DString & rhs) {
|
||||
return DString::compare(lhs, rhs) == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue