diff --git a/src/lib/parse.hpp b/src/lib/parse.hpp index b77aaa781..a462512c8 100644 --- a/src/lib/parse.hpp +++ b/src/lib/parse.hpp @@ -168,23 +168,21 @@ namespace util { -// namespace { -// /** handle all regular "function-like" entities */ -// template -// struct FunDetector -// { -// using Sig = typename _Fun::Sig; -// }; -// -// /** handle a generic lambda, accepting a reference to the `SRC` iterator */ -// template -// struct FunDetector> > -// { -// using Arg = std::add_lvalue_reference_t; -// using Ret = decltype(std::declval() (std::declval())); -// using Sig = Ret(Arg); -// }; -// } + namespace { + /** helper to detect return type of a possibly generic λ */ + template + struct _ProbeFunReturn + { + static_assert (!sizeof(ARG), + "Model binding must accept preceding model result."); + }; + + template + struct _ProbeFunReturn() (std::declval()))>> + { // probe the λ with ARG to force template instantiation + using Ret = decltype(std::declval() (std::declval())); + }; + } /** * Adapt by applying a result-transforming function after a successful parse. @@ -197,12 +195,8 @@ namespace util { adaptConnex (CON&& connex, BIND&& modelBinding) { using RX = typename CON::Result; -// using Arg = lib::meta::_FunArg; -// static_assert (std::is_constructible_v, -// "Model binding must accept preceding model result."); -// using AdaptedRes = typename _Fun::Ret; - using Arg = std::add_lvalue_reference_t; - using AdaptedRes = decltype(modelBinding (std::declval() )); + using Arg = std::add_rvalue_reference_t; + using AdaptedRes = typename _ProbeFunReturn::Ret; return Connex{[origConnex = forward(connex) ,binding = forward(modelBinding) ] @@ -217,6 +211,7 @@ namespace util { } + /* ===== building structured models ===== */ /** diff --git a/tests/library/parse-test.cpp b/tests/library/parse-test.cpp index 4202ade69..e0a27fb3e 100644 --- a/tests/library/parse-test.cpp +++ b/tests/library/parse-test.cpp @@ -573,7 +573,6 @@ namespace test { auto syntax1 = accept(word).seq(word) .bind([](Mod1 res) { -// auto& [a,b] = res; return res.get<0>().str() +"-"+ res.get<1>().str(); }); @@ -582,10 +581,22 @@ namespace test { syntax1.parse(s1); CHECK (syntax1.success()); auto res1 = syntax1.getResult(); -SHOW_TYPE(decltype(res1)) - CHECK (showType() == "string"); -SHOW_EXPR(res1) - CHECK (res == "ham-actor"_expect); + CHECK (showType() == "string"); // surprise! it is a simple string (as returned from λ) + CHECK (res1 == "ham-actor"_expect); + + // 💡 shortcut for RegExp match groups... + auto syntax1b = accept("(\\w+) (\\w+)"); + CHECK (accept(syntax1b).bindMatch( ).parse(s1).getResult() == "ham actor"_expect ); + CHECK (accept(syntax1b).bindMatch(1).parse(s1).getResult() == "ham"_expect ); + CHECK (accept(syntax1b).bindMatch(2).parse(s1).getResult() == "actor"_expect ); + CHECK (accept(syntax1b).bindMatch(3).parse(s1).getResult() == ""_expect ); + + 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()) } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 4d7f91f35..b175684ac 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -57066,7 +57066,7 @@ - + @@ -57078,27 +57078,32 @@ - + + - + - - + + - + - - - + + + + + + + - + @@ -57110,7 +57115,7 @@ - + @@ -57124,6 +57129,10 @@ + + + +