Library: suppress leading whitespace automatically
Seems like a pragmatic choice, which simplifies most syntax definitions significantly. In exceptional cases, it is still possible to enforce a situation with `\b` or `\B`
This commit is contained in:
parent
fb78c10996
commit
cf91f167dd
4 changed files with 87 additions and 40 deletions
|
|
@ -32,7 +32,6 @@
|
|||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/regex.hpp"
|
||||
|
||||
//#include <regex>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
|
|
@ -91,9 +90,11 @@ namespace util {
|
|||
{
|
||||
return Connex{[regEx = move(rex)]
|
||||
(StrView toParse) -> Eval<smatch>
|
||||
{
|
||||
{ // skip leading whitespace...
|
||||
size_t pre = leadingWhitespace (toParse);
|
||||
toParse = toParse.substr(pre);
|
||||
auto result{matchAtStart (toParse,regEx)};
|
||||
size_t consumed = result? result->length() : 0;
|
||||
size_t consumed = result? pre+result->length() : 0;
|
||||
return {move(result), consumed};
|
||||
}};
|
||||
}
|
||||
|
|
@ -236,7 +237,7 @@ namespace util {
|
|||
};
|
||||
|
||||
|
||||
|
||||
/** accept sequence of two parse functions */
|
||||
template<class C1, class C2>
|
||||
auto
|
||||
sequenceConnex (C1&& connex1, C2&& connex2)
|
||||
|
|
|
|||
|
|
@ -77,6 +77,16 @@ namespace util {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
/** @return number of leading whitespace characters */
|
||||
template<typename STR>
|
||||
size_t
|
||||
leadingWhitespace (STR&& toParse)
|
||||
{
|
||||
static const regex LEADING_WHITESPACE{"^\\s*", regex::optimize};
|
||||
auto search = RegexSearchIter{std::forward<STR> (toParse), LEADING_WHITESPACE};
|
||||
return search? search->length() : 0;
|
||||
}
|
||||
|
||||
}// namespace util
|
||||
|
||||
namespace lib {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,8 @@ namespace test {
|
|||
{
|
||||
}
|
||||
|
||||
/** @test TODO define a terminal symbol to match by parse. */
|
||||
|
||||
/** @test define a terminal symbol to match by parse. */
|
||||
void
|
||||
acceptTerminal()
|
||||
{
|
||||
|
|
@ -95,7 +96,7 @@ namespace test {
|
|||
string toParse{"hello vile world of power"};
|
||||
auto eval = parse (toParse);
|
||||
CHECK (eval.result);
|
||||
auto res = *eval.result;
|
||||
auto res = *eval.result; // ◁——————————— the »result model« of a terminal parse is the RegExp-Matcher
|
||||
CHECK (res.ready() and not res.empty());
|
||||
CHECK (res.size() == "2"_expect );
|
||||
CHECK (res.position() == "0"_expect );
|
||||
|
|
@ -103,10 +104,10 @@ namespace test {
|
|||
CHECK (res[1] == "vile"_expect );
|
||||
CHECK (res.suffix() == " of power"_expect );
|
||||
|
||||
auto syntax = Syntax{move (parse)};
|
||||
auto syntax = Syntax{move (parse)}; // Build a syntax clause from the simple terminal symbol parser
|
||||
CHECK (not syntax.hasResult());
|
||||
syntax.parse (toParse);
|
||||
CHECK (syntax.success());
|
||||
CHECK (syntax.success()); // Syntax clause holds an implicit state from the last parse
|
||||
CHECK (syntax.getResult()[1] == "vile"_expect);
|
||||
|
||||
// shorthand notation to start building a syntax
|
||||
|
|
@ -131,10 +132,12 @@ namespace test {
|
|||
CHECK (eval.result->str(1) == "cruel");
|
||||
}
|
||||
|
||||
/** @test TODO define a sequence of syntax structures to match by parse. */
|
||||
|
||||
/** @test define a sequence of syntax structures to match by parse. */
|
||||
void
|
||||
acceptSequential()
|
||||
{
|
||||
// Demonstration: how sequence combinator works....
|
||||
auto term1 = buildConnex ("hello");
|
||||
auto term2 = buildConnex ("world");
|
||||
auto parseSeq = [&](StrView toParse)
|
||||
|
|
@ -161,22 +164,29 @@ namespace test {
|
|||
return ProductEval{std::nullopt};
|
||||
};
|
||||
string s1{"hello millions"};
|
||||
string s2{"helloworld"};
|
||||
string s3{"helloworldtrade"};
|
||||
string s2{"hello world"};
|
||||
string s3{" hello world trade "};
|
||||
|
||||
auto e1 = parseSeq(s1);
|
||||
CHECK (not e1.result);
|
||||
CHECK (not e1.result); // Syntax 'hello'>>'world' does not accept "hello millions"
|
||||
auto e2 = parseSeq(s2);
|
||||
CHECK ( e2.result);
|
||||
|
||||
using SeqRes = std::decay_t<decltype(*e2.result)>;
|
||||
CHECK (is_Tuple<SeqRes>());
|
||||
using SeqRes = std::decay_t<decltype(*e2.result)>; // Note: the result type depends on the actual syntax construction
|
||||
CHECK (is_Tuple<SeqRes>()); // Result model from sequence is the tuple of terminal results
|
||||
auto& [r1,r2] = *e2.result;
|
||||
CHECK (r1.str() == "hello"_expect);
|
||||
CHECK (r2.str() == "world"_expect);
|
||||
|
||||
CHECK (term2.parse(" world").result); // Note: leading whitespace skipped by the basic terminal parsers
|
||||
CHECK (term2.parse("\n \t world ").result);
|
||||
CHECK (not term2.parse(" old ").result);
|
||||
|
||||
|
||||
// DSL parse clause builder: a sequence of terminals...
|
||||
auto syntax = accept("hello").seq("world");
|
||||
|
||||
// Perform the same parse as demonstrated above....
|
||||
CHECK (not syntax.hasResult());
|
||||
syntax.parse(s1);
|
||||
CHECK (not syntax.success());
|
||||
|
|
@ -186,13 +196,15 @@ namespace test {
|
|||
CHECK (get<0>(seqModel).str() == "hello"_expect);
|
||||
CHECK (get<1>(seqModel).str() == "world"_expect);
|
||||
|
||||
|
||||
// can build extended clause from existing one
|
||||
auto syntax2 = syntax.seq("trade");
|
||||
CHECK (not syntax2.hasResult());
|
||||
syntax2.parse(s2);
|
||||
CHECK (not syntax2.success());
|
||||
syntax2.parse(s3);
|
||||
CHECK (syntax2.success());
|
||||
auto seqModel2 = syntax2.getResult();
|
||||
auto seqModel2 = syntax2.getResult(); // Note: model of consecutive sequence is flattened into a single tuple
|
||||
CHECK (get<0>(seqModel2).str() == "hello"_expect);
|
||||
CHECK (get<1>(seqModel2).str() == "world"_expect);
|
||||
CHECK (get<2>(seqModel2).str() == "trade"_expect);
|
||||
|
|
|
|||
|
|
@ -55506,8 +55506,8 @@
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1736897354542" ID="ID_1609713458" MODIFIED="1736897365189" TEXT="Sequenz-Kombinator anlegen">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1736897787716" ID="ID_663293705" MODIFIED="1736902761360" TEXT="Basis-Mechanik">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1736897787716" ID="ID_663293705" MODIFIED="1737234458887" TEXT="Basis-Mechanik">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1736897797339" ID="ID_1097974753" MODIFIED="1736897811257" TEXT="brauche Zugang zu den Parse-Funktoren"/>
|
||||
<node CREATED="1736902653470" ID="ID_755819552" MODIFIED="1736902670961" TEXT="Ende des akzeptierten Strings">
|
||||
<node CREATED="1736902672230" ID="ID_1913745367" MODIFIED="1736902683365" TEXT="zunächst einmal: vom Match-Result"/>
|
||||
|
|
@ -55522,7 +55522,7 @@
|
|||
<node COLOR="#338800" CREATED="1736902736554" ID="ID_432853835" MODIFIED="1736902758544" TEXT="erst einmal explizit als Lambda für zwei Parse-Funktionen ausformuliert">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1736902793923" ID="ID_1319004614" MODIFIED="1736946563499" TEXT="umformulieren für variadische Argumente">
|
||||
<node COLOR="#5b280f" CREATED="1736902793923" FOLDED="true" ID="ID_1319004614" MODIFIED="1737234456278" TEXT="umformulieren für variadische Argumente">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1736942836696" ID="ID_329695591" MODIFIED="1736942842636" TEXT="Schwierigkeiten">
|
||||
<node CREATED="1736942844308" ID="ID_1678112989" MODIFIED="1736942912951" TEXT="Kurzschluß-Auswertung erwünscht"/>
|
||||
|
|
@ -55566,22 +55566,23 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1736949111365" ID="ID_1303026500" MODIFIED="1736949118408" TEXT="als Connex-Funktion formulieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1736949111365" ID="ID_1303026500" MODIFIED="1737234448750" TEXT="als Connex-Funktion formulieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1737048177736" ID="ID_991166662" MODIFIED="1737048198173" TEXT="Grundstruktur aus explizitiem Beispiel im Test abgeleitet">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737048205644" ID="ID_106647279" MODIFIED="1737048267183" TEXT="Problem lösen: Definition des Ergebnis-Modells">
|
||||
<arrowlink COLOR="#476e9d" DESTINATION="ID_251061074" ENDARROW="Default" ENDINCLINATION="-14;-71;" ID="Arrow_ID_1227279766" STARTARROW="None" STARTINCLINATION="-108;6;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1737048205644" ID="ID_106647279" MODIFIED="1737234441912" TEXT="Problem lösen: Definition des Ergebnis-Modells">
|
||||
<arrowlink COLOR="#47839d" DESTINATION="ID_251061074" ENDARROW="Default" ENDINCLINATION="-14;-71;" ID="Arrow_ID_1227279766" STARTARROW="None" STARTINCLINATION="-108;6;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1736946825696" ID="ID_272711066" MODIFIED="1736946834898" TEXT="Model-Increment">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1736947018560" ID="ID_251061074" MODIFIED="1737048260215" TEXT="Implementierungstechnik klären">
|
||||
<linktarget COLOR="#476e9d" DESTINATION="ID_251061074" ENDARROW="Default" ENDINCLINATION="-14;-71;" ID="Arrow_ID_1227279766" SOURCE="ID_106647279" STARTARROW="None" STARTINCLINATION="-108;6;"/>
|
||||
<linktarget COLOR="#47839d" DESTINATION="ID_251061074" ENDARROW="Default" ENDINCLINATION="-14;-71;" ID="Arrow_ID_1227279766" SOURCE="ID_106647279" STARTARROW="None" STARTINCLINATION="-108;6;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1736947190134" ID="ID_1146338669" MODIFIED="1736968973059" TEXT="es gibt dedizierte Funktionen für jede der drei Junktoren">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1736947190134" ID="ID_1146338669" MODIFIED="1737234426676" TEXT="es gibt dedizierte Funktionen für jede der drei Junktoren">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1736947371567" ID="ID_296644251" MODIFIED="1736947389799" TEXT="Sequence-Model ⟹ tuple_cat"/>
|
||||
<node CREATED="1736947394747" ID="ID_942226963" MODIFIED="1736947427275" TEXT="Alternative-Model ⟹ AltTypes (Spezial-Container)"/>
|
||||
<node CREATED="1736947454403" ID="ID_1190687854" MODIFIED="1736948158833" TEXT="Repetitive-Model ⟹ Array mit exponentiellem Wachstum"/>
|
||||
|
|
@ -55828,8 +55829,9 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1736988419593" ID="ID_364383845" MODIFIED="1736988437151" TEXT="Pattern-Match und Spezialfall-Implementierung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1736988439351" ID="ID_396611819" MODIFIED="1736988490982" TEXT="verwende ein explizit definiertes Tag: Sub<X>"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1736988542489" ID="ID_1635129166" MODIFIED="1736988555544" TEXT="Model-Join möglichst extrahieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1736988542489" ID="ID_1635129166" MODIFIED="1737234629319" TEXT="Model-Join extrahieren">
|
||||
<arrowlink COLOR="#465acd" DESTINATION="ID_226754618" ENDARROW="Default" ENDINCLINATION="-418;52;" ID="Arrow_ID_1636406845" STARTARROW="None" STARTINCLINATION="-11;79;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1736989303802" ID="ID_343321438" MODIFIED="1736989337762" TEXT="künstlichen Overlay-(Sub)-Typ mit präparierten ctor-Varianten"/>
|
||||
<node CREATED="1736989524517" ID="ID_1328191899" MODIFIED="1736989546365" TEXT="wir verwenden also für alle Fälle noch ein Type-Tag">
|
||||
<node CREATED="1736989550865" ID="ID_1529698419" MODIFIED="1736989681361" TEXT="hey ... jetzt wird die Sache doch noch symmetrisch">
|
||||
|
|
@ -55863,7 +55865,9 @@
|
|||
<node CREATED="1736990997055" ID="ID_814902476" MODIFIED="1736991012369" TEXT="explizite Spezialisierungen als Fallunterscheidung"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1736991166384" ID="ID_226754618" MODIFIED="1736991170299" TEXT="Fallkombinationen">
|
||||
<node CREATED="1736991166384" ID="ID_226754618" MODIFIED="1737234614712" TEXT="Fallkombinationen">
|
||||
<linktarget COLOR="#465acd" DESTINATION="ID_226754618" ENDARROW="Default" ENDINCLINATION="-418;52;" ID="Arrow_ID_1636406845" SOURCE="ID_1635129166" STARTARROW="None" STARTINCLINATION="-11;79;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1736991171271" ID="ID_1748513219" MODIFIED="1736991211262" TEXT="_Join<TAG,R1,R2> ⟼ TAG<R1,R2>">
|
||||
<node CREATED="1736991696404" ID="ID_564129640" MODIFIED="1736991706911" TEXT="das impliziert bereits den Tag-Wechsel">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -55896,6 +55900,14 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1737048069726" ID="ID_129104167" MODIFIED="1737048085836" TEXT="Fall-Differenzierung der _Join-Konstruktoren">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1737234497746" ID="ID_936287985" MODIFIED="1737234549166" TEXT="Sequence">
|
||||
<icon BUILTIN="info"/>
|
||||
<node COLOR="#435e98" CREATED="1737234502793" ID="ID_1552148571" MODIFIED="1737234536557" TEXT="akzeptiere zwei Werte ⟶ Paar"/>
|
||||
<node COLOR="#435e98" CREATED="1737234520187" ID="ID_898480863" MODIFIED="1737234536557" TEXT="akzeptiere SeqModel + Wert ⟶ verlängertes Model"/>
|
||||
</node>
|
||||
<node CREATED="1737234537803" ID="ID_337495209" MODIFIED="1737234551785" TEXT="Alternative">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -55904,8 +55916,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737048292893" ID="ID_387462355" MODIFIED="1737169984121" TEXT="Model-Inkrement konkret als tuple_cat realisieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1737048292893" ID="ID_387462355" MODIFIED="1737234313030" TEXT="Model-Inkrement konkret als tuple_cat realisieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1737132764886" ID="ID_975789323" MODIFIED="1737132784921" TEXT="erster Schritt: Tupel aus zwei Sub-Klauseln konstruieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -55984,8 +55996,8 @@
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737048838728" ID="ID_327712073" MODIFIED="1737048870554" TEXT="automatisch Whitespace absorbieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1737048838728" ID="ID_327712073" MODIFIED="1737234331858" TEXT="automatisch Whitespace absorbieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#5b280f" CREATED="1737170123805" ID="ID_4605321" MODIFIED="1737170139588" TEXT="theoretisch könnte man Whitespace-Trenner sogar mandatory machen">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1737170144395" ID="ID_620070055" MODIFIED="1737170158073" TEXT="dann braucht man aber auch wieder einen Mechanismus zum Abschalten"/>
|
||||
|
|
@ -56004,11 +56016,18 @@
|
|||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1737229037275" ID="ID_1729467516" MODIFIED="1737229073499" TEXT="sollte in den accept()-Basismechanismus">
|
||||
<node CREATED="1737234122430" ID="ID_1129471425" MODIFIED="1737234267590" TEXT="Hilfsfunktion: leadingWhitespace()"/>
|
||||
<node CREATED="1737234278625" ID="ID_1620595973" MODIFIED="1737234290691" TEXT="generisch ⟶ regexp.hpp"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1737048362231" ID="ID_751583918" MODIFIED="1737048461620" TEXT="funktioniert im Test">
|
||||
<arrowlink DESTINATION="ID_1506892827" ENDARROW="Default" ENDINCLINATION="44;-70;" ID="Arrow_ID_283520954" STARTARROW="None" STARTINCLINATION="-17;2;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1737048362231" ID="ID_751583918" MODIFIED="1737234328776" TEXT="funktioniert im Test">
|
||||
<arrowlink DESTINATION="ID_1506892827" ENDARROW="Default" ENDINCLINATION="44;-70;" ID="Arrow_ID_283520954" STARTARROW="None" STARTINCLINATION="-64;7;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737234396680" ID="ID_679636766" MODIFIED="1737235494542" TEXT="Alternativ-Kombinator bauen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1737048820482" ID="ID_235554745" MODIFIED="1737048832524" TEXT="generisches Model-Binding"/>
|
||||
</node>
|
||||
|
|
@ -56021,15 +56040,20 @@
|
|||
<node COLOR="#435e98" CREATED="1736884136614" ID="ID_243681799" MODIFIED="1736884148676" TEXT="als Syntax verpackt"/>
|
||||
<node COLOR="#435e98" CREATED="1736889505771" ID="ID_467899164" MODIFIED="1736889511345" TEXT="Abkürzungs-Notation"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1736897334425" ID="ID_1642919143" MODIFIED="1736897370269" TEXT="Sequenz-Kombinator">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1736897343352" ID="ID_693798752" MODIFIED="1736897348148" TEXT="Grundmechanismus">
|
||||
<node COLOR="#338800" CREATED="1736897334425" ID="ID_1642919143" MODIFIED="1737234335798" TEXT="Sequenz-Kombinator">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1736897343352" ID="ID_693798752" MODIFIED="1737234341384" TEXT="Grundmechanismus">
|
||||
<node COLOR="#435e98" CREATED="1736902766936" ID="ID_1599733497" MODIFIED="1736902777757" TEXT="zwei parse-Funktoren verbinden"/>
|
||||
<node COLOR="#435e98" CREATED="1737048404898" ID="ID_1797698438" MODIFIED="1737048419616" TEXT="Tupel aus RegExp-Matches"/>
|
||||
</node>
|
||||
<node CREATED="1737048429831" ID="ID_1506892827" MODIFIED="1737048461620" TEXT="Kombinator per DSL">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1506892827" ENDARROW="Default" ENDINCLINATION="44;-70;" ID="Arrow_ID_283520954" SOURCE="ID_751583918" STARTARROW="None" STARTINCLINATION="-17;2;"/>
|
||||
<node COLOR="#435e98" CREATED="1737048429831" ID="ID_1506892827" MODIFIED="1737234341383" TEXT="Kombinator per DSL">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1506892827" ENDARROW="Default" ENDINCLINATION="44;-70;" ID="Arrow_ID_283520954" SOURCE="ID_751583918" STARTARROW="None" STARTINCLINATION="-64;7;"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1737234345007" ID="ID_710053406" MODIFIED="1737234350021" TEXT="Syntax erweitern"/>
|
||||
<node COLOR="#435e98" CREATED="1737234354774" ID="ID_118574311" MODIFIED="1737234357941" TEXT="Whitespace"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737234372227" ID="ID_943372204" MODIFIED="1737234378059" TEXT="Alternativ-Kombinator">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue