Library: define skeleton of TextTemplate compilation
...implemented as »custom processing layer« within a demand-driven parsing pipeline, with the ability to inject additional Action-tokens to represent the intermittent constant text between tags; special handling to expose one constant postfix after the last active tag.
This commit is contained in:
parent
5b53b53c4c
commit
a9cbe7eb90
4 changed files with 306 additions and 58 deletions
|
|
@ -105,6 +105,7 @@
|
|||
#include "lib/regex.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
|
@ -113,6 +114,8 @@
|
|||
|
||||
namespace lib {
|
||||
|
||||
using std::optional;
|
||||
using std::nullopt;
|
||||
using std::string;
|
||||
using StrView = std::string_view;
|
||||
|
||||
|
|
@ -149,8 +152,9 @@ namespace lib {
|
|||
, END_FOR
|
||||
, ELSE
|
||||
};
|
||||
Keyword syntaxCase{ESCAPE};
|
||||
Keyword syntax{ESCAPE};
|
||||
StrView lead;
|
||||
StrView tail;
|
||||
string key;
|
||||
};
|
||||
|
||||
|
|
@ -166,30 +170,33 @@ namespace lib {
|
|||
auto pre = rest.length() - restAhead;
|
||||
tag.lead = rest.substr(0, pre);
|
||||
rest = rest.substr(tag.lead.length());
|
||||
if (mat[1].matched)
|
||||
return tag;
|
||||
if (mat[5].matched)
|
||||
tag.key = mat[5];
|
||||
if (mat[4].matched)
|
||||
{ // detected a logic keyword...
|
||||
if ("if" == mat[4])
|
||||
tag.syntaxCase = mat[5].matched? TagSyntax::END_IF : TagSyntax::IF;
|
||||
if (not mat[1].matched)
|
||||
{ // not escaped but indeed active field
|
||||
rest = rest.substr(mat.length());
|
||||
if (mat[4].matched)
|
||||
{ // detected a logic keyword...
|
||||
if ("if" == mat[4])
|
||||
tag.syntax = mat[3].matched? TagSyntax::END_IF : TagSyntax::IF;
|
||||
else
|
||||
if ("for" == mat[4])
|
||||
tag.syntax = mat[3].matched? TagSyntax::END_FOR : TagSyntax::FOR;
|
||||
else
|
||||
throw error::Logic("unexpected keyword");
|
||||
}
|
||||
else
|
||||
if ("for" == mat[4])
|
||||
tag.syntaxCase = mat[5].matched? TagSyntax::END_FOR : TagSyntax::FOR;
|
||||
if (mat[2].matched)
|
||||
tag.syntax = TagSyntax::ELSE;
|
||||
else
|
||||
throw error::Logic("unexpected keyword");
|
||||
tag.syntax = TagSyntax::KEYID;
|
||||
}
|
||||
else
|
||||
if (mat[3].matched)
|
||||
tag.syntaxCase = TagSyntax::ELSE;
|
||||
else
|
||||
tag.syntaxCase = TagSyntax::KEYID;
|
||||
tag.tail = rest;
|
||||
return tag;
|
||||
};
|
||||
|
||||
return explore (util::RegexSearchIter{input, ACCEPT_MARKUP})
|
||||
.transform(classify);
|
||||
.transform (classify);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +231,7 @@ namespace lib {
|
|||
struct Action
|
||||
{
|
||||
Code code{TEXT};
|
||||
string val{""};
|
||||
string val{};
|
||||
Idx refIDX{0};
|
||||
|
||||
template<class SRC>
|
||||
|
|
@ -234,7 +241,11 @@ namespace lib {
|
|||
/** the text template is compiled into a sequence of Actions */
|
||||
using ActionSeq = std::vector<Action>;
|
||||
|
||||
|
||||
|
||||
/** processor in a parse pipeline — yields sequence of Actions */
|
||||
template<class PAR>
|
||||
class ActionCompiler;
|
||||
|
||||
/** Binding to a specific data source.
|
||||
* @note requires partial specialisation */
|
||||
template<class DAT, typename SEL=void>
|
||||
|
|
@ -283,6 +294,89 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/* ======= Parser / Compiler pipeline ======= */
|
||||
|
||||
/**
|
||||
* @remarks this is a »custom processing layer«
|
||||
* to be used in an [Iter-Explorer](\ref iter-explorer.hpp)-pipeline.
|
||||
* The source layer (which is assumed to comply to the »State Core« concept),
|
||||
* yields TagSyntax records, one for each match of the ACCEPT_MARKUP reg-exp.
|
||||
* The actual compilation step, which is implemented as pull-processing here,
|
||||
* will emit one or several Action tokens on each match, thereby embedding the
|
||||
* extracted keys and possibly static fill strings. Since the _performance_ allows
|
||||
* for conditionals and iteration, some cross-linking is necessary, based on index
|
||||
* numbers for the actions emitted and coordinated by a stack of bracketing constructs.
|
||||
*/
|
||||
template<class PAR>
|
||||
class TextTemplate::ActionCompiler
|
||||
{
|
||||
Idx idx_{0};
|
||||
Action currToken_{};
|
||||
optional<StrView> post_{nullopt};
|
||||
|
||||
public:
|
||||
using PAR::PAR;
|
||||
|
||||
/* === state core protocol === */
|
||||
|
||||
bool
|
||||
checkPoint() const
|
||||
{
|
||||
return PAR::checkPoint()
|
||||
or bool(post_);
|
||||
}
|
||||
|
||||
Action const&
|
||||
yield() const
|
||||
{
|
||||
return currToken_;
|
||||
}
|
||||
|
||||
void
|
||||
iterNext()
|
||||
{
|
||||
++idx_;
|
||||
if (post_)
|
||||
post_ = nullopt;
|
||||
else
|
||||
currToken_ = compile();
|
||||
}
|
||||
|
||||
private:
|
||||
Action
|
||||
compile()
|
||||
{ //...throws if exhausted
|
||||
TagSyntax& tag = PAR::yield();
|
||||
auto isState = [this](Code c){ return c == currToken_.code; };
|
||||
auto nextState = [this] {
|
||||
StrView lead = tag.tail;
|
||||
PAR::iterNext();
|
||||
// first expose intermittent text before next tag
|
||||
if (PAR::checkPoint())
|
||||
lead = PAR::yield().lead;
|
||||
else // expose tail after final match
|
||||
post_ = lead;
|
||||
return Action{TEXT, lead};
|
||||
};
|
||||
switch (tag.syntax) {
|
||||
case TagSyntax::ESCAPE:
|
||||
return nextState();
|
||||
case TagSyntax::KEYID:
|
||||
if (isState (KEY))
|
||||
return nextState();
|
||||
return Action{KEY, tag.key};
|
||||
case TagSyntax::IF:
|
||||
case TagSyntax::END_IF:
|
||||
case TagSyntax::FOR:
|
||||
case TagSyntax::END_FOR:
|
||||
default:
|
||||
NOTREACHED ("uncovered TagSyntax keyword while compiling a TextTemplate.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* ======= preconfigured data bindings ======= */
|
||||
|
||||
|
|
@ -320,6 +414,36 @@ namespace lib {
|
|||
|
||||
/* ======= implementation of the instantiation state ======= */
|
||||
|
||||
/**
|
||||
* Interpret an action token from the compiled text template
|
||||
* based on the given data binding and iteration state to yield a rendering
|
||||
* @param instanceIter the wrapped InstanceCore with the actual data binding
|
||||
* @return a string-view pointing to the effective rendered chunk corresponding to this action
|
||||
*/
|
||||
template<class SRC>
|
||||
inline StrView
|
||||
TextTemplate::Action::instantiate (InstanceCore<SRC>& core) const
|
||||
{
|
||||
switch (code) {
|
||||
case TEXT:
|
||||
return val;
|
||||
case KEY:
|
||||
return core.getContent (val);
|
||||
case COND:
|
||||
return "";
|
||||
case JUMP:
|
||||
return "";
|
||||
case ITER:
|
||||
return "";
|
||||
case LOOP:
|
||||
return "";
|
||||
default:
|
||||
NOTREACHED ("uncovered Activity verb in activation function.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class SRC>
|
||||
TextTemplate::InstanceCore<SRC>::InstanceCore (TextTemplate::ActionSeq const& actions, SRC s)
|
||||
: dataSrc_{s}
|
||||
|
|
@ -375,35 +499,6 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Interpret an action token from the compiled text template
|
||||
* based on the given data binding and iteration state to yield a rendering
|
||||
* @param instanceIter the wrapped InstanceCore with the actual data binding
|
||||
* @return a string-view pointing to the effective rendered chunk corresponding to this action
|
||||
*/
|
||||
template<class SRC>
|
||||
inline StrView
|
||||
TextTemplate::Action::instantiate (InstanceCore<SRC>& core) const
|
||||
{
|
||||
switch (code) {
|
||||
case TEXT:
|
||||
return val;
|
||||
case KEY:
|
||||
return core.getContent (val);
|
||||
case COND:
|
||||
return "";
|
||||
case JUMP:
|
||||
return "";
|
||||
case ITER:
|
||||
return "";
|
||||
case LOOP:
|
||||
return "";
|
||||
default:
|
||||
NOTREACHED ("uncovered Activity verb in activation function.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** */
|
||||
|
|
|
|||
|
|
@ -837,7 +837,7 @@ namespace test{
|
|||
/**
|
||||
* demo of a custom processing layer
|
||||
* interacting directly with the iteration mechanism.
|
||||
* @note we can assume `SRC` is itself a Lumiera Iterator
|
||||
* @note we can assume `SRC` is itself a Lumiera »State Core«
|
||||
*/
|
||||
template<class SRC>
|
||||
struct MagicTestRubbish
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ namespace test {
|
|||
"${two}, \\$, ${if high}"_expect);
|
||||
|
||||
auto render = [](TagSyntax& tag) -> string
|
||||
{ return _Fmt{"▶%s‖%d|%s‖▷"} % string{tag.lead} % uint(tag.syntaxCase) % tag.key; };
|
||||
{ return _Fmt{"▶%s‖%d|%s‖▷"} % string{tag.lead} % uint(tag.syntax) % tag.key; };
|
||||
|
||||
auto wau = parse(input)
|
||||
.transform(render);
|
||||
|
|
|
|||
|
|
@ -112558,8 +112558,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
über einen freien Erweiterungspunkt? ⟹ die optimal flexible Lösung, aber trickreich zu realisieren und schwer zuverlässig zu steuern
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1711050681983" ID="ID_1452056641" MODIFIED="1711050729214" TEXT="gebe stattdessen einen literalen leeren String"/>
|
||||
|
|
@ -112736,7 +112735,45 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710799920412" ID="ID_1195498496" MODIFIED="1710800023758" TEXT="parsing">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1710804975672" ID="ID_1778438879" MODIFIED="1710804998137" TEXT="Reg-Exp-Iteration auf die Tag-Syntax"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710804975672" ID="ID_1778438879" MODIFIED="1711211821132" TEXT="Reg-Exp-Iteration auf die Tag-Syntax">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1711211822654" FOLDED="true" ID="ID_1575734676" LINK="#ID_1871157756" MODIFIED="1711212214143" TEXT="Layer-1 : Übersetzung in Syntax-Fälle">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1711212050899" ID="ID_573965593" MODIFIED="1711212112634" TEXT="gibt jeweils einen TagSyntax-Record aus">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...dieser enthält die Informationen aus dem RegExp-Match bereits semantisch aufgeschlüsselt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1711212113875" ID="ID_842279818" MODIFIED="1711212212420" TEXT="zudem wird eine Anschlußposition im Functor »versteckt mitgeschleppt«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...das heißt, die einzelne Auswertung ist keine <i>pure function </i>— aber der Seiteneffekt-Stat verbleibt in der Pipeline selber und merkt sich den Endpunkt des vorausgehenden Matches
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711211835240" ID="ID_1594550860" LINK="#ID_1703324697" MODIFIED="1711211884546" TEXT="Layer-2 : Behandeln und Ausfalten dieser Fälle">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1711212223692" ID="ID_1386017379" MODIFIED="1711212229862" TEXT="ein custom-processing-Layer"/>
|
||||
<node CREATED="1711212230571" ID="ID_1706127132" MODIFIED="1711212236414" TEXT="beinhaltet eine State-Machine"/>
|
||||
<node CREATED="1711212237363" ID="ID_98431449" MODIFIED="1711212249045" TEXT="und einen Stack für Klammer-Konstrukte"/>
|
||||
<node CREATED="1711212252456" ID="ID_1957416037" MODIFIED="1711212264479" TEXT="pull-processing auf iterNext()"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710804999413" ID="ID_670708059" MODIFIED="1710805006332" TEXT="handzuhabende Situationen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1710805054381" ID="ID_1600465677" MODIFIED="1710805058600" TEXT="erstes Tag">
|
||||
|
|
@ -113083,32 +113120,148 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<node CREATED="1711158213519" ID="ID_367034320" MODIFIED="1711158228179" TEXT="der sub-Match hat nur einen operator-string()">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1711209038541" ID="ID_363063181" MODIFIED="1711209133550">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
man könnte wohl was basteln mit den Funktionen <font color="#8b1212" face="Monospaced">position(i)</font> und <font color="#8b1212" face="Monospaced">length(i)</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1711158230860" ID="ID_421709614" MODIFIED="1711158244517" TEXT="also dann halt gleich als String speichern"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711158258547" ID="ID_431240403" MODIFIED="1711158398896" TEXT="muß das letzte Postfix ohne Match finden">
|
||||
<linktarget COLOR="#b72676" DESTINATION="ID_431240403" ENDARROW="Default" ENDINCLINATION="-233;16;" ID="Arrow_ID_232745747" SOURCE="ID_1998845229" STARTARROW="None" STARTINCLINATION="170;-14;"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711158258547" ID="ID_431240403" MODIFIED="1711209191700" TEXT="muß das letzte Postfix ohne Match finden">
|
||||
<linktarget COLOR="#b72676" DESTINATION="ID_431240403" ENDARROW="Default" ENDINCLINATION="-189;13;" ID="Arrow_ID_232745747" SOURCE="ID_1998845229" STARTARROW="None" STARTINCLINATION="170;-14;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711158504002" ID="ID_1524679089" MODIFIED="1711158524645" TEXT="Idee: pseudo-Match ganz auf das Ende der Quelle">
|
||||
<node CREATED="1711206740722" ID="ID_669120425" MODIFIED="1711206968242" TEXT="gute Lösung hängt stark von der intendierten Verwendung ab">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...und diese soll <i>irgendwie</i> auf eine Pipeline aufbauen. Das bedeutet, die Lösung sollte möglichst <i>in der Verarbeitung selber </i>zugänglich sein, und nicht über eine externe Zusatz-Information oder einen Seiteneffekt. Es wäre denkbar, auf das Ende des letzten Match aufzubauen — allerdings noch viel schöner wäre es, wenn der letzte Match den Quell-String <i>komplett ausschöpft, </i>so daß gar kein Rest übrig bleibt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1711158504002" ID="ID_1524679089" MODIFIED="1711211519363" TEXT="Idee: pseudo-Match ganz auf das Ende der Quelle">
|
||||
<icon BUILTIN="idea"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1711211522235" ID="ID_1955150565" MODIFIED="1711211532437" TEXT="pfiffig — aber nicht gut"/>
|
||||
<node CREATED="1711211533385" ID="ID_306654164" MODIFIED="1711211543099" TEXT="weicht die Semantik eines Match auf"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1711211553358" ID="ID_649407235" MODIFIED="1711211681159" TEXT="der nächste Übersetzungs-Schritt muß ohnehin zusätziche Token injizieren">
|
||||
<arrowlink COLOR="#8a7986" DESTINATION="ID_381376485" ENDARROW="Default" ENDINCLINATION="59;-62;" ID="Arrow_ID_1443688910" STARTARROW="None" STARTINCLINATION="-219;8;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1711211697867" ID="ID_1270227186" MODIFIED="1711211718485" TEXT="damit paßt eine solche Spezial-Behandlung viel besser dorthin">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711211720040" ID="ID_1750995315" MODIFIED="1711211788529" TEXT="man müßte nur einen continuation-Iterator durchgeben">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1711158657004" ID="ID_1183584439" MODIFIED="1711158688520" TEXT="Vorsicht: string-view ist gefährlich — wirklich sinnvoll?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1711158703398" ID="ID_338603175" MODIFIED="1711158746068" TEXT="in den Command-Tokens werden ohnehin Strings gespeichert"/>
|
||||
<node CREATED="1711158703398" ID="ID_338603175" MODIFIED="1711211670624" TEXT="in den Command-Tokens werden ohnehin Strings gespeichert"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711158747109" ID="ID_514130753" MODIFIED="1711158769304" TEXT="nochmal explizit durchverfolgen wo »materialisiert« werden soll">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711211350569" ID="ID_1703324697" MODIFIED="1711211362297" TEXT="Übersetzung in eine Action-Sequenz">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1711211369094" ID="ID_381376485" MODIFIED="1711211681159" TEXT="Achtung: muß die Iteration »rekursiv auffalten«">
|
||||
<linktarget COLOR="#8a7986" DESTINATION="ID_381376485" ENDARROW="Default" ENDINCLINATION="59;-62;" ID="Arrow_ID_1443688910" SOURCE="ID_649407235" STARTARROW="None" STARTINCLINATION="-219;8;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1711211412952" ID="ID_1907051261" MODIFIED="1711211437713" TEXT="in diversen Fällen erzeugt ein parse-Match mehrere Action-Token"/>
|
||||
<node CREATED="1711212281357" ID="ID_888907782" MODIFIED="1711212311261" TEXT="zudem ist das nicht nur eine Sate-Machine, sondern sogar ein Finite-Automaton with Stack"/>
|
||||
<node CREATED="1711212325687" ID="ID_1747255881" MODIFIED="1711212343572" TEXT="kann man aber in ein pull-Processing verwandeln">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711212348956" ID="ID_363295345" MODIFIED="1711212359403" TEXT="custom-processing-Layer schaffen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1711212365801" ID="ID_537344075" MODIFIED="1711212378412" TEXT="dieser enthält die eigentliche compile-Logik"/>
|
||||
<node CREATED="1711212381344" ID="ID_1526201544" MODIFIED="1711212412343" TEXT="⟹ wird eine nested template in der eigentlichen Engine"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711212414388" ID="ID_21802142" MODIFIED="1711212493609" TEXT="muß »State-Core«-Konzept implementieren — Behandlung hängt an iterNext()">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1711218612775" ID="ID_1789122488" MODIFIED="1711218978734" TEXT="State-Machine implementieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1711218621758" ID="ID_441666770" MODIFIED="1711218632180" TEXT="Funktion compile()">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1711218635275" ID="ID_567626918" MODIFIED="1711218954571" TEXT="zweistufige Entscheidung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1711218644620" ID="ID_193795202" MODIFIED="1711218667627" TEXT="basierend auf dem aktuell ausgegebenen Action-Token"/>
|
||||
<node CREATED="1711218668263" ID="ID_1000340819" MODIFIED="1711218684833" TEXT="plus zusätzlich dem im Basis-Iter sichtbaren Syntax-Match"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1711218687005" ID="ID_268208820" MODIFIED="1711218952954" TEXT="bei Weiterschalten...">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1711218708158" ID="ID_614509520" MODIFIED="1711218720643" TEXT="wird stets zunächst eine Action-TEXT emittiert"/>
|
||||
<node CREATED="1711218721440" ID="ID_676740256" MODIFIED="1711218738637" TEXT="diese exponiert den lead-Text (zwischen den Tags)"/>
|
||||
<node CREATED="1711218743589" ID="ID_1099243535" MODIFIED="1711218795646">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
erst in einem zweiten Schritt wird explizit eine spezifische Action für <i>diese Syntax </i>emittiert
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1711218803245" ID="ID_843446113" MODIFIED="1711218950661" TEXT="Spezialfall »Ende«">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1711218813985" ID="ID_1359111172" MODIFIED="1711218820291" TEXT="es gibt einen optional-tail"/>
|
||||
<node CREATED="1711218821082" ID="ID_1017969918" MODIFIED="1711218843881" TEXT="dieser wird nur aktiviert, wenn das Weiterschalten den Basis(Syntax)-Iterartor verbraucht hat"/>
|
||||
<node CREATED="1711218847503" ID="ID_730765448" MODIFIED="1711218910259">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
in diesem speziellen Fall wird das verbleibende Postfix
|
||||
</p>
|
||||
<p>
|
||||
vom letzten beobachteten Syntax-Match als TEXT-lead ausgegeben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1711218915070" ID="ID_201326654" MODIFIED="1711218937703" TEXT="iterNext() erkennt das ⟹ schaltet den optional-tail wieder weg"/>
|
||||
<node CREATED="1711218938586" ID="ID_253133952" MODIFIED="1711218948260" TEXT="danach: Trap-door">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711218958736" ID="ID_263202088" MODIFIED="1711218975015" TEXT="Klammer-Konstrukte">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1711158288320" ID="ID_309368656" MODIFIED="1711158292632" TEXT="Test....">
|
||||
<node CREATED="1711158297133" ID="ID_788373690" MODIFIED="1711158307246" TEXT="Iteration als Solche ist möglich"/>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1711158308121" ID="ID_1938624994" MODIFIED="1711158363263" TEXT="Kürzen des `lead` muß das Pattern selber überspringen">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1711158373801" ID="ID_1998845229" MODIFIED="1711158405321" TEXT="verliere das letzte Postfix">
|
||||
<arrowlink COLOR="#b72676" DESTINATION="ID_431240403" ENDARROW="Default" ENDINCLINATION="-233;16;" ID="Arrow_ID_232745747" STARTARROW="None" STARTINCLINATION="170;-14;"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1711158373801" ID="ID_1998845229" MODIFIED="1711209191700" TEXT="verliere das letzte Postfix">
|
||||
<arrowlink COLOR="#b72676" DESTINATION="ID_431240403" ENDARROW="Default" ENDINCLINATION="-189;13;" ID="Arrow_ID_232745747" STARTARROW="None" STARTINCLINATION="170;-14;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue