From b024b0baa6d319160dba4f658bd303a6348f1210 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 25 Jan 2025 17:00:51 +0100 Subject: [PATCH] Library: generic model transformer to get accepted string The `bindMatch()` as implemented yesterday works only directly on top of the terminal parsers, which yield a `RegExp`-Matcher. However, it would be desirable to provide a generic shortcut to always get some string as result model. A simple fallback is to return the part of the input-string accepted thus far. --- src/lib/parse.hpp | 47 +++++++++++++++++-- tests/library/parse-test.cpp | 28 +++++++----- wiki/thinkPad.ichthyo.mm | 88 +++++++++++++++++++++++++++++++++++- 3 files changed, 146 insertions(+), 17 deletions(-) diff --git a/src/lib/parse.hpp b/src/lib/parse.hpp index a462512c8..f8e23a3d2 100644 --- a/src/lib/parse.hpp +++ b/src/lib/parse.hpp @@ -41,6 +41,7 @@ #include "lib/meta/function.hpp" #include "lib/meta/trait.hpp" #include "lib/regex.hpp" +#include "lib/test/diagnostic-output.hpp"/////////TODO #include #include @@ -204,12 +205,50 @@ namespace util { { auto eval = origConnex.parse (toParse); if (eval.result) - return {binding (move (*eval.result))}; + return {binding (move (*eval.result)) + ,eval.consumed}; else return {std::nullopt}; }}; } + template + auto + toStringConnex (CON&& connex, uint part) + { + using Result = typename CON::Result; + using Arg = std::add_rvalue_reference_t; + return Connex([baseConnex = forward(connex) + ,part + ] + (StrView toParse) -> Eval + { + if constexpr (lib::meta::is_basically()) + { + Eval eval = baseConnex.parse (toParse); + if (eval.result) + return {eval.result->str(part) + ,eval.consumed + }; + else + return {std::nullopt}; + } + else + { + auto eval = baseConnex.parse (toParse); + if (eval.result) + { + size_t pre = leadingWhitespace (toParse); + return {string{toParse.substr (pre, eval.consumed)} + ,eval.consumed + }; + } + else + return {std::nullopt}; + } + }); + } + /* ===== building structured models ===== */ @@ -1008,10 +1047,8 @@ namespace util { auto Syntax::bindMatch (uint group) { - return bind ([group](smatch const& mat) - { - return mat.str(group); - }); + return accept( + toStringConnex (move(parse_), group)); } }// namespace parse diff --git a/tests/library/parse-test.cpp b/tests/library/parse-test.cpp index e0a27fb3e..3ef21ec11 100644 --- a/tests/library/parse-test.cpp +++ b/tests/library/parse-test.cpp @@ -569,19 +569,18 @@ namespace test { verify_modelBinding() { auto word{"\\w+"}; - using Mod1 = SeqModel; - auto syntax1 = accept(word).seq(word) - .bind([](Mod1 res) - { - return res.get<0>().str() +"-"+ res.get<1>().str(); - }); + auto syntax1 = accept(word).seq(word) // get a tuple with two RegExp-Matchers + .bind([](SeqModel res) + { + return res.get<0>().str() +"-"+ res.get<1>().str(); + }); string s1{"ham actor"}; CHECK (not syntax1.hasResult()); syntax1.parse(s1); CHECK (syntax1.success()); auto res1 = syntax1.getResult(); - CHECK (showType() == "string"); // surprise! it is a simple string (as returned from λ) + CHECK (showType() == "string"); // surprise! it's a simple string (as returned from λ) CHECK (res1 == "ham-actor"_expect); // 💡 shortcut for RegExp match groups... @@ -593,10 +592,17 @@ namespace test { auto wordEx = accept(word).bindMatch(); auto syntax1c = accept(wordEx) - .seq(wordEx) - .bind([](SeqModel m) - { return m.get<0>() +"-"+ m.get<1>(); }); -SHOW_EXPR(syntax1c.parse(s1).getResult()) + .seq(wordEx) // sub-expressions did already transform to string + .bind([](SeqModel res) + { return res.get<0>() +"-"+ res.get<1>(); }); + + CHECK (syntax1c.parse("ham actor").getResult() == "ham-actor"); + CHECK (syntax1c.parse("con artist").getResult() == "con-artist"); + + auto syntax1d =accept(word).seq(word) + .bindMatch(); // generic shortcut: ignore model, yield accepted part of input + CHECK (syntax1d.parse("ham actor").getResult() == "ham actor"); + CHECK (syntax1d.parse(" ham actor").getResult() == "ham actor"); } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index b175684ac..c7ac9b63a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -57116,6 +57116,67 @@ + + + + + + + + + +

+ ...denn es steuert die Art der Dekoration +

+ + +
+ + + + + + + +
+ + + + + + + + + + + + +

+ analog wie die anderen Combinatoren und buildConnex() +

+ + +
+
+ + + + + + + + + + + + +
+
+ + + + + @@ -57128,10 +57189,35 @@ + - + + + + + + + +

+ ganz banal: habe eval.consumed nicht weitergegeben +

+ + +
+ + + + + +

+ d.h. jede sub-expression setzt wieder am Anfang auf +

+ + +
+