Library: investigate how to approach recursion

Allowing free recursion in grammars is the key enabling feature,
which allows to accept arbitrary complex structures (like numeric expressions).
It is however also the element which makes the task of parsing a challenging endeavour;
after weighting the arguments, I decided ''not to place the focus on advanced usage,''
yet to open a pathway towards representation of such grammars.

Essentially, I consider it acceptable to require some additional work by the user,
if arbitrary recursive grammars are desired; because this design relies on explicitly
given parse functions, we need to introduce some kind of indirection interface,
to allow ''declaring'' a recursive rule first and later to ''supply the definition,''
which obviously then will involve other rules (or itself) recursively.

This leads to a very ''nifty approach'' towards recursion: we require the user
to provide an ''explicit model type'' beforehand, which implies that this is a
simple type, that can be spelled out (no λ) — and so the user is also
''forced to augment the actual rule with a model-binding,'' thereby reducing
the structured return types from the parse into something simple and uniform.
The user ''has to do the hard work,'' but can ''exploit additional knowledge''
related to the specific use case.

All this framework needs to do then is to supply a `std::function`, using the
explicit return type given; everything else will still work as implemented,
since a `std::function` can always stand-in for any arbitrary λ.
This commit is contained in:
Fischlurch 2025-01-25 02:48:11 +01:00
parent 41ded40a3a
commit 860e2fa226
3 changed files with 533 additions and 11 deletions

View file

