Library: implement logic-interpretation

- the basic interpretation of Action-tokens is already in place
 - add the interpretation of conditional and looping constructs
 - this includes helpers for
   * reset to another Action-token index
   * recursive interpretation of the next token
   * handling of nested loop evaluation context

In order to make this implementation compile, also the skeleton
of the Map-string-string data binding must be completed, including
a draft how to handle nested keys in a simple map
This commit is contained in:
Fischlurch 2024-03-25 02:19:46 +01:00
parent dd67b9f97b
commit 58ffbac7f3
4 changed files with 246 additions and 31 deletions

View file

@ -131,6 +131,20 @@ namespace lib {
template<class X>
using ExploreIter = decltype (lib::explore (std::declval<X>()));
//-----------Syntax-for-iteration-control-in-map------
const string MATCH_DATA_TOKEN { R"~(([^,;"\s]*)\s*)~"};
const string MATCH_DELIMITER { R"~((?:^|,|;)\s*)~" };
const regex ACCEPT_DATA_ELM {MATCH_DELIMITER + MATCH_DATA_TOKEN};
inline auto
iterNestedKeys (string key, string const& iterDef)
{
return explore (util::RegexSearchIter{iterDef, ACCEPT_DATA_ELM})
.transform ([&](smatch mat){ return key+"."+string{mat[1]}; });
}
//-----------Syntax-for-TextTemplate-tags--------
const string MATCH_SINGLE_KEY = "[A-Za-z_]+\\w*";
const string MATCH_KEY_PATH = MATCH_SINGLE_KEY+"(?:\\."+MATCH_SINGLE_KEY+")*";
const string MATCH_LOGIC_TOK = "if|for";
@ -283,8 +297,12 @@ namespace lib {
StrView& yield() const;
void iterNext();
void instantiateNext();
StrView instantiateNext();
StrView reInstatiate (Idx =Idx(-1));
StrView getContent(string key);
bool conditional (string key);
bool openIteration (string key);
bool loopFurther();
};
template<class DAT>
@ -507,7 +525,7 @@ namespace lib {
struct TextTemplate::DataSource<MapS>
{
MapS const * data_;
using Iter = std::string_view;
using Iter = decltype(iterNestedKeys("",""));
bool
contains (string key)
@ -522,6 +540,19 @@ namespace lib {
ENSURE (elm != data_->end());
return elm->second;
}
Iter
getSequence (string key)
{
UNIMPLEMENTED ("extract data sequence from definition key");
}
DataSource
openContext (Iter& iter)
{
REQUIRE (iter);
UNIMPLEMENTED ("open a nested sub-data-ctx based on the given iterator");
}
};
@ -545,13 +576,16 @@ namespace lib {
case KEY:
return core.getContent (val);
case COND:
return "";
return core.conditional (val)? core.reInstatiate() // next is the conditional content
: core.reInstatiate(refIDX); // points to start of else-block (or after)
case JUMP:
return "";
return core.reInstatiate(refIDX);
case ITER:
return "";
return core.openIteration(val)? core.reInstatiate() // looping initiated => continue with next
: core.reInstatiate(refIDX); // points to start of else-block (or after)
case LOOP:
return "";
return core.loopFurther() ? core.reInstatiate(refIDX+1) // start with one after the loop opening
: core.reInstatiate(); // continue with next -> jump over else-block
default:
NOTREACHED ("uncovered Activity verb in activation function.");
}
@ -593,25 +627,104 @@ namespace lib {
TextTemplate::InstanceCore<SRC>::iterNext()
{
++actionIter_;
instantiateNext();
rendered_ = instantiateNext();
}
template<class SRC>
inline void
TextTemplate::InstanceCore<SRC>::instantiateNext()
{
rendered_ = actionIter_? actionIter_->instantiate(*this)
: StrView{};
}
/** Instantiate next Action token and expose its rendering */
template<class SRC>
inline StrView
TextTemplate::InstanceCore<SRC>::getContent(string key)
TextTemplate::InstanceCore<SRC>::instantiateNext()
{
return actionIter_? actionIter_->instantiate(*this)
: StrView{};
}
/**
* relocate to another Action token and continue instantiation there
* @param nextCode index number of the next token;
* when not given, then iterate one step ahead
* @return the rendering produced by the selected next Action token
*/
template<class SRC>
inline StrView
TextTemplate::InstanceCore<SRC>::reInstatiate (Idx nextCode)
{
if (nextCode == Idx(-1))
++actionIter_;
else
actionIter_.setIDX (nextCode);
return instantiateNext();
}
/** retrieve a data value from the data source for the indiated key */
template<class SRC>
inline StrView
TextTemplate::InstanceCore<SRC>::getContent (string key)
{
static StrView nil{""};
return dataSrc_.contains(key)? dataSrc_.retrieveContent(key) : nil;
}
/** retrieve a data value for the key and interpret it as boolean expression */
template<class SRC>
inline bool
TextTemplate::InstanceCore<SRC>::conditional (string key)
{
return not util::isNo (string{getContent (key)});
}
/**
* Attempt to open data sequence by evaluating the entrance key.
* Data is retrieved for the key and evaluated to produce a collection of
* data entities to be iterated; each of these will be handled as a data scope
* nested into the current data scope. This implies to push a #NestedCtx into the
* #ctxStack_, store aside the current data source and replace it with the new
* data source for the nested scope. If iteration can not be initiated, all of
* the initialisation is reverted and the previous scope is reinstated.
* @return `true` if the nested context exists and the first element is available,
* `false` if iteration is not possible and the original context was restored
*/
template<class SRC>
inline bool
TextTemplate::InstanceCore<SRC>::openIteration (string key)
{
if (dataSrc_.contains(key))
if (DataCtxIter dataIter = dataSrc_.getSequence(key))
{
ctxStack_.push (NestedCtx{move (dataIter)
,dataSrc_});
dataSrc_ = dataSrc_.openContext (ctxStack_.top().first);
return true;
}
return false;
}
/**
* Possibly continue the iteration within an already established nested scope.
* If iteration to the next element is possible, it is expanded into the nested scope,
* else, when reaching iteration end, the enclosing scope is reinstated
* @return `true` if the next iterated element is available, `false` after iteration end
*/
template<class SRC>
inline bool
TextTemplate::InstanceCore<SRC>::loopFurther()
{
DataCtxIter& dataIter = ctxStack_.top().first;
++dataIter;
if (dataIter)
{ // open next nested context *from enclosing context*
dataSrc_ = ctxStack_.top().second.openContext (dataIter);
return true;
}
else
{ // restore original data context
std::swap (dataSrc_, ctxStack_.top().second);
ctxStack_.pop();
return false;
}
}

View file

@ -118,6 +118,14 @@ namespace util {
return regex_match (textForm, trueTokens);
}
bool
isNo (string const& textForm) noexcept
{
return isnil (textForm)
or regex_match (textForm, falseTokens);
}
} // namespace util

View file

@ -465,6 +465,12 @@ namespace util {
*/
bool isYes (string const&) noexcept;
/** check if the given text is empty or can be interpreted as rejection (bool `false`)-
* @remarks this function fishes for the known `false` tokens;
* any other non-empty content counts as _not no._
*/
bool isNo (string const&) noexcept;
} // namespace util

View file

@ -112564,10 +112564,12 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710803055072" ID="ID_1341021229" MODIFIED="1710888017135" TEXT="DataSrc.getSequence(key) &#x27fc; iter">
<node CREATED="1710803141876" ID="ID_196999296" MODIFIED="1710803152399" TEXT="interpretiert Content in eine Datensequenz"/>
<node CREATED="1710803153298" ID="ID_1252110387" MODIFIED="1710803171163" TEXT="liefert neuen Iterator &#xfc;ber Sequenz-content"/>
<node CREATED="1711329535378" ID="ID_155267016" MODIFIED="1711329541733" TEXT="(iter kann leer sein)"/>
</node>
<node CREATED="1710803215034" ID="ID_1113301675" MODIFIED="1710803311545" TEXT="DataSrc.openContext(iter) &#x27fc; DataSrc">
<node CREATED="1710803369685" ID="ID_530647329" MODIFIED="1710803382976" TEXT="auf dem Sequenz-iter aufgerufen"/>
<node CREATED="1710803384011" ID="ID_186066895" MODIFIED="1710803404991" TEXT="verwandelt diesen in eine verschachtelte Datenquelle"/>
<node CREATED="1711329511724" ID="ID_974929544" MODIFIED="1711329526896" TEXT="(darf nicht scheitern)"/>
</node>
</node>
<node CREATED="1710803510723" ID="ID_175021668" MODIFIED="1710803517763" TEXT="Datentypen">
@ -112731,8 +112733,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710799996889" ID="ID_1910948400" MODIFIED="1710800002425" TEXT="Processing">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710799920412" ID="ID_1195498496" MODIFIED="1710800023758" TEXT="parsing">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1710799920412" ID="ID_1195498496" MODIFIED="1711323991738" TEXT="parsing">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1710804975672" ID="ID_1778438879" MODIFIED="1711311749543" TEXT="Reg-Exp-Iteration auf die Tag-Syntax">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1711211822654" FOLDED="true" ID="ID_1575734676" LINK="#ID_1871157756" MODIFIED="1711212214143" TEXT="Layer-1 : &#xdc;bersetzung in Syntax-F&#xe4;lle">
@ -112820,11 +112822,15 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710806405673" ID="ID_1310523006" MODIFIED="1710806408164" TEXT="else &#x2227; Stack-Top &#x27fc; clauseIT">
<node CREATED="1710806493641" ID="ID_1459454155" MODIFIED="1710809753965" TEXT="Zugriff via clause-FOR.iterIDX"/>
<node CREATED="1710806533512" ID="ID_1807003849" MODIFIED="1710806538211" TEXT="loop-Code emittieren"/>
<node CREATED="1710806552007" ID="ID_354718435" MODIFIED="1711305441229" TEXT="iterIDX aus der clause-FOR f&#xfc;r R&#xfc;cksprung in den loop-Code &#xfc;bertragen"/>
<node CREATED="1710806552007" ID="ID_354718435" MODIFIED="1711329887721" TEXT="iterIDX aus der clause-FOR f&#xfc;r R&#xfc;cksprung in den loop-Code &#xfc;bertragen">
<linktarget COLOR="#7e8f95" DESTINATION="ID_354718435" ENDARROW="Default" ENDINCLINATION="535;21;" ID="Arrow_ID_1393334617" SOURCE="ID_1341056249" STARTARROW="None" STARTINCLINATION="314;-40;"/>
</node>
<node CREATED="1710808973802" ID="ID_21613324" MODIFIED="1710808986148" TEXT="jump-Code emittieren"/>
<node CREATED="1710806706513" ID="ID_899347616" MODIFIED="1710806717967" TEXT="(afterIDX) bleibt noch leer"/>
<node CREATED="1710806777807" ID="ID_700983662" MODIFIED="1710809774227" TEXT="aktuellen (jump)IDX in die clause-FOR schreiben"/>
<node CREATED="1710806509686" ID="ID_1028209132" MODIFIED="1711305413648" TEXT="n&#xe4;chsten IDX nach jump in iterCode schreiben"/>
<node CREATED="1710806509686" ID="ID_1028209132" MODIFIED="1711329761298" TEXT="n&#xe4;chsten IDX nach jump in iterCode schreiben">
<linktarget COLOR="#8fa5a4" DESTINATION="ID_1028209132" ENDARROW="Default" ENDINCLINATION="578;35;" ID="Arrow_ID_216186916" SOURCE="ID_1148009709" STARTARROW="None" STARTINCLINATION="107;-17;"/>
</node>
</node>
<node CREATED="1710806821425" ID="ID_1990562028" MODIFIED="1710806827725" TEXT="end for ID">
<node CREATED="1710806838975" ID="ID_400001835" MODIFIED="1710809782658" TEXT="pr&#xfc;fen: Stack-Top &#x27fc; clause-FOR mit passender ID "/>
@ -112852,24 +112858,24 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710800667346" ID="ID_299824445" MODIFIED="1710800700515" TEXT="handzuhabende Situationen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1710800705306" ID="ID_906431564" MODIFIED="1710800711869" TEXT="literaler Textblock">
<node COLOR="#435e98" CREATED="1710800705306" ID="ID_906431564" MODIFIED="1711326090062" TEXT="literaler Textblock">
<node CREATED="1710800725888" ID="ID_1235186459" MODIFIED="1710800731914" TEXT="Text liegt im Speicher"/>
<node CREATED="1710800732695" ID="ID_777704048" MODIFIED="1710800741009" TEXT="wird in die Ausgabe &#xfc;bertragen"/>
</node>
<node CREATED="1710800787373" ID="ID_1077539392" MODIFIED="1710800799529" TEXT="einfacher Platzhalter">
<node COLOR="#435e98" CREATED="1710800787373" ID="ID_1077539392" MODIFIED="1711326091945" TEXT="einfacher Platzhalter">
<node CREATED="1710800908415" ID="ID_1239575187" MODIFIED="1710800920805" TEXT="content-retrieval by key"/>
<node CREATED="1710800923037" ID="ID_681363276" MODIFIED="1710800939271" TEXT="missing-handler"/>
<node CREATED="1710800939834" ID="ID_1283509869" MODIFIED="1710800945313" TEXT="transfer to output"/>
</node>
<node CREATED="1710800985467" ID="ID_1738451953" MODIFIED="1710801003930" TEXT="Beginn conditional">
<node COLOR="#435e98" CREATED="1710800985467" ID="ID_1738451953" MODIFIED="1711326094040" TEXT="Beginn conditional">
<node CREATED="1710801008828" ID="ID_1249620465" MODIFIED="1710801016817" TEXT="content-retrieval by key"/>
<node CREATED="1710801019256" ID="ID_460082886" MODIFIED="1710801034122" TEXT="bool evaluation"/>
<node CREATED="1710801035982" ID="ID_743080453" MODIFIED="1710807359005" TEXT="false &#x27f9; jump to else/after-content"/>
</node>
<node CREATED="1710801201142" ID="ID_1826208607" MODIFIED="1710801226280" TEXT="Ende cond-true-Block">
<node COLOR="#435e98" CREATED="1710801201142" ID="ID_1826208607" MODIFIED="1711326108615" TEXT="Ende cond-true-Block">
<node CREATED="1710801231297" ID="ID_451436855" MODIFIED="1710801263363" TEXT="jump to content after conditional"/>
</node>
<node CREATED="1710801338037" ID="ID_864477992" MODIFIED="1710801346664" TEXT="Ende cond-else-block">
<node COLOR="#5b280f" CREATED="1710801338037" ID="ID_864477992" MODIFIED="1711326116336" TEXT="Ende cond-else-block">
<node CREATED="1710801347676" ID="ID_345168244" MODIFIED="1710801351618" TEXT="nichts zu tun"/>
<node CREATED="1710801352347" ID="ID_1875977491" MODIFIED="1710801358702" TEXT="mu&#xdf; daher nicht repr&#xe4;sentiert werden"/>
</node>
@ -112878,14 +112884,25 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710801417147" ID="ID_1408892944" MODIFIED="1710801477638" TEXT="start content-evaluation"/>
<node CREATED="1710801478482" ID="ID_1960402684" MODIFIED="1710801574417" TEXT="further content available?"/>
<node CREATED="1710801579485" ID="ID_23058821" MODIFIED="1710805564766" TEXT="true &#x27f9; push nested context ; continue with loop content"/>
<node CREATED="1710801620407" ID="ID_623818855" MODIFIED="1710807351948" TEXT="false &#x27f9; no nested context ; jump to else/after-content"/>
<node CREATED="1710801620407" ID="ID_623818855" MODIFIED="1710807351948" TEXT="false &#x27f9; no nested context ; jump to else/after-content">
<node CREATED="1711329698989" ID="ID_1148009709" MODIFIED="1711329775046" TEXT="stored in ITER.refIDX">
<arrowlink COLOR="#8fa5a4" DESTINATION="ID_1028209132" ENDARROW="Default" ENDINCLINATION="578;35;" ID="Arrow_ID_216186916" STARTARROW="None" STARTINCLINATION="107;-17;"/>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1710801647364" ID="ID_112069175" MODIFIED="1710801680283" TEXT="Loop-turn">
<node CREATED="1710801709939" ID="ID_791166881" MODIFIED="1710801715318" TEXT="re-access content-evaluation"/>
<node CREATED="1710801720458" ID="ID_1918287018" MODIFIED="1710801724653" TEXT="iterate content"/>
<node CREATED="1710801726097" ID="ID_336459864" MODIFIED="1710801732164" TEXT="further content available?"/>
<node CREATED="1710801736120" ID="ID_192397143" MODIFIED="1710805570164" TEXT="true &#x27f9; open content ; jump to loop content"/>
<node CREATED="1710801785474" ID="ID_800375943" MODIFIED="1710805576940" TEXT="false &#x27f9; pop nsted content ; jump to content after loop"/>
<node CREATED="1710801736120" ID="ID_192397143" MODIFIED="1710805570164" TEXT="true &#x27f9; open content ; jump to loop content">
<node CREATED="1711329802163" ID="ID_1341056249" MODIFIED="1711329895883" TEXT="stored in LOOP.refIDX">
<arrowlink COLOR="#7e8f95" DESTINATION="ID_354718435" ENDARROW="Default" ENDINCLINATION="535;21;" ID="Arrow_ID_1393334617" STARTARROW="None" STARTINCLINATION="314;-40;"/>
</node>
</node>
<node CREATED="1710801785474" ID="ID_800375943" MODIFIED="1710805576940" TEXT="false &#x27f9; pop nsted content ; jump to content after loop">
<node CREATED="1711329903057" ID="ID_1943380433" MODIFIED="1711329923237" TEXT="just proced to next (jump)"/>
</node>
</node>
<node CREATED="1710806989587" ID="ID_1498168313" MODIFIED="1710807003125" TEXT="Ende Iteration-else">
<node CREATED="1710807154373" ID="ID_1583286685" MODIFIED="1710807157096" TEXT="nichts zu tun"/>
@ -112976,7 +112993,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node CREATED="1710972830691" ID="ID_895397251" MODIFIED="1710972835926" TEXT="Auswertungs-Muster">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1710972830691" ID="ID_895397251" MODIFIED="1711329597210" TEXT="Auswertungs-Muster">
<icon BUILTIN="info"/>
<node CREATED="1710972837963" ID="ID_1932847831" MODIFIED="1710972867251" TEXT="gesteuert wird die Auswertung durch die ActionSeq-Iteration"/>
<node CREATED="1710972870686" ID="ID_522213375" MODIFIED="1710972892484" TEXT="daher bestimmt der ActionIter insgesamt den Zustand"/>
<node COLOR="#5b280f" CREATED="1710972915016" ID="ID_842055820" MODIFIED="1710973898400" TEXT="zudem soll aber auch die eigentliche Instantiierung on-demand geschehen">
@ -113000,6 +113018,34 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node COLOR="#338800" CREATED="1711326442066" ID="ID_1975129717" MODIFIED="1711329586814" TEXT="Implementierung der Iteration">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1711326831824" ID="ID_1207110980" MODIFIED="1711329576670" TEXT="openIteration()">
<icon BUILTIN="button_ok"/>
<node CREATED="1711326848891" ID="ID_1085311759" MODIFIED="1711326863445" TEXT="&#xf6;ffnet die Datensequenz"/>
<node CREATED="1711326864480" ID="ID_1029083441" MODIFIED="1711326881490" TEXT="legt den verschachtelten Kontext an"/>
<node CREATED="1711326882270" ID="ID_425634963" MODIFIED="1711326894144" TEXT="stellt darin den Element-Iterator bereit"/>
<node CREATED="1711327077532" ID="ID_1522625220" MODIFIED="1711327111532" TEXT="wenn dieser liefert &#x27f9; &#xf6;ffnet ersten Sub-Kontext"/>
<node CREATED="1711327114071" ID="ID_833633620" MODIFIED="1711327190428" TEXT="return...">
<node COLOR="#435e98" CREATED="1711327191287" ID="ID_1413278715" MODIFIED="1711329580845" TEXT="true &#x27f8; wenn Einstieg in Iteration"/>
<node COLOR="#435e98" CREATED="1711327193389" ID="ID_1755475253" MODIFIED="1711329582084" TEXT="false &#x27f8; wenn keine Iteration und Sub-Kontext wieder geschlossen"/>
</node>
</node>
<node COLOR="#338800" CREATED="1711327138951" ID="ID_1470540668" MODIFIED="1711329578827" TEXT="loopFurther()">
<icon BUILTIN="button_ok"/>
<node CREATED="1711327150235" ID="ID_1914395416" MODIFIED="1711327166972" TEXT="erwartet eine bereits ge&#xf6;ffnete Datensequenz"/>
<node CREATED="1711327216794" ID="ID_1011881825" MODIFIED="1711327224940" TEXT="inkrementiert den Iterator"/>
<node CREATED="1711327077532" ID="ID_570802171" MODIFIED="1711327241162" TEXT="wenn dieser liefert &#x27f9; &#xf6;ffnet n&#xe4;chsten Sub-Kontext"/>
<node CREATED="1711327114071" ID="ID_1357415127" MODIFIED="1711327190428" TEXT="return...">
<node COLOR="#435e98" CREATED="1711327191287" ID="ID_1415559908" MODIFIED="1711329583140" TEXT="true &#x27f8; wenn n&#xe4;chster Sub-Kontext bereitsteht"/>
<node COLOR="#435e98" CREATED="1711327193389" ID="ID_916304521" MODIFIED="1711329584228" TEXT="false &#x27f8; wenn Iterationsende und Sub-Kontext wieder geschlossen"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1711330603683" ID="ID_296531042" MODIFIED="1711330671193" TEXT="brauche zumindest elementares MapS-Binding">
<arrowlink COLOR="#b54881" DESTINATION="ID_702455242" ENDARROW="Default" ENDINCLINATION="-279;-482;" ID="Arrow_ID_1670013683" STARTARROW="None" STARTINCLINATION="-121;7;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node COLOR="#338800" CREATED="1710978786840" ID="ID_647695428" MODIFIED="1711046694334" TEXT="brauche einen &#xbb;Cursor&#xab; f&#xfc;r aktuelle Action">
<linktarget COLOR="#7e4239" DESTINATION="ID_647695428" ENDARROW="Default" ENDINCLINATION="-527;-17;" ID="Arrow_ID_660745747" SOURCE="ID_1755236197" STARTARROW="None" STARTINCLINATION="211;249;"/>
@ -113062,8 +113108,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710856784967" ID="ID_201927694" MODIFIED="1711067618760" TEXT="Parsing soll eager sein (wegen Syntax-Fehlern)">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1710856784967" FOLDED="true" ID="ID_201927694" MODIFIED="1711323978664" TEXT="Parsing soll eager sein (wegen Syntax-Fehlern)">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1711057133538" ID="ID_1870486170" MODIFIED="1711312266549" TEXT="versuche aber trotzdem ein Pipeline-Design">
<richcontent TYPE="NOTE"><html>
<head/>
@ -113366,7 +113412,15 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710804031539" ID="ID_1692068622" MODIFIED="1710879172991" TEXT="der Inhaltstyp wird via util::toString() zugegriffen"/>
<node CREATED="1710804062496" ID="ID_377899149" MODIFIED="1710804093937" TEXT="DataSrc ist ein generischer Wrapper um die Map"/>
<node CREATED="1710804167972" ID="ID_200600045" MODIFIED="1710804186992" TEXT="der Iterator ist eine String-View (ein String-Range)"/>
<node CREATED="1710804197208" ID="ID_709716942" MODIFIED="1710804233519" TEXT="Sequenz-Auswertung interpretiert den String als CSV-Zeile"/>
<node CREATED="1710804197208" ID="ID_709716942" MODIFIED="1710804233519" TEXT="Sequenz-Auswertung interpretiert den String als CSV-Zeile">
<node CREATED="1711333409904" ID="ID_402579513" MODIFIED="1711333425916" TEXT="aber vereinfacht: keine Quotes, kein embedded whitespace"/>
<node CREATED="1711333426672" ID="ID_1427514449" MODIFIED="1711333441194" TEXT="lediglich eine Sequenz von Key-pr&#xe4;fixen">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1711333449605" ID="ID_1163600793" MODIFIED="1711333463407" TEXT="(RegExp aus CSV.hpp abnehmen)">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1710804454510" ID="ID_835685377" MODIFIED="1710879851836" TEXT="die einzelnen Sequenz-Elemente werden als Key-Pr&#xe4;fix interpretiert"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1710804234267" ID="ID_226073889" MODIFIED="1710804261633" TEXT="Verschachtelung wird nicht unterst&#xfc;tzt">
<icon BUILTIN="yes"/>
@ -113374,6 +113428,40 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710804264759" ID="ID_1288259029" MODIFIED="1710804281745" TEXT="das bedeutet: die Daten m&#xfc;ssen eben dementsprechend strukturiert sein"/>
<node CREATED="1710804473275" ID="ID_1177047190" MODIFIED="1710804522912" TEXT="ein verschachtelter Kontext mu&#xdf; Keys referenzieren, die anderweitig in der Map vorhanden sind"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1711330640991" ID="ID_702455242" MODIFIED="1711330676226" TEXT="Implementierung">
<linktarget COLOR="#b54881" DESTINATION="ID_702455242" ENDARROW="Default" ENDINCLINATION="-279;-482;" ID="Arrow_ID_1670013683" SOURCE="ID_296531042" STARTARROW="None" STARTINCLINATION="-121;7;"/>
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1711330691216" ID="ID_650431219" MODIFIED="1711331581249" TEXT="h&#xe4;lt einen Pointer auf die zugrundeliegende Map">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711331357462" ID="ID_1912581954" MODIFIED="1711331578929" TEXT="merkt sich ein Key-Pr&#xe4;fix zur Dekoration">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711331495228" ID="ID_745563840" MODIFIED="1711331561532" TEXT="es wird nur beim Zugriff immer das Pr&#xe4;fix vor den jeweils gegebenen Key geklebt">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1711331371556" ID="ID_909634689" MODIFIED="1711331568956" TEXT="hier wird nicht verschachtelt">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711331380819" ID="ID_853300536" MODIFIED="1711331563787" TEXT="es gibt dann nur einen Fallback auf die undekorierte Map">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711331407216" ID="ID_1304513851" MODIFIED="1711331577097" TEXT="die Iteration wertet eine Liste von Daten-Key-Elementen aus">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#435e98" CREATED="1711331431068" ID="ID_748427184" MODIFIED="1711333491631" TEXT="aus jedem wird ein Pr&#xe4;fix gebildet">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1711331438131" ID="ID_11449117" MODIFIED="1711333484929" TEXT="mit dem Namen des Datenscope als gemeinsame Wurzel">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711331452457" ID="ID_1332962848" MODIFIED="1711333475268" TEXT="das l&#xe4;uft auf eine Filter-Pipeline hinaus">
<icon BUILTIN="button_ok"/>
<node CREATED="1711331463028" ID="ID_87423548" MODIFIED="1711331468558" TEXT="Ebene-1 : RegExp-Iter"/>
<node CREATED="1711331469327" ID="ID_1328551681" MODIFIED="1711331478314" TEXT="Ebene-2 : Keys zusammensetzen"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710804833930" ID="ID_1766619477" MODIFIED="1710804839987" TEXT="Test-Binding">
<icon BUILTIN="flag-yellow"/>