tag:forum.selfhtml.org,2005:/self Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? – SELFHTML-Forum 2021-02-19T02:34:16Z https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783878#m1783878 MB 2021-02-10T00:00:31Z 2021-02-10T00:00:31Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <p>ich will einen sehr sehr sehr simplen Text Format in ein array umwandeln</p> <p>der blaupausen Text:</p> <pre><code class="block"> Einkaufsliste: [Obst] * Aepfel * Birnen * Bananen [Gemuese] * Kartoffeln * Zwiebeln Den Schluessel Nicht vergessen! Fund: * 3 Gang * 2 Regal * 8 Fach Wertetabelle: Fett - 8,7 Kohlenhydrate - 80 </code></pre> <p>rauskommen soll sowas ein 2 Dimensionales Hashmap mit unterschiedlichem Inhalt:</p> <pre><code class="block language-php"><span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Einkaufsliste"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Obst"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token comment">// Liste</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"Aepfel"</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"Birne"</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"Banane"</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Gemuese"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token comment">// Liste</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"Kartoffeln"</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"Zwiebeln"</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token comment">// Text</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Den Schluessel Nicht vergessen!"</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Fund"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">""</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token comment">// Liste</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"3 Gang"</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"1 Regal"</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"8 Fach"</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Wertetabelle"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">""</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token comment">// Tabelle</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"Fett"</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"8.7%"</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string double-quoted-string">"kolenhydrate"</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"80%"</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> </code></pre> <p>Ich hab es seeehr statisch hinbekommen. Mein Script arbeitet maßgeblich mit mit Tabstopps und EOL, hat zur Überprüfung jeder Zeile gehäuft switch case verweise zu den funktionen die eine zeile funktionsspezifisch behandeln.</p> <p>Ich möchte es besser, kompetenter machen und hab dazu den Begriffen Tokenizer Lexer und Parser überflogen eben was so ein Compiler eben tut. Aber ich bezweifle stark, das ich einen Compiler für die trivialeste Dinge, wie meine Einkaufsliste, benötige um daraus ein hashmap zu machen.</p> <p>Ich benötige nur Theorie eines z.B. WYSIWYG-Editoren auf HTML Basis. Ist da win Präprozessor am Werk und wenn ja wie ist der Aufbau? Ähnlich wie bei Kompilern???</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783893#m1783893 Rolf B 2021-02-10T10:27:17Z 2021-02-10T10:27:17Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>Hallo MB,</p> <blockquote> <p>Ich benötige nur Theorie eines z.B. WYSIWYG-Editoren auf HTML Basis.</p> </blockquote> <p>Nein. Das ist kein WYSIWYG Editor. Es ist definitiv ein Parser.</p> <p>Lexer und Parser sind nur die halbe Miete. Je nach Syntax der verwendeten Notation braucht es danach noch semantische Interpretation.</p> <p>Man kann nun aufwändig eine EBNF-Grammatik formulieren, die deine "Sprache" definiert, und dafür dann einen Lexer und einen Parser bauen. Das geht, ich hab's auch mal angefangen, aber dann abgebrochen.</p> <p>Denn bei Dir ist es einfacher. Das Zeilenende ist ein eindeutiger Trenner, und du hast genau 6 Zeilentypen: Level-1 Key, Level-2 Key, Text, Listenpunkt, Tabellenzeile.</p> <p>Diese 6 Zeilentypen kannst Du recht gut mit Regexen erkennen und zerlegen. Das solltest Du im ersten Schritt tun, und basierend darauf ein Array aus Zeileninformationen erzeugen. Eine solche Zeileninformation besagt, was für ein Typ von Zeile das ist und welche relevanten Daten drinstehen (Key, Einrücktiefe bei Listen, Text-Array).</p> <p>Dieser Programmteil sollte noch nichts von der weiteren Struktur der Einkaufsliste wissen. Er hat nur seine 3 oder 4 Regexe, die Level-1 Key, Level-2 Key, Liste und Text/Tabellenzeile erkennen. Text und Tabellenzeile sind im Prinzip nur an der Anzahl der Texte unterscheidbar, deswegen bietet sich da eine gemeinsame Regex an und du prüfst nur, wieviele tab-getrennte Texte du darin gefunden hast. Je nachdem, welche Regex getroffen hat (oder ob es eine Leerzeile war) baust Du die entsprechene Zeileninformation auf und schiebst sie in ein Array. Punkt!</p> <p>Daraus baust Du ein Array aus Level-1 Einträgen auf. Ein solcher Eintrag besteht aus einem Key und einem Array aus Level-2 Einträgen. D.h. sobald Du einen neuen Level-1 Key findest, ist der Level-1 Eintrag, den Du gerade baust, fertig und Du beginnst einen neuen.</p> <p>In einem Level-2 Eintrag musst Du unterscheiden. Du kannst - wenn dein Beispiel vollständig ist - eine Liste finden, eine Wertetabelle oder Text. D.h. du musst prüfen, ob Du einen dieser drei Zeilentypen hast. Eventuell musst Du, wenn Du eine Zeile analysierst, auch berücksichtigen, in welchem Typ von Gruppe Du bist. In einer Punkteliste? Hab ich noch gar keine Liste? Das kann einfach oder kompliziert sein, je nachdem, welche Varianten du erlauben willst.</p> <p>Sicherlich sieht dein aktueller Code ähnlich aus, vermengt aber möglicherweise die Schritte 1 und 2 und verwendet vielleicht auch keine Regexe. Aber irgendwie muss die Programmstruktur die Struktur des Eingabedokuments wiederspiegeln, oder Du verwendest einen generischen Parser, der eine Grammatik vorgegeben bekommt. Dann ist die statische Struktur die Grammatik. Aber irgendwo muss die Definition der Struktur sein.</p> <p>Du könntest Dich auch mal mit YAML beschäftigen. Das ist deiner Einkaufsliste sehr ähnlich, und für YAML gibt es fertige Interpreter, die daraus ein Objekt machen, welches Du dann in einen JSON-String umwandeln kannst.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783895#m1783895 Raktenstartbeauftragter 2021-02-10T13:45:16Z 2021-02-10T13:45:16Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p><a href="https://yaml.org/" rel="nofollow noopener noreferrer">Ich würde anno 2020 über YAML nachdenken.</a></p> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783926#m1783926 1unitedpower 2021-02-11T11:40:31Z 2021-02-11T11:40:31Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <blockquote> <p>Ich möchte es besser, kompetenter machen und hab dazu den Begriffen Tokenizer Lexer und Parser überflogen eben was so ein Compiler eben tut.</p> </blockquote> <p>Da warst du schon in der richtigen Ecke unterwegs. Einen richtigen Lexer brauchst du nicht, den braucht man eigentlich nur, wenn die Sprache, die man parsen will, auch Schlüsselwörter wie "if", "while" und "for" benutzt. Ein Compiler ist auch zu viel des Guten, du brauchst lediglich einen Parser.</p> <p>Die Sprache, die du parsen möchtest, hat eine Besonderheit und ist deshalb auch nicht ganz so einfach zu behandeln, wie es den Anschein macht. Deine Sprache benutzt die Einrückungstiefe einer Zeile, um die Verschachtelungssruktur zu bestimmen. Die meisten Sprachen benutzen stattdessen Klammerpaare, wie "[]" oder "{}". In der Theorie sagt man, dass deine Sprache kontextsensitiv ist. Das macht das Parsen deutlich schwieriger. Da steckt also der Teufel in einem kleinen Detail.</p> <p>Grundsätzlich ist es meistens eine gute Idee das Problem, vor dem man steht, erstmal extrem zu vereinfachen und dafür eine Lösung zu finden. Also, lass uns doch erstmal einen einfachen Parser schreiben, der aus einem Text mit Zeileneinrückung ein verschachteltes Array macht. Der Einfachheit halber ignorieren wir auch erstmal Leerzeilen und Zeilen, die nur Tabs enthalten.</p> <h3>Outline</h3><p>Hier ist schonmal die grobe Rahmenstruktur für den Algorithmus, die Details müssen wir noch einfügen:</p> <pre><code class="block language-javascript"><span class="token keyword">const</span> <span class="token constant">TOKEN_TAB</span> <span class="token operator">=</span> <span class="token string">"\t"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">TOKEN_NEWLINE</span> <span class="token operator">=</span> <span class="token string">"\n"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">STATE_INDENTATION</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">STATE_CONTENT</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">input</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token constant">STATE_INDENTATION</span><span class="token punctuation">;</span> <span class="token comment">// TODO 1</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> char <span class="token keyword">of</span> input<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>state<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token constant">STATE_INDENTATION</span><span class="token operator">:</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>char<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token constant">TOKEN_TAB</span><span class="token operator">:</span> <span class="token comment">// TODO 2</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token constant">TOKEN_NEWLINE</span><span class="token operator">:</span> <span class="token comment">// TODO 3</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">default</span><span class="token operator">:</span> <span class="token comment">// TODO 4</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token constant">STATE_CONTENT</span><span class="token operator">:</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>char<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token constant">TOKEN_TAB</span><span class="token operator">:</span> <span class="token comment">// TODO 5</span> <span class="token keyword">case</span> <span class="token constant">TOKEN_NEWLINE</span><span class="token operator">:</span> <span class="token comment">// TODO 6</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">default</span><span class="token operator">:</span> <span class="token comment">// TODO 7</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// TODO 8</span> <span class="token punctuation">}</span> </code></pre> <ul> <li>Der Algorithmus durchläuft die Eingabe Zeichen für Zeichen, dafür ist die Schleife da.</li> <li>Wir unterscheiden nun zwei Zustände: Haben wir in der aktuell zu lesenden Zeile schon ein Symbol gelesen, dass kein Tab ist? Denn wenn das der Fall ist, lesen wir gerade richtigen Textinhalt. Ansonsten ermitteln wir noch die Verschachtelungsstruktur. Für diese Fallunterscheidung ist das äußere switch-Statement gedacht.</li> <li>Je nachdem, ob es sich bei dem gerade gelesenen Zeichen um einen Zeilenumbruch, ein Tab oder einen anderen Buchstaben handelt, ist eine andere Reaktion notwendig. Dafür sind die inneren switch-Statements da.</li> </ul> <p>Wir füllen jetzt nach und nach die Lücken.</p> <h3>Todo 1</h3><p>In die Lücke 1 kommen diverse Hilfsvariablen, die unser Algorithmus zum Arbeiten braucht.</p> <pre><code class="block language-javascript"><span class="token keyword">let</span> lineDepth <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> previousLineDepth <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> buffer <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">let</span> list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> stack <span class="token operator">=</span> <span class="token punctuation">[</span>list<span class="token punctuation">]</span><span class="token punctuation">;</span> </code></pre> <ul> <li>Die Variable <code>lineDepth</code> speichert die Einrückungstiefe der aktuell zu lesenden Zeile. Am Anfang einer Zeile (also wenn wir ein Zeilenumbruch gelesen haben) setzen wir die Variable auf 0. Und wir erhöhren Sie dann um 1 für jedes Tab, das wir am Zeileanfang lesen.</li> <li>Die Variable <code>previousLineDepth</code> speichert die Einrückungstiefe der zuletzt gelesenen Zeile. Wenn wir die beiden Variablen vergleichen, wissen wir, ob wir uns auf der selben Verschachtelungsebene wie in der Zeile zuvor befinden, ob wir tiefer gehen müssen, oder ob wir wieder eine oder mehrere Ebenen rauf gehen müssen.</li> <li>Die Variable <code>buffer</code> speichert den Textinhalt der aktuellen Zeile ohne die führenden Tabs. Am Zeilenanfang löschen wir den Inhalt. Und nachdem wir alle führenden Tabs gelesen haben, hängen wir Zeichen um Zeichen an diesen Buffer.</li> <li>Die Variable <code>list</code> speichert die aktuelle Liste, die wir bearbeiten.</li> <li>Die Variable <code>stack</code> speichert unfertige Listen, die wir noch nicht bis zum Ende gelesen haben. Immer, wenn wir festellen, dass wir uns eine Einrückungsebene tiefer befinden als in der Zeile zuvor, dann fangen eine neue Liste an und legen sie auf den Stack. Falls wir umgekehrt feststellen, dass wir uns eine Einrückungsebene über der zuletzt gelesenen Zeile gefinden, dann können wir die aktuelle Liste abschließen. D.h. wir nehmen sie vom dem Stack und fügen sie der Liste darunter als ein Listenelement hinzu.</li> </ul> <p>Dass ich diese Hilfsvariable brauche, wusste ich nicht von Anfang an. Das hat sich nach und nach ergeben, während ich mir um die einzelnen Fälle in den switch-Statements Gedanken gemacht habe. Deshalb war es wichtig erstmal den Rahmenalgorithmus vor mir zu sehen. Außerdem ist das nicht die einzige Wahl für Hilfsvariablen. Bspw. ist <code>previousLineDepth</code> eigentlich unnötig, weil die darin gespeicherte Information sich auch aus der Stack-Tiefe ableiten lässt. Ich fand es so aber besser verständlich, und hab die Hilfsvariable deshalb definiert.</p> <h3>TODO 2</h3><p>Der Zustand <code>STATE_INDENTATION</code> sagt uns, dass wir uns noch am Zeilenanfang befinden. Das aktuell gelesene Symbol ist ein Tab. Was müssen wir also machen?</p> <pre><code class="block language-javascript">lineDepth <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>lineDepth <span class="token operator">></span> previousLineDepth<span class="token punctuation">)</span> <span class="token punctuation">{</span> list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> stack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <ul> <li>Wir erhöhen erstmal die aktuelle Einrückungstiefe um 1.</li> <li>Dann überprüfen wir, ob wir uns nun eine Ebene tiefer befinden als zuvor. Wenn ja, dann machen wir eine neue Arbeitsliste auf und legen Sie oben auf den Stack.</li> </ul> <h3>TODO 3</h3><p>Der Zustand <code>STATE_INDENTATION</code> sagt uns, dass wir uns noch am Zeilenanfang befinden. Das aktuell gelesene Symbol ist ein Zeilenumbruch. Was müssen wir also machen?</p> <pre><code class="block language-javascript"><span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Unexepcted newline."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <ul> <li>Wie am Anfang geschrieben, wir ignorieren Leerzeilen und Zeilen, die nur aus Tabs bestehen. Wir produzieren deshalb nur einen Parse-Error.</li> </ul> <h3>TODO 4</h3><p>Der Zustand <code>STATE_INDENTATION</code> sagt uns, dass wir uns noch am Zeilenanfang befinden. Das aktuell gelesene Symbol ist kein Sonderzeichen. Was müssen wir also machen?</p> <pre><code class="block language-javascript"><span class="token keyword">while</span> <span class="token punctuation">(</span>lineDepth <span class="token operator"><</span> previousLineDepth<span class="token punctuation">)</span> <span class="token punctuation">{</span> previousLineDepth <span class="token operator">-=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> finishedList <span class="token operator">=</span> stack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> list <span class="token operator">=</span> stack<span class="token punctuation">[</span>stack<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>finishedList<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> buffer <span class="token operator">+=</span> char<span class="token punctuation">;</span> state <span class="token operator">=</span> <span class="token constant">STATE_CONTENT</span><span class="token punctuation">;</span> </code></pre> <ul> <li>Wir überprüfen zunächst, ob wir uns eine oder mehrere Ebenen über der Einrückungsstufe der zuletzt gelesen Zeile befinden. Das heißt, ob wir eine Ebene abschließen können. Für jede zu schließende Ebene vermindern wir zunächst die Variable <code>previousLineDepth</code>, wir nehmen die oberste Liste vom Stack und fügen sie der Liste darunter als Listenelement hinzu. Die Variable <code>previousLineDepth</code> hat in diesem Zusammenhang einen irreführenden Namen. Sie speichert eigentlich nur Anzahl der noch nicht abgeschlossenen Ebenen.</li> <li>Anschließend fügen wir das gerade gelesen Zeichen dem Textbuffer hinzu.</li> <li>Schlussendlich wechseln wir den internen Zustand unseres Parsers. Wir ermitteln nun nicht mehr die Verschatelungsebene, sondern lesen Textinhalt.</li> </ul> <h3>TOOD 5 und TODO 7</h3><p>Der Zustand <code>STATE_CONTENT</code> sagt uns, dass wir Textinhalt lesen. Das aktuell gelesene Symbol ist kein Zeilenumburch. Beachte, dass ein Tab in der Zeilenmitte auch kein Sonderzeichen ist. Wir können die Fälle 5 und 7 deshalb gleich behandeln. Was müssen wir also machen?</p> <pre><code class="block language-javascript">buffer <span class="token operator">+=</span> char<span class="token punctuation">;</span> </code></pre> <p>Wir fügen das atuell gelesene Zeichen dem Textbuffer hinzu, ansonsten müssen wir nichts unternehmen.</p> <h3>TODO 6</h3><p>Der Zustand <code>STATE_CONTENT</code> sagt uns, dass wir Textinhalt lesen. Das aktuell gelesene Symbol ist ein Zeilenumburch. Was müssen wir also machen?</p> <pre><code class="block language-javascript">previousLineDepth <span class="token operator">=</span> lineDepth<span class="token punctuation">;</span> lineDepth <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span> buffer <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> state <span class="token operator">=</span> <span class="token constant">STATE_INDENTATION</span><span class="token punctuation">;</span> </code></pre> <ul> <li>Wir setzen die Einrückungstiefe der vorherigen Zeile auf die Einrückungstiefe der aktuellen Zeile.</li> <li>Wir setzen die Einrückungstiefe der aktuellen Zeile zurück auf 0.</li> <li>Wir fügen den Textbuffer der aktuellen Arbeitsliste hinzu und löschen den Textbuffer.</li> <li>Wir wechseln wieder in den <code>STATE_INDENTATION</code>-Zustand.</li> </ul> <h3>TODO 8</h3><p>Wir sind nun den gesamten Eingabe-String durchlaufen. Wir müssen jetzt noch gucken, welche Hilfsvariablen noch unfertige Teilresultate erhalten und die zusammensetzen.</p> <pre><code class="block language-javascript">list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator"><</span> stack<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> finishedList <span class="token operator">=</span> stack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> list <span class="token operator">=</span> stack<span class="token punctuation">[</span>stack<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>finishedList<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> stack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <ul> <li>Wir führen nochmal die gleichen Schritte aus, die auch bei einem Zeilumbruch anfallen. Auf diese Weise schließen wir alle noch offenen Ebenen ab.</li> <li>Schlussendlich liegt unser Endergebnis als einziges Element auf dem Stack. Das geben wir jetzt zurück.</li> </ul> <h3>Zusammenfassung</h3><p>Den kompletten Algorithmus findest du inkl. einiger Tests auch bei <a href="https://stackblitz.com/edit/typescript-knexqj" rel="nofollow noopener noreferrer">Stackblitz</a>. Da fehlen natürlich noch etliche Details, die in deinem ursprünglichen Format vorgesehen waren, aber hier vernachlässigt werden. Ich würde an deiner Stelle damit beginnen, das Handling für Leerzeilen hinzuzufügen. Ich habe mir hier nur den kontextsenstiven Teil deines Problems rausgepickt, habe aber <a href="https://forum.selfhtml.org/self/2019/jun/20/bestimmte-sprache-aus-mehrsprachigem-string-filtern/1750862#m1750862" rel="noopener noreferrer">an andere Stelle</a> im Forum auch schon über kontextfreie Parser geschrieben.</p> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783896#m1783896 MB 2021-02-10T15:01:57Z 2021-02-10T15:01:57Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <p>ok schon mal echt herzlichen Dank zur Bstimmung meines Problemes! extrem blöderweise aber hat die Sprache keinen Regex - wird aber definitiv noch durch eine neuere Version kommen - und ich benötige diese lösung möglichst schnell aus meine fingern gesorgen.</p> <p>Ich schätze ich muss das allein durchstehen, aber deinen Rat beherzigen und gern aufnehmen, was du gesagt hast. Den ansatz habe ich ja bereits hinter mir wie du weist . Den source code werde ich auf GitHunb posten.</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783897#m1783897 Rolf B 2021-02-10T15:25:56Z 2021-02-10T15:31:29Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>Hallo MB,</p> <p>okay, wenn Du keine Regex hast, dann musst Du die Zeilentypen eben von Hand erkennen. Das lässt sich ja durch Aufsuchen von :, *, [ und ] ganz gut machen.</p> <p>Die Zweiteilung in "Zeileninfos bilden" und "Infos aggregieren" solltest Du auf jeden Fall einbauen.</p> <p>Welche Sprache ist das? Eine selbstgemachte? Oder was bekanntes?</p> <p>Ist das wirklich ein Einkaufszettel? Oder ist der nur ein Muster für das eigentliche Problem?</p> <p>Spricht irgendwas gegen YAML? Einen Parser dafür gibt's für <a href="https://yaml.org/" rel="nofollow noopener noreferrer">viele Sprachen</a>.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783898#m1783898 MB 2021-02-10T15:50:44Z 2021-02-10T15:50:44Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <blockquote> <p>okay, wenn Du keine Regex hast, dann musst Du die Zeilentypen eben von Hand erkennen. Das lässt sich ja durch Aufsuchen von :, *, [ und ] ganz gut machen.</p> </blockquote> <p>so habe ich es ja gemacht</p> <blockquote> <p>Die Zweiteilung in "Zeileninfos bilden" und "Infos aggregieren" solltest Du auf jeden Fall einbauen.</p> </blockquote> <p>das ebenfalls</p> <blockquote> <p>Welche Sprache ist das? Eine selbstgemachte? Oder was bekanntes?</p> </blockquote> <p>eigentlich sind es Script Header Kommentare die blöderweise mehr oder weitaus weniger einer Syntax folgen. Das sind eben die, die ich hier im Thread vorgestellt habe. Es gibt bloderweise aber massive Abweichungen .</p> <blockquote> <p>Ist das wirklich ein Einkaufszettel? Oder ist der nur ein Muster für das eigentliche Problem?</p> </blockquote> <p>Nur n Muster </p> <blockquote> <p>Spricht irgendwas gegen YAML? Einen Parser dafür gibt's für <a href="https://yaml.org/" rel="nofollow noopener noreferrer">viele Sprachen</a>.</p> </blockquote> <p>Das hat @Raketenstartbeauftrakter auch vorgeschlagen. Aber mit meinen Begründungen eher nich .</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783899#m1783899 Rolf B 2021-02-10T16:04:36Z 2021-02-10T16:04:36Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>Hallo MB,</p> <blockquote> <blockquote> <p>Welche Sprache ist das? Eine selbstgemachte? Oder was bekanntes?</p> </blockquote> </blockquote> <blockquote> <p>eigentlich sind es Script Header Kommentare</p> </blockquote> <p>Nee, in welcher Sprache programmierst Du das? Bestimmt nicht mit Header Kommentaren...</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783900#m1783900 MB 2021-02-10T16:32:23Z 2021-02-10T16:49:31Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <blockquote> <blockquote> <blockquote> <p>Welche Sprache ist das? Eine selbstgemachte? Oder was bekanntes?</p> </blockquote> </blockquote> <blockquote> <p>eigentlich sind es Script Header Kommentare</p> </blockquote> </blockquote> <blockquote> <p>Nee, in welcher Sprache programmierst Du das? Bestimmt nicht mit Header Kommentaren...</p> </blockquote> <p>Sry, habe ich vergessen zu erwähnen. Ich entwickle mit der proprietäre Scriptsprache von <a href="https://www.bohemia.net/" rel="nofollow noopener noreferrer">Bohemia Interactive Studios (BIS)</a> mit der Bezeichnung <a href="https://community.bistudio.com/wiki/SQF_syntax" rel="nofollow noopener noreferrer">SQF</a>.</p> <p>Mein Absicht ist eigentlich nicht für BIS gedacht aber ich entwickle…</p> <ol> <li>zum Zeitvertreib…</li> <li>ausfreude…</li> <li>um mich zu profilieren egal in welchem Code</li> <li>für die BIS community</li> </ol> <p>ich hoffe zu verstehst meine Intension.</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1783901#m1783901 MB 2021-02-10T19:18:27Z 2021-02-10T19:18:27Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <p>nebenbei bemerkt: Ein - oder DAS - Erzeugnis von BIS war damals der ausschlaggebende Grund dafür, warum ich so früh die Affinität (unteranderem über Editoren) zu Code entwickelt habe .</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1784032#m1784032 MB 2021-02-13T00:06:20Z 2021-02-13T00:11:45Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <blockquote> <blockquote> <p>Ich möchte es besser, kompetenter machen und hab dazu den Begriffen Tokenizer Lexer und Parser überflogen eben was so ein Compiler eben tut.</p> </blockquote> </blockquote> <blockquote> <p>Da warst du schon in der richtigen Ecke unterwegs.</p> </blockquote> <p>perfekt </p> <blockquote> <p>Einen richtigen Lexer brauchst du nicht […] du brauchst lediglich einen Parser.</p> </blockquote> <p>ok?</p> <blockquote> <p>[…]. Deine Sprache benutzt die Einrückungstiefe einer Zeile. […] In der Theorie sagt man, dass deine Sprache kontextsensitiv ist.</p> </blockquote> <p>euer wissen möchte ich gerne haben .</p> <blockquote> <p>[…] Das macht das Parsen deutlich schwieriger.</p> </blockquote> <p>Das was ich als beispiel geschrieben habe habe ich schon geparset, aber unschön und nicht gegliedert.</p> <blockquote> <p>Grundsätzlich ist es meistens eine gute Idee das Problem, vor dem man steht, erstmal extrem zu vereinfachen und dafür eine Lösung zu finden. […]</p> </blockquote> <p>Dann hatte ich wohl nix falsches im sinn gehabt . Genauso habe ich es gemacht, aber mich nur mit der zweiten einrücktungstiefe beschränkt. Hilfsvariablen benötige ich keine, da ich das alles über eine rekursive funktion gelöst hab, die nichts zurück gibt und einen string extern behandelt. So kann man bis ins <em>n</em>-te hinein verschachteln. Ich weis aber nicht ob's gut ist .</p> <blockquote> <p>[…]. Ich würde an deiner Stelle damit beginnen, das Handling für Leerzeilen hinzuzufügen.</p> </blockquote> <p>Ich müsste zunächst alle anderen non-printable characters ansehen</p> <pre><code class="block"><end> --->Title:<end> --->--->-.listpoint<end> <end> --->--->Definition:--->{--->*}Description<end> <end> --->--->collum.1--->{--->*}-.collum.2<end> <end> </code></pre> <p><strong>Legende</strong></p> <ul> <li><code>.</code> steht für Leerzeichen</li> <li><code><end></code> steht für Zeilenumbruch</li> <li><code>---></code> steht für Tabulator</li> <li><code>[character*]</code> steht für Zeichen <em>n</em> mal</li> </ul> <blockquote> <p>Ich habe mir hier nur den kontextsenstiven Teil deines Problems rausgepickt, habe aber <a href="https://forum.selfhtml.org/self/2019/jun/20/bestimmte-sprache-aus-mehrsprachigem-string-filtern/1750862#m1750862" rel="noopener noreferrer">an andere Stelle</a> im Forum auch schon über kontextfreie Parser geschrieben.</p> </blockquote> <p>schaue ich mir sehr gern an - aber heute, nicht gestern .</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div> https://forum.selfhtml.org/self/2021/feb/10/strukturierter-klartext-zu-array-mit-compiler-oder-praprozessor/1784506#m1784506 MB 2021-02-19T02:34:16Z 2021-02-19T02:34:16Z Strukturierter Klartext zu Array mit Compiler oder Präprozessor??? <p>moin,</p> <blockquote> <blockquote> <p>Ich möchte es besser, kompetenter machen und hab dazu den Begriffen Tokenizer Lexer und Parser überflogen eben was so ein Compiler eben tut.</p> </blockquote> <p>Da warst du schon in der richtigen Ecke unterwegs. Einen richtigen Lexer brauchst du nicht, den braucht man eigentlich nur, wenn die Sprache, die man parsen will, auch Schlüsselwörter wie "if", "while" und "for" benutzt.</p> </blockquote> <p>Ich hab jetzt ne konzeptionelle Idee von <strong>Tokenizer</strong> und <strong>Parser</strong>. Melde mich hoffentlich mit meinem sehr trivialen Parser im <strong>SQF</strong> Format auf <a href="https://github.com/" rel="noopener noreferrer">GitHub</a> wieder .</p> <p>lgmb</p> <div class="signature">-- <br> Sprachstörung </div>