@ -20,6 +20,13 @@
** easier to understand and maintain. With some helper abbreviations, notably
** a combinator scheme to work from building blocks, a hand-written solution
** can benefit from taking short-cuts, especially related to result bindings.
**
** So what is provided here is _not a parser library_ yet aims at »making
** simple things simple« and let you implement the complicated ones yourselves.
** Several decisions were taken accordingly, like only supporting std::string_view
** and automatically consuming any leading whitespace. And notably the focus was
** _not placed_ on the challenging aspects of parsing while still allowing a
** pathway towards definition of arbitrarily recursive grammars, if so desired.
*/
@ -160,6 +167,25 @@ namespace util {
}
// namespace {
// /** handle all regular "function-like" entities */
// template<typename SRC, typename F, typename SEL =void>
// struct FunDetector
// {
// using Sig = typename _Fun<F>::Sig;
// };
//
// /** handle a generic lambda, accepting a reference to the `SRC` iterator */
// template<typename SRC, typename F>
// struct FunDetector<SRC, F, lib::meta::disable_if<_Fun<F>> >
// {
// using Arg = std::add_lvalue_reference_t<SRC>;
// using Ret = decltype(std::declval<F>() (std::declval<Arg>()));
// using Sig = Ret(Arg);
// };
// }
/**
* Adapt by applying a result-transforming function after a successful parse.
* @remark the purpose is to extract a custom data model immediately from the
@ -171,10 +197,12 @@ namespace util {
adaptConnex (CON&& connex, BIND&& modelBinding)
{
using RX = typename CON::Result;
using Arg = lib::meta::_FunArg<BIND>;
static_assert (std::is_constructible_v<Arg,RX>,
"Model binding must accept preceding model result.");
using AdaptedRes = typename _Fun<BIND>::Ret;
// using Arg = lib::meta::_FunArg<BIND>;
// static_assert (std::is_constructible_v<Arg,RX>,
// "Model binding must accept preceding model result.");
// using AdaptedRes = typename _Fun<BIND>::Ret;
using Arg = std::add_lvalue_reference_t<RX>;
using AdaptedRes = decltype(modelBinding (std::declval<Arg>() ));
return Connex{[origConnex = forward<CON>(connex)
,binding = forward<BIND>(modelBinding)
]
@ -663,6 +691,11 @@ namespace util {
template<typename SPEC>
auto bracketOpt (SPEC&& bodyDef);
template<class FUN>
auto bind (FUN&& modelAdapt);
auto bindMatch (uint group =0);
private:
Eval<Result>& eval() { return *this;}
};
@ -966,6 +999,26 @@ namespace util {
return seq (accept_bracketOpt (forward<SPEC>(bodyDef)));
}
template<class PAR>
template<class FUN>
auto
Syntax<PAR>::bind (FUN&& modelAdapt)
{
return accept(
adaptConnex (move(parse_)
,forward<FUN>(modelAdapt)));
}
template<class PAR>
auto
Syntax<PAR>::bindMatch (uint group)
{
return bind ([group](smatch const& mat)
{
return mat.str(group);
});
}
}// namespace parse

View file

@ -76,19 +76,21 @@ namespace test {
virtual void
run (Arg)
{
simpleBlah();
simpleUsage();
acceptTerminal();
acceptSequential();
acceptAlternatives();
acceptIterWithDelim();
acceptOptionally();
acceptBracketed();
verify_modelBinding();
}
/** @test TODO just blah. */
void
simpleBlah ()
simpleUsage ()
{
}
@ -559,6 +561,32 @@ namespace test {
CHECK (not accept_bracket("a","n","...").parse(" gain")); // opening expression "a" missing
CHECK (not accept_bracket("a","n", word).parse("again")); // "\\w+" consumes eagerly => closing expression not found
}
/** @test define syntax with bracketed sub-expressions */
void
verify_modelBinding()
{
auto word{"\\w+"};
using Mod1 = SeqModel<smatch,smatch>;
auto syntax1 = accept(word).seq(word)
.bind([](Mod1 res)
{
// auto& [a,b] = 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();
SHOW_TYPE(decltype(res1))
CHECK (showType<decltype(res1)>() == "string");
SHOW_EXPR(res1)
CHECK (res == "ham-actor"_expect);
}
};
LAUNCHER (Parse_test, "unit common");

View file

@ -56995,8 +56995,7 @@
....mu&#223; dann aber durch die Entscheidungs-Logik sicherstellen, da&#223; dann auch die zugeh&#246;rige schlie&#223;ende Klammer entweder erwartet, oder &#252;bersprungen wird.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node COLOR="#437c98" CREATED="1737686235979" ID="ID_85956191" MODIFIED="1737686271881" TEXT="(insofern ist die Sequenziertung explizit ausprogrammiert)">
<font NAME="SansSerif" SIZE="11"/>
@ -57013,12 +57012,121 @@
<node CREATED="1737692736393" ID="ID_1456187904" MODIFIED="1737692753851" TEXT="biete die optionalen Klammern nur f&#xfc;r einfache Specs"/>
<node CREATED="1737692936766" ID="ID_1532611498" MODIFIED="1737692952152" TEXT="aber mit explizitem &quot;Opt&quot; im Namen"/>
</node>
<node COLOR="#338800" CREATED="1737509793049" ID="ID_890596853" MODIFIED="1737693103778" TEXT="funktioniert im Test">
<node COLOR="#338800" CREATED="1737509793049" ID="ID_890596853" MODIFIED="1737763432229" TEXT="funktioniert im Test">
<arrowlink COLOR="#69a19e" DESTINATION="ID_1463442375" ENDARROW="Default" ENDINCLINATION="365;-30;" ID="Arrow_ID_522261019" STARTARROW="None" STARTINCLINATION="-269;35;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1737515362910" ID="ID_1587990202" MODIFIED="1737515384135" TEXT="offene Rekursion?">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737762868854" ID="ID_311219420" MODIFIED="1737762954045" TEXT="Result-Bindings">
<linktarget COLOR="#fadad2" DESTINATION="ID_311219420" ENDARROW="Default" ENDINCLINATION="-362;51;" ID="Arrow_ID_1251442496" SOURCE="ID_1290815698" STARTARROW="None" STARTINCLINATION="-954;49;"/>
<icon BUILTIN="pencil"/>
<node CREATED="1737762977024" ID="ID_1561603785" MODIFIED="1737762981006" TEXT="Basis-Implementierung">
<node CREATED="1737762981897" ID="ID_1090727371" MODIFIED="1737763001027" TEXT="ist schon da">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
nebenbei abgefallen
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
<node CREATED="1737763004632" ID="ID_822193320" MODIFIED="1737763015437" TEXT="ist nur ein Dekorator der Parse-Funktion"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737763021537" ID="ID_1389624027" MODIFIED="1737768628999" TEXT="DSL-Einbindung">
<icon BUILTIN="pencil"/>
<node CREATED="1737763027300" ID="ID_681702080" MODIFIED="1737763052404">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<i>das</i>&#160;mu&#223; tats&#228;chlich ein <b>Postfix-Operator</b>&#160;sein
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="yes"/>
</node>
<node CREATED="1737763069414" ID="ID_1049523751" MODIFIED="1737763109434">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Vorschlag: <font face="Monospaced"><b>bind</b>(</font><font face="Monospaced" color="#642929">FUN</font><font face="Monospaced">)</font>
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737763165990" ID="ID_1051966220" MODIFIED="1737763211832" TEXT="wichtig: static-assertion bieten">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
damit klar gesagt wird, wenn die Funktion nicht den bisherigen Result-Typ nimmt
</p>
</body>
</html>
</richcontent>
<node CREATED="1737766232691" ID="ID_1413683857" MODIFIED="1737766240549" TEXT="Ha! die ist schon da">
<icon BUILTIN="ksmiletris"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1737766241770" ID="ID_1746968965" MODIFIED="1737766267762" TEXT="nicht so einfach ... &#x3bb;-generic ist keine Funktion">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1737768448186" ID="ID_446285333" MODIFIED="1737768487565" TEXT="die probe-Technik anwenden (&#x27f5; iterExplorer)">
<icon BUILTIN="help"/>
</node>
<node COLOR="#5b280f" CREATED="1737768488844" ID="ID_95454385" MODIFIED="1737768511897" TEXT="damit kann man aber keine static-assertion-failure provozieren">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1737768513367" ID="ID_262683040" MODIFIED="1737768519412" TEXT="ja dann....">
<node CREATED="1737768521376" ID="ID_1251164571" MODIFIED="1737768535589" TEXT="entweder gar keine &#x3bb;-generic unterst&#xfc;tzen"/>
<node CREATED="1737768536342" ID="ID_1137963941" MODIFIED="1737768552975" TEXT="oder gleich immer das Probing auf alle anwenden"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1737768555555" ID="ID_3235456" MODIFIED="1737768583613" TEXT="oder ein Probing-Tempalte schreiben">
<icon BUILTIN="forward"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737763306315" ID="ID_556563323" MODIFIED="1737763342424">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Standard-Variante: <font face="Monospaced"><b>bindMatch</b>(n)</font>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737509793049" ID="ID_1532451583" MODIFIED="1737763426814" TEXT="komplexere F&#xe4;lle testen">
<arrowlink COLOR="#69a19e" DESTINATION="ID_1875116599" ENDARROW="Default" ENDINCLINATION="365;-30;" ID="Arrow_ID_1373514851" STARTARROW="None" STARTINCLINATION="-268;27;"/>
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1737768590998" ID="ID_1409763179" MODIFIED="1737768617430" TEXT="einfache F&#xe4;lle funktionieren mal grunds&#xe4;tzlich wie erwartet">
<icon BUILTIN="ksmiletris"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1737768366091" ID="ID_1745696338" MODIFIED="1737768442619" TEXT="bind-Functions schreiben ist m&#xfc;hsam">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1737768409191" ID="ID_46123353" MODIFIED="1737768426237" TEXT="&#x3bb;-generic funktionieren nicht wie gew&#xfc;nscht"/>
<node CREATED="1737768426892" ID="ID_1722753025" MODIFIED="1737768440774" TEXT="und sonst mu&#xdf; man immer die Model-Namen ganz anschreiben"/>
</node>
</node>
</node>
<node CREATED="1737515362910" ID="ID_1587990202" MODIFIED="1737693815237" TEXT="offene Rekursion">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1737515599278" ID="ID_1897353084" MODIFIED="1737515606925" TEXT="schwierige Frage....">
<icon BUILTIN="help"/>
<node CREATED="1737515610957" ID="ID_1394504016" MODIFIED="1737515628606" TEXT="es ist nat&#xfc;rlich ein Kern-Feature von recursive-descent"/>
@ -57031,6 +57139,331 @@
<node CREATED="1737553446367" ID="ID_420976669" MODIFIED="1737553464114" TEXT="m&#xfc;&#xdf;te daf&#xfc;r Klauseln per Referenz nehmen k&#xf6;nnen"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737693819337" ID="ID_228574257" MODIFIED="1737761064544" TEXT="Implementierungs-Technik kl&#xe4;ren">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737693835207" ID="ID_1616305471" MODIFIED="1737694295281" TEXT="grunds&#xe4;tzlich realisierbar in diesem Framework">
<icon BUILTIN="pencil"/>
<node CREATED="1737693849853" ID="ID_1927056535" MODIFIED="1737693956231" TEXT="ABER wir m&#xfc;ssen dann die strikte Model-Typisierung abschneiden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
....weil eine rekursive Definition im Prinzip offen ist und im Extremfall auch tats&#228;chlich nicht terminiert; in Haskell k&#246;nnte man einen solchen Typ anschreiben, in C++ nicht (weil Typ-Ausdr&#252;cke eager aufgel&#246;st werden)
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737693890688" ID="ID_70642689" MODIFIED="1737694064532" TEXT="das Ergebnis ist trotzdem strikt typisiert">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...denn was wir abschneiden ist nur die komplett ausformulierte Struktur des Typs; an der Stelle, an der eine andere Klausel rekursiv eingebunden wird, greifen wir nur <i>deren Ergebnis-Model</i>&#160;auf.
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1737694065800" ID="ID_303092277" MODIFIED="1737761080042" TEXT="das stellt aber ein Lock-in dar">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1737694102427" ID="ID_878363951" MODIFIED="1737694137594" TEXT="was ohnehin schon durch die Definition einer Syntax&lt;PAR&gt;-Instanz erfolgt"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1737694138462" ID="ID_837740353" MODIFIED="1737694189304" TEXT="Vorsicht &#xd83e;&#xdc32; k&#xf6;nnen dann rekursive Systeme &#xfc;berhaupt formuliert werden?">
<icon BUILTIN="help"/>
<node CREATED="1737694494314" ID="ID_1349021262" MODIFIED="1737694529548" TEXT="konkrete Typen k&#xf6;nnen nur durch &#xbb;Beispiel&#xab; erzeugt werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
der Lambdas wegen
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737694541439" ID="ID_1004008024" MODIFIED="1737694566958">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
das hei&#223;t, es w&#252;rde eine Art <i>late-Binding</i>&#160;notwendig
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1737694569853" ID="ID_1483280295" MODIFIED="1737694574820" TEXT="und zwar auf Typ-Ebene">
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1737761108914" ID="ID_64242861" MODIFIED="1737761160846" TEXT="oder der Typ an der Schnitt-Stelle mu&#xdf; vereinfacht werden">
<arrowlink COLOR="#fdfcce" DESTINATION="ID_593591679" ENDARROW="Default" ENDINCLINATION="-98;-174;" ID="Arrow_ID_1260672332" STARTARROW="None" STARTINCLINATION="-525;26;"/>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1737738318817" ID="ID_1107737972" MODIFIED="1737751309871" TEXT="nochmal Vergleich mit existierenden Libraries">
<icon BUILTIN="list"/>
<node CREATED="1737738393985" ID="ID_1121877326" MODIFIED="1737751317964" TEXT="viele verstecken das Thema (wenn es &#xfc;berhaupt erw&#xe4;hnt wird)">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1737738410117" ID="ID_1562192349" MODIFIED="1737738436974" TEXT="Ansatz-1 : als Sonderfall mit Einschr&#xe4;nkungen">
<node CREATED="1737738439713" ID="ID_1378187419" MODIFIED="1737738453835" TEXT="es gibt dann einen spezielle Operator &quot;recurse&quot;"/>
<node CREATED="1737738454471" ID="ID_1938793742" MODIFIED="1737751342079" TEXT="und der kann dann x% der andern coolen Features der Library nicht nutzen"/>
<node CREATED="1737738477289" ID="ID_32969388" MODIFIED="1737738522859" TEXT="an der Stelle wird dynamisch (w&#xe4;hrend dem Parsen) aufgel&#xf6;st"/>
</node>
<node CREATED="1737738524980" ID="ID_674981283" MODIFIED="1737738537250" TEXT="Ansatz-2 : Grammatik-Tree">
<node CREATED="1737738538204" ID="ID_1620744459" MODIFIED="1737738550958" TEXT="die DSL baut eine Meta-Datenstruktur auf"/>
<node CREATED="1737738568902" ID="ID_708583532" MODIFIED="1737738582581" TEXT="die kann man dann in einem post-Processing &#xbb;binden&#xab;"/>
<node CREATED="1737738583534" ID="ID_421798511" MODIFIED="1737738612254" TEXT="bei diesem Ansatz stehen die Ankn&#xfc;pfungen (Model-Bindings) stets separat daneben"/>
<node CREATED="1737738633032" ID="ID_1454644762" MODIFIED="1737738645258" TEXT="wenn sie applikativ sind, werden sie erst zur Parse-Zeit aufgel&#xf6;st"/>
<node CREATED="1737738800921" ID="ID_564771468" MODIFIED="1737738820906" TEXT="oder es wird eine Kette von Parser-Actions generiert und erst zuletzt ausgef&#xfc;hrt"/>
</node>
<node CREATED="1737738657607" ID="ID_1955702188" MODIFIED="1737738665447" TEXT="Ansatz-3 : Baukasten-System">
<node CREATED="1737738666339" ID="ID_276019914" MODIFIED="1737738675374" TEXT="die Library ist sowiso nur ein Baukasten-System"/>
<node CREATED="1737738675982" ID="ID_1166347180" MODIFIED="1737738690102" TEXT="die DSL beschr&#xe4;nkt sich auf Rules and Productions"/>
<node CREATED="1737738694393" ID="ID_462842617" MODIFIED="1737738704898" TEXT="der User mu&#xdf; dann selber einen Parser zusammenbauen"/>
<node CREATED="1737738709109" ID="ID_1100948683" MODIFIED="1737738722431" TEXT="die Model-Verwaltung liegt beim User"/>
<node CREATED="1737738723505" ID="ID_1018761314" MODIFIED="1737738748516" TEXT="im klassischen &quot;Calculator&quot;-Beispiel wird dann ein Ergebnis-Stack verwendet"/>
</node>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1737756303660" ID="ID_593591679" MODIFIED="1737761152655" TEXT="Unvermeidbare Einschr&#xe4;nkung: User mu&#xdf; Result-Type explizit benennen">
<linktarget COLOR="#fdfcce" DESTINATION="ID_593591679" ENDARROW="Default" ENDINCLINATION="-98;-174;" ID="Arrow_ID_1260672332" SOURCE="ID_64242861" STARTARROW="None" STARTINCLINATION="-525;26;"/>
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
<node CREATED="1737756333584" ID="ID_473974893" MODIFIED="1737756354874" TEXT="damit k&#xf6;nnen wir eine std::function&lt;Ret(StrView)&gt; anlegen"/>
<node CREATED="1737756891099" ID="ID_1058310023" MODIFIED="1737756901161">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
und sp&#228;ter an diese <b>zuweisen</b>
</p>
</body>
</html>
</richcontent>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1737756949618" ID="ID_1994498294" MODIFIED="1737757016770">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
das impliziert <b>Heap-Storage</b>&#160;f&#252;r das Parse-&#955;
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1737757056699" ID="ID_1321549013" MODIFIED="1737757108138" TEXT="und i.d.R. schlechte Optimierbarkeit">
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1737757082628" ID="ID_817205255" MODIFIED="1737757100962" TEXT="Result-Storage ist nicht betroffen">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#e8d8bb" CREATED="1737757274593" ID="ID_1290815698" MODIFIED="1737762963804" TEXT="User mu&#xdf; typischerweise ein Result-Binding definieren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...denn sonst d&#252;rfte es kaum m&#246;glich sein, einen explizit angebbaren Result-Typ zu konstituieren; in diesem Result-Binding steckt der <i>eigentliche Ansatz,</i>&#160;mit dem eine offen-rekursive Grammatik dennoch handhabbar wird, denn es mu&#223; eine Art Reduktion der Komplexit&#228;t erfolgen, beispielsweise indem sofort ein Ergebnis ausgerechnet wird
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#fadad2" DESTINATION="ID_311219420" ENDARROW="Default" ENDINCLINATION="-362;51;" ID="Arrow_ID_1251442496" STARTARROW="None" STARTINCLINATION="-954;49;"/>
<icon BUILTIN="forward"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1737762884132" HGAP="23" ID="ID_1097242773" MODIFIED="1737762918245" TEXT="&#x27f9; das mu&#xdf; das n&#xe4;chste Thema sein" VSHIFT="10">
<font NAME="SansSerif" SIZE="10"/>
</node>
</node>
</node>
</node>
<node COLOR="#5b280f" CREATED="1737694196062" ID="ID_625191879" MODIFIED="1737757490835" TEXT="Einstiegs-Punkt: wie die Sub-Syntax-&#xfc;bergeben wird">
<icon BUILTIN="idea"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1737694235744" ID="ID_1016606366" MODIFIED="1737694259530" TEXT="per Value / RValue &#x27f9; &#xfc;bernehmen und komplett einbinden"/>
<node CREATED="1737694260501" ID="ID_199476088" MODIFIED="1737694285502" TEXT="per LValue &#x27f9; nur Referenz nehmen und PImpl-Model vorsehen"/>
<node COLOR="#5b280f" CREATED="1737757492862" HGAP="22" ID="ID_888754137" MODIFIED="1737757528825" TEXT="NEIN das verfehlt den eigentlichen Punkt" VSHIFT="5">
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1737757530355" ID="ID_38602384" MODIFIED="1737757618234" TEXT="Einstiegs-Punkt: eine Syntax wird vordeklariert">
<icon BUILTIN="idea"/>
<node CREATED="1737757552386" ID="ID_193170390" MODIFIED="1737757558213" TEXT="expect&lt;RES&gt;()"/>
<node CREATED="1737757736924" ID="ID_845564019" MODIFIED="1737757760362" TEXT="Type-Tag &#x27f9; macht den Connex zuweisbar"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1737757814918" ID="ID_7084823" MODIFIED="1737757837403" TEXT="alles &#xdc;brige bleibt weiterhin &#xbb;locker&#xab;">
<icon BUILTIN="yes"/>
<node CREATED="1737757864319" ID="ID_1384035666" MODIFIED="1737757887112" TEXT="das hei&#xdf;t, au&#xdf;er dem Type-Tag sollte sich die Syntax komplett normal verhalten"/>
<node CREATED="1737757888884" ID="ID_1542863836" MODIFIED="1737757914004" TEXT="im Parse passiert eine Indirektion (normalerweise transparent)"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1737757927671" ID="ID_100422313" MODIFIED="1737758161080" TEXT="was machen nachfolgende Dekorationen?">
<icon BUILTIN="help"/>
<node CREATED="1737758174587" ID="ID_29086225" MODIFIED="1737758222499" TEXT="m&#xf6;gliche Varianten">
<node CREATED="1737758223415" ID="ID_1731735440" MODIFIED="1737758228534" TEXT="nichts speziell">
<icon BUILTIN="full-1"/>
<node CREATED="1737758231806" ID="ID_672212089" MODIFIED="1737758243134" TEXT="bedeutet: die std::function wird &#xbb;zugedeckt&#xab;"/>
<node CREATED="1737758244380" ID="ID_39267660" MODIFIED="1737758250903" TEXT="danach ist keine Zuweisung mehr m&#xf6;glich"/>
<node CREATED="1737758586785" ID="ID_333487301" MODIFIED="1737758596473" TEXT="es ist aber auch keine Spezialbehandlung notwendig"/>
</node>
<node CREATED="1737758372060" ID="ID_360134347" MODIFIED="1737758376669" TEXT="unterbinden">
<icon BUILTIN="full-2"/>
<node CREATED="1737758383978" ID="ID_70770798" MODIFIED="1737758456356" TEXT="da jede weitere Dekoration dem Sinn der Forward-Deklaration zuwiderl&#xe4;uft"/>
<node CREATED="1737758466942" ID="ID_397213831" MODIFIED="1737758745475">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Konsequenz &#10233; das <i>Einbinden</i>&#160;in andere Syntax ist speziell zu behandeln
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
....weil ja das Einbinden technisch nichts anderes ist, als eine Dekoration (und damit unterbunden w&#252;rde)
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737758560698" ID="ID_1679326652" MODIFIED="1737758575731" TEXT="man mu&#xdf; eine solche Syntax noch zuweisen und dann so verwenden wie sie ist"/>
<node CREATED="1737758982616" ID="ID_375516011" MODIFIED="1737759057960" TEXT="(oder aber in andere Syntax integrieren &#x2014; was stets m&#xf6;glich ist)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
diese andere Syntax h&#228;tte dann aber auch einen anderen Typ und m&#252;&#223;te in einer anderen Syntax-Variablen gespeichert werden;
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="11"/>
</node>
</node>
<node CREATED="1737758798442" ID="ID_1126967744" MODIFIED="1737758814914" TEXT="zuweisbar halten">
<icon BUILTIN="full-3"/>
<node CREATED="1737758818535" ID="ID_1171282084" MODIFIED="1737758835145" TEXT="die einmal markierte Funktion bleibt als Zuweisungspunkt zug&#xe4;nglich"/>
<node CREATED="1737758836035" ID="ID_1710211125" MODIFIED="1737758849830" TEXT="man kann beliebig dar&#xfc;ber dekorieren"/>
<node CREATED="1737758850635" ID="ID_1519359559" MODIFIED="1737758861486" TEXT="aber nur die markierte Funktion kann zugewiesen werden"/>
</node>
</node>
<node CREATED="1737758899676" ID="ID_661878055" MODIFIED="1737758902194" TEXT="Diskussion">
<node CREATED="1737758903192" ID="ID_447755008" MODIFIED="1737759845669" TEXT="Varianten-1 und 2 laufen auf die gleiche Verwendung hinaus"/>
<node CREATED="1737759828390" ID="ID_1549999802" MODIFIED="1737760031271">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Variante-1 ist &#187;filosofisch&#171; und praktsich attraktiv
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...weil sie der &#8222;dann mach's halt nicht falsch&#8220;-Haltung entspricht, die diesem ganzen Parser-Framework zugrunde gelegt wurde; und ganz praktisch: man bekommt diese Variante geschenkt, alles funktioniert von selber so wie es soll &#8212; und wenn irgendjemand unbedingt dekorieren m&#246;chte, dann soll er halt
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737760037922" ID="ID_188274481" MODIFIED="1737760311471" TEXT="Variante-3 w&#xfc;rde tats&#xe4;chlich erweiterte Logik erm&#xf6;glichen &#x2014; erscheint aber fragw&#xfc;rdig">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Weil das, was man nun zus&#228;tzlich machen k&#246;nnte, nur auf Basis der Implementierung verst&#228;ndlich ist, aber f&#252;r jeden Benutzer ziemlich verwirrend
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1737760312861" ID="ID_1430169629" MODIFIED="1737760337743" TEXT="Beschlu&#xdf;: Variante-1">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="yes"/>
<node CREATED="1737760340128" ID="ID_1904432675" MODIFIED="1737760536651" TEXT="Variante-2 w&#xe4;re w&#xfc;nschenswert">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
da sie ohnehin das erlaubt was man machen sollte, aber Fehl-Verwendungen unterbindet
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737760356767" ID="ID_523967840" MODIFIED="1737760483530" TEXT="ist aber in der Umsetzung unklar">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
da man ja dennoch irgendwie auf diese Funktion Bezug nehmen kann, indem man sie in andere Sytnax einbaut, ist die Abgrenzung zum <i>&#187;Dekorieren&#171;</i>&#160; nicht klar
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1737760484654" ID="ID_1431261175" MODIFIED="1737760552303" TEXT="besser ist, korrekte und klare Verwendung der Library zu fordern"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1737760572436" ID="ID_1761010902" MODIFIED="1737760625364" TEXT="diese Forward-Deklarationen m&#xfc;ssen dauerhaft bestehen bleiben">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1737760626950" ID="ID_1746781945" MODIFIED="1737760654483" TEXT="damit die sp&#xe4;tere Zuweisung klappt, m&#xfc;ssen Referenzen verwendet werden"/>
<node CREATED="1737760760265" ID="ID_1932015736" MODIFIED="1737760997909" TEXT="eine &#xbb;high-tech-L&#xf6;sung&#xab; w&#xe4;re denkbar &#x2014; erscheit aber zweifelhaft">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...sie best&#252;nde darin, die Referenzen nach der Zuweisung zu <i>materialisieren;</i>&#160; aber die Schwierigkeit besteht darin dieses Linken auszul&#246;sen, da die ganze DSL darauf abstellt, Funktionen beliebig ineinander zu verschachteln, und damit sehr viel zu kopieren; man m&#252;&#223;te dann entweder eine komplette Link-Infrastruktur hochziehen (Parser-Funktionen w&#228;ren speziell als noch ungelinkt markiert und es g&#228;be einen separaten Call-Chain), oder man m&#252;&#223;t das Binden/Materialisieren beim ersten Aufruf machen, was in der Praxis nicht sonderlich hilfreich ist
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1737761029853" ID="ID_588199339" MODIFIED="1737761044357" TEXT="also auch das etwas, was man einfach akzeptieren sollte">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1737048820482" ID="ID_235554745" MODIFIED="1737048832524" TEXT="generisches Model-Binding"/>
</node>
@ -57076,13 +57509,21 @@
</node>
<node COLOR="#338800" CREATED="1737692961931" ID="ID_877283346" MODIFIED="1737692966878" TEXT="Klammer-Kombinator">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1737509774878" ID="ID_1463442375" MODIFIED="1737693103778" TEXT="hier nur einige Varianten durchspielen">
<node COLOR="#435e98" CREATED="1737509774878" ID="ID_1463442375" MODIFIED="1737763426815" TEXT="hier nur einige Varianten durchspielen">
<linktarget COLOR="#69a19e" DESTINATION="ID_1463442375" ENDARROW="Default" ENDINCLINATION="365;-30;" ID="Arrow_ID_522261019" SOURCE="ID_890596853" STARTARROW="None" STARTINCLINATION="-269;35;"/>
</node>
<node COLOR="#435e98" CREATED="1737692984571" ID="ID_766136348" MODIFIED="1737693020068" TEXT="einmal zeigen wie das Model extrahiert wird"/>
<node COLOR="#435e98" CREATED="1737692995551" ID="ID_1734452138" MODIFIED="1737693020069" TEXT="Backtracking &#xfc;ber Whitespace bei optionaler Klammer"/>
<node COLOR="#435e98" CREATED="1737693009389" ID="ID_1022057324" MODIFIED="1737693020069" TEXT="beliebige Ausdr&#xfc;cke zur Klammerung"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737763262674" ID="ID_1514969475" MODIFIED="1737763269614" TEXT="Model-Bindings">
<icon BUILTIN="pencil"/>
<node CREATED="1737763440641" ID="ID_1186409722" MODIFIED="1737763479551" TEXT="einfache Transformatinon demonstrieren"/>
<node CREATED="1737763449624" ID="ID_299994031" MODIFIED="1737763466753" TEXT="bindMatch testen, auch mit Sub-Matches"/>
<node CREATED="1737509774878" ID="ID_1875116599" MODIFIED="1737763432229" TEXT="komplexe mehrstufige Transformation">
<linktarget COLOR="#69a19e" DESTINATION="ID_1875116599" ENDARROW="Default" ENDINCLINATION="365;-30;" ID="Arrow_ID_1373514851" SOURCE="ID_1532451583" STARTARROW="None" STARTINCLINATION="-268;27;"/>
</node>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1685583627381" FOLDED="true" ID="ID_1193075176" MODIFIED="1685631528263" TEXT="iterierbare Integer-Sequenz">