Library: add support for bracketed expressions
This is the very key feature that requires a real parser and can not be handled by regular expressions. After all the groundwork, it is surprisingly easy provide now; only coding up all those DSL-variants is tedious. Notably we also support accepting an ''optional'' bracket, and we support arbitrary expressions for the ''opening'' and ''closing construct.''
This commit is contained in:
parent
089fafc1bd
commit
41ded40a3a
3 changed files with 280 additions and 80 deletions
|
|
@ -412,7 +412,7 @@ namespace util {
|
|||
]
|
||||
(StrView toParse) -> IterEval
|
||||
{
|
||||
uint consumed{0};
|
||||
size_t consumed{0};
|
||||
IterResult results;
|
||||
do
|
||||
{
|
||||
|
|
@ -460,6 +460,48 @@ namespace util {
|
|||
}
|
||||
|
||||
|
||||
/** accept some structure enclosed into a bracketing construct.
|
||||
* \param isOptional if the bracketing can be omitted */
|
||||
template<class C1, class C2, class C3>
|
||||
auto
|
||||
bracketedConnex (C1&& openingConnex
|
||||
,C2&& closingConnex
|
||||
,C3&& bodyConnex
|
||||
,bool isOptional)
|
||||
{
|
||||
using Res = typename decay_t<C3>::Result;
|
||||
return Connex{[opening = forward<C1>(openingConnex)
|
||||
,closing = forward<C2>(closingConnex)
|
||||
,body = forward<C3>(bodyConnex)
|
||||
,isOptional
|
||||
]
|
||||
(StrView toParse) -> Eval<Res>
|
||||
{
|
||||
auto bracket = opening.parse (toParse);
|
||||
if (bracket.result or isOptional)
|
||||
{
|
||||
size_t consumed = bracket.consumed;
|
||||
bool expectClose{bracket.result};
|
||||
auto eval = body.parse (toParse.substr(consumed));
|
||||
if (eval.result)
|
||||
{
|
||||
consumed += eval.consumed;
|
||||
if (expectClose)
|
||||
bracket = closing.parse (toParse.substr(consumed));
|
||||
if (bracket.result or not expectClose)
|
||||
{
|
||||
consumed += bracket.consumed;
|
||||
return Eval<Res>{move (*eval.result)
|
||||
,consumed
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return Eval<Res>{std::nullopt};
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -606,6 +648,21 @@ namespace util {
|
|||
template<typename SPEC>
|
||||
auto repeat (SPEC&& clauseDef);
|
||||
|
||||
template<typename SPEC1, typename SPEC2, typename SPEC3>
|
||||
auto bracket (SPEC1&& openDef, SPEC2&& closeDef, SPEC3&& bodyDef);
|
||||
|
||||
template<typename SPEC>
|
||||
auto bracket (string bracketSpec, SPEC&& bodyDef);
|
||||
|
||||
template<typename SPEC>
|
||||
auto bracket (SPEC&& bodyDef);
|
||||
|
||||
template<typename SPEC>
|
||||
auto bracketOpt (string bracketSpec, SPEC&& bodyDef);
|
||||
|
||||
template<typename SPEC>
|
||||
auto bracketOpt (SPEC&& bodyDef);
|
||||
|
||||
private:
|
||||
Eval<Result>& eval() { return *this;}
|
||||
};
|
||||
|
|
@ -696,7 +753,74 @@ namespace util {
|
|||
{
|
||||
return accept_repeated (NullType{}, forward<SPEC>(clauseDef));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start Syntax with a sub-clause enclosed into a _bracketing construct._
|
||||
* The »bracket« is defined as syntax for the _open marker_ and _close marker._
|
||||
* These are consumed without generating model elements. The parse fails unless
|
||||
* the full sequence `open body close` can be matched.
|
||||
*/
|
||||
template<typename SPEC1, typename SPEC2, typename SPEC3>
|
||||
auto
|
||||
accept_bracket (SPEC1&& openDef, SPEC2&& closeDef, SPEC3&& bodyDef)
|
||||
{
|
||||
return accept(
|
||||
bracketedConnex (Parser{forward<SPEC1>(openDef) }
|
||||
,Parser{forward<SPEC2>(closeDef)}
|
||||
,Parser{forward<SPEC3>(bodyDef) }
|
||||
,false // bracket mandatory, not optional
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Syntax with a bracketed sub-clause, with given single-char delimiters.
|
||||
* \param bracketSpec a 2-char string, e.g. "{}" to expect curly braces.
|
||||
*/
|
||||
template<typename SPEC>
|
||||
auto
|
||||
accept_bracket (string bracketSpec, SPEC&& bodyDef)
|
||||
{
|
||||
if (bracketSpec.size() != 2)
|
||||
throw err::Invalid{"Bracket spec with opening and closing character expected"};
|
||||
return accept(
|
||||
bracketedConnex (Parser{"\\"+bracketSpec.substr(0,1)}
|
||||
,Parser{"\\"+bracketSpec.substr(1,1)}
|
||||
,Parser{forward<SPEC>(bodyDef) }
|
||||
,false // bracket mandatory, not optional
|
||||
));
|
||||
}
|
||||
|
||||
/** Start Syntax with a sub-clause enclosed in parentheses */
|
||||
template<typename SPEC>
|
||||
auto
|
||||
accept_bracket (SPEC&& bodyDef)
|
||||
{
|
||||
return accept_bracket ("()", forward<SPEC>(bodyDef));
|
||||
}
|
||||
|
||||
/** Start Syntax with a sub-clause, _optionally_ enclosed into brackets. */
|
||||
template<typename SPEC>
|
||||
auto
|
||||
accept_bracketOpt (string bracketSpec, SPEC&& bodyDef)
|
||||
{
|
||||
if (bracketSpec.size() != 2)
|
||||
throw err::Invalid{"Bracket spec with opening and closing character expected"};
|
||||
return accept(
|
||||
bracketedConnex (Parser{"\\"+bracketSpec.substr(0,1)}
|
||||
,Parser{"\\"+bracketSpec.substr(1,1)}
|
||||
,Parser{forward<SPEC>(bodyDef) }
|
||||
,true // bracket optional, can be omitted
|
||||
));
|
||||
}
|
||||
|
||||
template<typename SPEC>
|
||||
auto
|
||||
accept_bracketOpt (SPEC&& bodyDef)
|
||||
{
|
||||
return accept_bracketOpt ("()", forward<SPEC>(bodyDef));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Combinator: extend this Syntax clause by expecting a further sub-clause
|
||||
|
|
@ -794,6 +918,54 @@ namespace util {
|
|||
return seq (accept_repeated (forward<SPEC>(clauseDef)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Combinator: extend this Syntax with a further sequenced sub-clause in brackets.
|
||||
* @see accept_bracket()
|
||||
*/
|
||||
template<class PAR>
|
||||
template<typename SPEC1, typename SPEC2, typename SPEC3>
|
||||
auto
|
||||
Syntax<PAR>::bracket (SPEC1&& openDef, SPEC2&& closeDef, SPEC3&& bodyDef)
|
||||
{
|
||||
return seq (accept_bracket (forward<SPEC1>(openDef)
|
||||
,forward<SPEC2>(closeDef)
|
||||
,forward<SPEC3>(bodyDef)));
|
||||
}
|
||||
|
||||
template<class PAR>
|
||||
template<typename SPEC>
|
||||
auto
|
||||
Syntax<PAR>::bracket (string bracketSpec, SPEC&& bodyDef)
|
||||
{
|
||||
return seq (accept_bracket (move (bracketSpec)
|
||||
,forward<SPEC>(bodyDef)));
|
||||
}
|
||||
|
||||
template<class PAR>
|
||||
template<typename SPEC>
|
||||
auto
|
||||
Syntax<PAR>::bracket (SPEC&& bodyDef)
|
||||
{
|
||||
return seq (accept_bracket (forward<SPEC>(bodyDef)));
|
||||
}
|
||||
|
||||
template<class PAR>
|
||||
template<typename SPEC>
|
||||
auto
|
||||
Syntax<PAR>::bracketOpt (string bracketSpec, SPEC&& bodyDef)
|
||||
{
|
||||
return seq (accept_bracketOpt (move (bracketSpec)
|
||||
,forward<SPEC>(bodyDef)));
|
||||
}
|
||||
|
||||
template<class PAR>
|
||||
template<typename SPEC>
|
||||
auto
|
||||
Syntax<PAR>::bracketOpt (SPEC&& bodyDef)
|
||||
{
|
||||
return seq (accept_bracketOpt (forward<SPEC>(bodyDef)));
|
||||
}
|
||||
|
||||
}// namespace parse
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -533,13 +533,31 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test
|
||||
*
|
||||
*/
|
||||
/** @test define syntax with bracketed sub-expressions */
|
||||
void
|
||||
acceptBracketed()
|
||||
{
|
||||
UNIMPLEMENTED ("bracketed");
|
||||
string word{"\\w+"};
|
||||
|
||||
CHECK (not accept(word).bracket(word) .parse("so sad"));
|
||||
CHECK ( accept(word).bracketOpt(word).parse("so sad"));
|
||||
CHECK ( accept(word).bracketOpt(word).parse("so (sad)"));
|
||||
|
||||
CHECK (accept_bracket(word).parse(" ( again ) ").getResult().str() == "again");
|
||||
|
||||
CHECK (not accept_bracket(word) .parse("(again"));
|
||||
CHECK (not accept_bracketOpt(word).parse("(again"));
|
||||
CHECK ( accept_bracketOpt(word).parse("again)")); // just stops before the trailing ')'
|
||||
CHECK ( accept_bracketOpt(word).parse("again)").consumed() == 5);
|
||||
CHECK ( accept_bracketOpt(word).parse(" again")); // backtracks also over the whitespace
|
||||
|
||||
CHECK (not accept_bracket("[]",word).parse("(again)"));
|
||||
CHECK (not accept_bracket("[]",word).parse("[again)"));
|
||||
CHECK (not accept_bracket("[]",word).parse("(again]"));
|
||||
CHECK ( accept_bracket("[]",word).parse("[again]"));
|
||||
CHECK ( accept_bracket("a","n","...").parse("again")); // arbitrary expressions for open / close
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -55219,16 +55219,13 @@
|
|||
<icon BUILTIN="forward"/>
|
||||
<node BACKGROUND_COLOR="#ecdcb4" COLOR="#491354" CREATED="1737603423470" ID="ID_1829725832" LINK="#ID_172468776" MODIFIED="1737643392381" STYLE="fork">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
top-Level-Einstiege bieten ⟹ Präfix <font face="Monospaced" color="#681d21">accept_</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ecdcb4" COLOR="#491354" CREATED="1737603413919" ID="ID_1979527720" MODIFIED="1737603564463" STYLE="fork" TEXT="implizite Sequenz als default-Junktor">
|
||||
|
|
@ -55461,7 +55458,7 @@
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1736896942694" ID="ID_50956958" MODIFIED="1737649641200" TEXT="Kreis schließen: Parser wieder aus Syntax bauen">
|
||||
<linktarget COLOR="#de5868" DESTINATION="ID_50956958" ENDARROW="Default" ENDINCLINATION="-792;1631;" ID="Arrow_ID_1971370194" SOURCE="ID_950065344" STARTARROW="None" STARTINCLINATION="-1469;98;"/>
|
||||
<linktarget COLOR="#587bde" DESTINATION="ID_50956958" ENDARROW="Default" ENDINCLINATION="-792;1631;" ID="Arrow_ID_1971370194" SOURCE="ID_950065344" STARTARROW="None" STARTINCLINATION="-1469;98;"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1736896960412" ID="ID_281482378" MODIFIED="1736896967137" TEXT="will nicht recht funktionieren">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1736896977066" ID="ID_773020678" MODIFIED="1736897010857" TEXT="das läuft auf ein clone-construct des Connex hinaus">
|
||||
|
|
@ -55952,9 +55949,7 @@
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1737512123490" ID="ID_1402725802" MODIFIED="1737512293076" TEXT="andere Lösung: wir geben den aufzunehmenden Typ im Konstruktor vor">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das ist eine mehrstufige Kette
|
||||
|
|
@ -56589,9 +56584,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1737482977331" ID="ID_63052973" MODIFIED="1737483103594" TEXT="Analog zum SeqModel, aber...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...hier ist die Logik umgedreht
|
||||
|
|
@ -56611,9 +56604,7 @@
|
|||
<node CREATED="1737483106692" ID="ID_483924984" MODIFIED="1737483124362" TEXT="linker Zweig: ein isolierter Einzel-Wert"/>
|
||||
<node CREATED="1737483124926" ID="ID_1937433694" MODIFIED="1737483165305">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
linker Zweig: ein sub-Model, in dem <i>irgend ein Zweig</i> gematched hat
|
||||
|
|
@ -56642,9 +56633,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1737483378196" ID="ID_1296449236" LINK="https://stackoverflow.com/a/34941417/444796" MODIFIED="1737483733563" TEXT="Problem: C++ kann nur sehr limitiert gegen Argument-Packs matchen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Der Argument-Pack muß stets am Ende stehen
|
||||
|
|
@ -56671,9 +56660,7 @@
|
|||
<node CREATED="1737488602575" ID="ID_1122120666" MODIFIED="1737488612529" TEXT="wenn man O(n) akzeptiert..."/>
|
||||
<node CREATED="1737488613118" ID="ID_19428808" MODIFIED="1737496895025" TEXT="dann kann man direkt ein Sequenz-Rebinding-Template bauen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Grundidee: man baut die neue, umgebaute Typ-Sequenz in den variadischen Argumenten <i>eines beliebigen Templates,</i> das selbst als Template-Template-Parameter gegeben wird. Damit kann man unmittelbar in einem einzigen Zug das redefinierte Ziel-Template konstruieren, ohne erst in eine andere Verarbeitungs-Domäne (tuple, Typsequenz, Typliste) mappen zu müssen. Zudem kann das gleiche Verarbeitungs-Template auch Spezial-Belegungen für Hilfs-Operationen mit anbieten, und man kann gleich die häufigsten verwandten Tools in einer einzigen Definition zur Verfügung stellen.
|
||||
|
|
@ -56693,9 +56680,7 @@
|
|||
<node CREATED="1737496192747" ID="ID_1063059900" MODIFIED="1737496232714" TEXT="da kann auch das RebindVariadic umziehen"/>
|
||||
<node CREATED="1737496233662" ID="ID_1200621276" MODIFIED="1737496367205" TEXT="alle ohne weitere Abhängigkeiten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
da zeichnet sich ein Schema ab, das die bekannten Sequenz-Umordnungen sehr direkt ausführt, ohne erst in eine andere Repräsentation (wie Typelist) zu mappen. Trotzdem ist der Aufwand O(n), für das Umkehren der Sequenz sogar O(n²)
|
||||
|
|
@ -56731,9 +56716,7 @@
|
|||
<node CREATED="1737504193738" ID="ID_1385503322" MODIFIED="1737504206428" TEXT="wird hier sogar noch einfacher"/>
|
||||
<node CREATED="1737504208567" ID="ID_1221738967" MODIFIED="1737507938424" TEXT="Design scheint sehr gut zu passen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...Hinweis darauf ist der Umstand, daß ich gar nicht mehr viel auswerten / prüfen muß, sondern direkt der Match auf die Konstruktor-Argumente den Rest der Logik erledigt.
|
||||
|
|
@ -56754,9 +56737,7 @@
|
|||
<node CREATED="1737507491637" ID="ID_397795294" MODIFIED="1737507505855" TEXT="Clients sollen nur selected() und get<i>() verwenden"/>
|
||||
<node CREATED="1737507511586" ID="ID_1197062880" MODIFIED="1737507548997" TEXT="eigentlichen Konstruktor besser private machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
da geht nämlich eine Branch-ID ein, und die muß <= TOP sein
|
||||
|
|
@ -56787,9 +56768,7 @@
|
|||
<node CREATED="1737513818322" ID="ID_532960229" MODIFIED="1737513970917" TEXT="speziell gecodeter Seq-Kombinator"/>
|
||||
<node CREATED="1737514200891" ID="ID_349069421" MODIFIED="1737514255695" TEXT="hat Backtracking zum Abbruch">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
wenn am Ende keine weitere Iteration akzeptiert werden kann, ist das kein Fehler, sondern wir stehen hinter der zuletzt akzeptierten Iteration
|
||||
|
|
@ -56799,9 +56778,7 @@
|
|||
</node>
|
||||
<node CREATED="1737514258866" ID="ID_1304545890" MODIFIED="1737514379504" TEXT="(optional) Trenner mit 1-Fall-Behandlung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ein Trenner muß nicht gegeben sein (dann wird lediglich der Rumpf iteriert); wenn aber ein Trenner gegeben ist, dann wird er beim 1.Mal explizit übersprungen (darf also nicht da sein), bei allen anderen Iterationen wird er zu Beginn der Iteration erwartet
|
||||
|
|
@ -56816,9 +56793,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1737553087867" ID="ID_1345136935" MODIFIED="1737553184049" TEXT="nein denn der Regelfall zählt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
man kann sich Situationen denken.... aber dann hätte man auch stets dieses Ergebnis-Tupel zu handhaben.
|
||||
|
|
@ -56844,9 +56819,7 @@
|
|||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1737515006854" ID="ID_1604079761" MODIFIED="1737516214711" TEXT="feste Anzahl ist grundsätzlich notwendig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
weil wir bisher keinen generischen Rekursions-Mechanismus vorsehen und ansonsten die Zahl der Iterationen erst in einem Post-Proecssing-Schritt geprüft werden könnte.
|
||||
|
|
@ -56856,9 +56829,7 @@
|
|||
</node>
|
||||
<node CREATED="1737516079454" ID="ID_1854925549" MODIFIED="1737516212509" TEXT="spezielles Modell erscheint mir unnötig komplex">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Es würde sich um einige Randfälle handeln, denn im Regelfall ist eine Iteration offen / abzählbar. Und wir müßten in eine derart performance-kritische Situation vorstoßen, in der eine Heap-Allokation prohibitiv wäre
|
||||
|
|
@ -56899,9 +56870,7 @@
|
|||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1737569852750" ID="ID_1574259355" MODIFIED="1737571535674" TEXT="Begründung: sonst bekommen wir stets eine implizite Sequenz mit Tupel auf Model-Ebene">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dem inzwischen etablierten Schema der Syntax-Klauseln zufolge muß jeder Junktor etwas mit der aktuellen Syntax-Spec anknüpfen. Wenn nun ein iter()-Prädikat essentiell eine neue Syntax anfängt, wäre eine implizite Konvention zu treffen, was mit der bestehenden Klausel passiert. Naheliegend wäre eine Sequenz; dann besteht aber die Gefahr, daß in der Praxis oft eine leere Sequenz spezifiziert wird (wäre noch akzeptabel) — und man zur Model-Anknüpfung stets dieses Tupel aufmachen müßte (schröcklich)
|
||||
|
|
@ -56912,9 +56881,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1737570726608" ID="ID_1134276650" MODIFIED="1737571090798">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dann muß man aber die <b>Postfix-takes-all-Logik</b> akzeptieren
|
||||
|
|
@ -56932,27 +56899,24 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#ecdcb4" COLOR="#491354" CREATED="1737603246542" ID="ID_1239316504" MODIFIED="1737603354469" TEXT="implizite Sequenz als Default ist doch gar nicht so schlecht">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737603322428" ID="ID_172468776" MODIFIED="1737603344117" TEXT="also doch top-Level">
|
||||
<node COLOR="#435e98" CREATED="1737603322428" ID="ID_172468776" MODIFIED="1737683900054" TEXT="also doch top-Level">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1737643237418" ID="ID_1852967082" MODIFIED="1737643310172">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
stets mit Präfix <font face="Monospaced" size="3" color="#542c2c">accept_</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1737649521902" ID="ID_950065344" MODIFIED="1737649641200" TEXT="muß Parser aus Syntax erzeugen können">
|
||||
<arrowlink COLOR="#de5868" DESTINATION="ID_50956958" ENDARROW="Default" ENDINCLINATION="-792;1631;" ID="Arrow_ID_1971370194" STARTARROW="None" STARTINCLINATION="-1469;98;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#007488" CREATED="1737649521902" ID="ID_950065344" MODIFIED="1737683929300" TEXT="muß Parser aus Syntax erzeugen können">
|
||||
<arrowlink COLOR="#587bde" DESTINATION="ID_50956958" ENDARROW="Default" ENDINCLINATION="-792;1631;" ID="Arrow_ID_1971370194" STARTARROW="None" STARTINCLINATION="-1469;98;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737603327947" ID="ID_366774797" MODIFIED="1737603344113" TEXT="und lokal als implizite Sequenz">
|
||||
<node COLOR="#435e98" CREATED="1737603327947" ID="ID_366774797" MODIFIED="1737683904933" TEXT="und lokal als implizite Sequenz">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -56961,22 +56925,21 @@
|
|||
<node COLOR="#435e98" CREATED="1737557821953" ID="ID_874093473" MODIFIED="1737581094904" TEXT="ohne Delimiter"/>
|
||||
<node COLOR="#435e98" CREATED="1737557826978" ID="ID_631895252" MODIFIED="1737581097119" TEXT="mit fester Anzahl"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1737509793049" ID="ID_909696958" MODIFIED="1737557632090" TEXT="funktioniert im Test">
|
||||
<node COLOR="#338800" CREATED="1737509793049" ID="ID_909696958" MODIFIED="1737659588090" TEXT="funktioniert im Test">
|
||||
<arrowlink COLOR="#69a19e" DESTINATION="ID_1818283954" ENDARROW="Default" ENDINCLINATION="341;-27;" ID="Arrow_ID_1906636741" STARTARROW="None" STARTINCLINATION="-269;35;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737515386507" ID="ID_1671829221" MODIFIED="1737591861198" TEXT="optionaler Kombinator">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1737515386507" ID="ID_1671829221" MODIFIED="1737683894096" TEXT="optionaler Kombinator">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1737515398692" ID="ID_1478704437" MODIFIED="1737515413091" TEXT="der ist einfach zu realisieren und sehr nützlich"/>
|
||||
<node CREATED="1737515413799" ID="ID_1235063232" MODIFIED="1737515424929" TEXT="das Model wird in einen std::optional gewickelt"/>
|
||||
<node BACKGROUND_COLOR="#e5d4c6" COLOR="#435e98" CREATED="1737515765304" ID="ID_692646776" MODIFIED="1737571714725" TEXT="per postfix-Operator darstellbar?">
|
||||
<node BACKGROUND_COLOR="#e5d4c6" COLOR="#435e98" CREATED="1737515765304" ID="ID_692646776" MODIFIED="1737686075882" TEXT="per postfix-Operator darstellbar?">
|
||||
<icon BUILTIN="help"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1737552397609" ID="ID_411565433" MODIFIED="1737552415673">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
der Implementierung nach <i>ist es</i> ein Dekorator
|
||||
|
|
@ -56987,7 +56950,8 @@
|
|||
<node CREATED="1737552798647" ID="ID_845579574" MODIFIED="1737552821888" TEXT="Scheitern des Parsers führt nur zu Backtracking"/>
|
||||
</node>
|
||||
<node CREATED="1737552824569" ID="ID_1896891774" MODIFIED="1737603097508" TEXT="Lesbarkeit der DSL-Varianten....">
|
||||
<node CREATED="1737552866525" ID="ID_849718453" MODIFIED="1737603117259" TEXT="Postfix geht immer — wirkt aber auf die ganze Klausel">
|
||||
<node COLOR="#5b280f" CREATED="1737552866525" ID="ID_849718453" MODIFIED="1737686086186" TEXT="Postfix geht immer — wirkt aber auf die ganze Klausel">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1737570726608" ID="ID_543391021" MODIFIED="1737603076848" TEXT="Postfix-takes-all-Logik">
|
||||
<arrowlink COLOR="#b60c19" DESTINATION="ID_1134276650" ENDARROW="Default" ENDINCLINATION="205;10;" ID="Arrow_ID_497998726" STARTARROW="None" STARTINCLINATION="79;-13;"/>
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
|
|
@ -56997,7 +56961,8 @@
|
|||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1737552896306" ID="ID_978425545" MODIFIED="1737603209963" TEXT="optional(parse) - Funktionsschreibweise klarer">
|
||||
<node COLOR="#435e98" CREATED="1737552896306" ID="ID_978425545" MODIFIED="1737686083456" TEXT="optional(parse) - Funktionsschreibweise klarer">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1737571480380" ID="ID_330911197" MODIFIED="1737571485431" TEXT="muß dann aber top-level sein"/>
|
||||
<node CREATED="1737571488227" ID="ID_479972357" MODIFIED="1737603236739" TEXT="oder eine Sequenz implizieren">
|
||||
<arrowlink COLOR="#9091a5" DESTINATION="ID_1574259355" ENDARROW="Default" ENDINCLINATION="185;6;" ID="Arrow_ID_1603942836" STARTARROW="None" STARTINCLINATION="128;-10;"/>
|
||||
|
|
@ -57006,8 +56971,10 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1737515434452" ID="ID_1202348659" MODIFIED="1737515439980" TEXT="geklammerter Kombinator">
|
||||
<node CREATED="1737515442819" ID="ID_1736743033" MODIFIED="1737515446558" TEXT="Ansatz">
|
||||
<node COLOR="#338800" CREATED="1737515434452" ID="ID_1202348659" MODIFIED="1737693034882" TEXT="geklammerter Kombinator">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1737515442819" ID="ID_1736743033" MODIFIED="1737686220301" TEXT="Ansatz">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1737515447274" ID="ID_489661667" MODIFIED="1737515455093" TEXT="auch das ist ein spezieller Seq-Kombinator"/>
|
||||
<node CREATED="1737515524672" ID="ID_1601647856" MODIFIED="1737515536547" TEXT="auch hier mehrere Definitionsvarianten">
|
||||
<node CREATED="1737515541990" ID="ID_747449690" MODIFIED="1737515553010" TEXT="mit einer 2-Elementigen Zeichenkette"/>
|
||||
|
|
@ -57015,6 +56982,41 @@
|
|||
</node>
|
||||
<node CREATED="1737515572953" ID="ID_1363324375" MODIFIED="1737515586156" TEXT="auch hier wird für die Klammer kein Model-Binding erzeugt"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1737686102981" ID="ID_1886755899" MODIFIED="1737686120919" TEXT="Connex-Implementierung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1737686122903" ID="ID_510115146" MODIFIED="1737686134035" TEXT="zusätzlicher Parameter: isOptional">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#005488" CREATED="1737686134769" ID="ID_555728929" MODIFIED="1737686205650" TEXT="kann damit eine optionale Klammerung stillschweigend konsumieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....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>
|
||||
</node>
|
||||
<node COLOR="#437c98" CREATED="1737686235979" ID="ID_85956191" MODIFIED="1737686271881" TEXT="(insofern ist die Sequenziertung explizit ausprogrammiert)">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1737686277970" ID="ID_157058701" MODIFIED="1737692733801" TEXT="DSL-Varianten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1737686320772" ID="ID_311789519" MODIFIED="1737693134268" TEXT="wieder das gleiche Schema wie bei repeat()">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1737686330919" ID="ID_723414011" MODIFIED="1737686346057" TEXT="die stand-alone accept_ - Builder formulieren alle Varianten"/>
|
||||
<node CREATED="1737686346740" ID="ID_1198745755" MODIFIED="1737686374019" TEXT="die eingebetteten combinatoren rufen diese mit seq() auf"/>
|
||||
</node>
|
||||
<node CREATED="1737692801065" ID="ID_713160509" MODIFIED="1737692828857" TEXT="einfache Spec: zerlege 2-Zeichen String ⟶ RegExp mit Quote"/>
|
||||
<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">
|
||||
<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="#f0d5c5" COLOR="#990033" CREATED="1737515599278" ID="ID_1897353084" MODIFIED="1737515606925" TEXT="schwierige Frage....">
|
||||
|
|
@ -57066,13 +57068,21 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1737557515000" ID="ID_717799418" MODIFIED="1737557531293" TEXT="Parse-Mechanismus skizzieren"/>
|
||||
<node COLOR="#435e98" CREATED="1737557534805" ID="ID_1997532643" MODIFIED="1737557551147" TEXT="Akzeptieren und Backtracking"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737509774878" ID="ID_1818283954" MODIFIED="1737603375589" TEXT="Kombinator per DSL">
|
||||
<node COLOR="#435e98" CREATED="1737509774878" ID="ID_1818283954" MODIFIED="1737693072768" TEXT="Kombinator per DSL">
|
||||
<linktarget COLOR="#69a19e" DESTINATION="ID_1818283954" ENDARROW="Default" ENDINCLINATION="341;-27;" ID="Arrow_ID_1906636741" SOURCE="ID_909696958" STARTARROW="None" STARTINCLINATION="-269;35;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1737581111703" ID="ID_1277454723" MODIFIED="1737581129805" TEXT="mit vorgegebener Anzahl"/>
|
||||
<node COLOR="#435e98" CREATED="1737581124685" ID="ID_196113271" MODIFIED="1737581129806" TEXT="ohne Delimiter"/>
|
||||
</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">
|
||||
<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>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1685583627381" FOLDED="true" ID="ID_1193075176" MODIFIED="1685631528263" TEXT="iterierbare Integer-Sequenz">
|
||||
|
|
|
|||
Loading…
Reference in a new issue