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:
parent
41ded40a3a
commit
860e2fa226
3 changed files with 533 additions and 11 deletions
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -56995,8 +56995,7 @@
|
|||
....muß dann aber durch die Entscheidungs-Logik sicherstellen, daß dann auch die zugehörige schließende Klammer entweder erwartet, oder ü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ür einfache Specs"/>
|
||||
<node CREATED="1737692936766" ID="ID_1532611498" MODIFIED="1737692952152" TEXT="aber mit explizitem "Opt" 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> muß tatsächlich ein <b>Postfix-Operator</b> 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 ... λ-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 (⟵ 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 λ-generic unterstü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ä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älle funktionieren mal grundsä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ühsam">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1737768409191" ID="ID_46123353" MODIFIED="1737768426237" TEXT="λ-generic funktionieren nicht wie gewünscht"/>
|
||||
<node CREATED="1737768426892" ID="ID_1722753025" MODIFIED="1737768440774" TEXT="und sonst muß 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ürlich ein Kern-Feature von recursive-descent"/>
|
||||
|
|
@ -57031,6 +57139,331 @@
|
|||
<node CREATED="1737553446367" ID="ID_420976669" MODIFIED="1737553464114" TEXT="müßte dafür Klauseln per Referenz nehmen können"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737693819337" ID="ID_228574257" MODIFIED="1737761064544" TEXT="Implementierungs-Technik klären">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737693835207" ID="ID_1616305471" MODIFIED="1737694295281" TEXT="grundsätzlich realisierbar in diesem Framework">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1737693849853" ID="ID_1927056535" MODIFIED="1737693956231" TEXT="ABER wir mü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ächlich nicht terminiert; in Haskell könnte man einen solchen Typ anschreiben, in C++ nicht (weil Typ-Ausdrücke eager aufgelö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> 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<PAR>-Instanz erfolgt"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1737694138462" ID="ID_837740353" MODIFIED="1737694189304" TEXT="Vorsicht �� können dann rekursive Systeme überhaupt formuliert werden?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1737694494314" ID="ID_1349021262" MODIFIED="1737694529548" TEXT="konkrete Typen können nur durch »Beispiel« 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ßt, es würde eine Art <i>late-Binding</i> 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ß 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 überhaupt erwähnt wird)">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1737738410117" ID="ID_1562192349" MODIFIED="1737738436974" TEXT="Ansatz-1 : als Sonderfall mit Einschränkungen">
|
||||
<node CREATED="1737738439713" ID="ID_1378187419" MODIFIED="1737738453835" TEXT="es gibt dann einen spezielle Operator "recurse""/>
|
||||
<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ährend dem Parsen) aufgelö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 »binden«"/>
|
||||
<node CREATED="1737738583534" ID="ID_421798511" MODIFIED="1737738612254" TEXT="bei diesem Ansatz stehen die Anknü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öst"/>
|
||||
<node CREATED="1737738800921" ID="ID_564771468" MODIFIED="1737738820906" TEXT="oder es wird eine Kette von Parser-Actions generiert und erst zuletzt ausgefü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änkt sich auf Rules and Productions"/>
|
||||
<node CREATED="1737738694393" ID="ID_462842617" MODIFIED="1737738704898" TEXT="der User muß 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 "Calculator"-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änkung: User muß 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önnen wir eine std::function<Ret(StrView)> anlegen"/>
|
||||
<node CREATED="1737756891099" ID="ID_1058310023" MODIFIED="1737756901161">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
und spä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> für das Parse-λ
|
||||
</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ß typischerweise ein Result-Binding definieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn sonst dürfte es kaum möglich sein, einen explizit angebbaren Result-Typ zu konstituieren; in diesem Result-Binding steckt der <i>eigentliche Ansatz,</i> mit dem eine offen-rekursive Grammatik dennoch handhabbar wird, denn es muß eine Art Reduktion der Komplexitä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="⟹ das muß das nä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-übergeben wird">
|
||||
<icon BUILTIN="idea"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1737694235744" ID="ID_1016606366" MODIFIED="1737694259530" TEXT="per Value / RValue ⟹ übernehmen und komplett einbinden"/>
|
||||
<node CREATED="1737694260501" ID="ID_199476088" MODIFIED="1737694285502" TEXT="per LValue ⟹ 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<RES>()"/>
|
||||
<node CREATED="1737757736924" ID="ID_845564019" MODIFIED="1737757760362" TEXT="Type-Tag ⟹ macht den Connex zuweisbar"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1737757814918" ID="ID_7084823" MODIFIED="1737757837403" TEXT="alles Übrige bleibt weiterhin »locker«">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1737757864319" ID="ID_1384035666" MODIFIED="1737757887112" TEXT="das heißt, auß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ö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 »zugedeckt«"/>
|
||||
<node CREATED="1737758244380" ID="ID_39267660" MODIFIED="1737758250903" TEXT="danach ist keine Zuweisung mehr mö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äuft"/>
|
||||
<node CREATED="1737758466942" ID="ID_397213831" MODIFIED="1737758745475">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Konsequenz ⟹ das <i>Einbinden</i> 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ürde)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1737758560698" ID="ID_1679326652" MODIFIED="1737758575731" TEXT="man muß 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 — was stets möglich ist)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
diese andere Syntax hätte dann aber auch einen anderen Typ und müß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änglich"/>
|
||||
<node CREATED="1737758836035" ID="ID_1710211125" MODIFIED="1737758849830" TEXT="man kann beliebig darü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 »filosofisch« und praktsich attraktiv
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...weil sie der „dann mach's halt nicht falsch“-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 — und wenn irgendjemand unbedingt dekorieren möchte, dann soll er halt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1737760037922" ID="ID_188274481" MODIFIED="1737760311471" TEXT="Variante-3 würde tatsächlich erweiterte Logik ermöglichen — erscheint aber fragwürdig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Weil das, was man nun zusätzlich machen könnte, nur auf Basis der Implementierung verständlich ist, aber für jeden Benutzer ziemlich verwirrend
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1737760312861" ID="ID_1430169629" MODIFIED="1737760337743" TEXT="Beschluß: Variante-1">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1737760340128" ID="ID_1904432675" MODIFIED="1737760536651" TEXT="Variante-2 wäre wü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>»Dekorieren«</i>  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üssen dauerhaft bestehen bleiben">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1737760626950" ID="ID_1746781945" MODIFIED="1737760654483" TEXT="damit die spätere Zuweisung klappt, müssen Referenzen verwendet werden"/>
|
||||
<node CREATED="1737760760265" ID="ID_1932015736" MODIFIED="1737760997909" TEXT="eine »high-tech-Lösung« wäre denkbar — erscheit aber zweifelhaft">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...sie bestünde darin, die Referenzen nach der Zuweisung zu <i>materialisieren;</i>  aber die Schwierigkeit besteht darin dieses Linken auszulösen, da die ganze DSL darauf abstellt, Funktionen beliebig ineinander zu verschachteln, und damit sehr viel zu kopieren; man müßte dann entweder eine komplette Link-Infrastruktur hochziehen (Parser-Funktionen wären speziell als noch ungelinkt markiert und es gäbe einen separaten Call-Chain), oder man müß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 über Whitespace bei optionaler Klammer"/>
|
||||
<node COLOR="#435e98" CREATED="1737693009389" ID="ID_1022057324" MODIFIED="1737693020069" TEXT="beliebige Ausdrü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">
|
||||
|
|
|
|||
Loading…
Reference in a new issue