Discussion:
State Machine Compiler für 8-bit AVRs?
Add Reply
Andreas Weber
2019-09-21 09:29:06 UTC
Antworten
Permalink
Hallo an alle,

ich verwende seit knapp 4 Jahren immer wieder den Ragel [1] Generator
für Parser auf Atmel/Microchip AVRs z.B. für UART Empfangsroutinen.

Was verwendet ihr so, sobald die Grammatik etwas komplizierter wird? Lex
wäre ja auch eine Möglichkeit.

TIA, Gruß Andy

[1] https://www.colm.net/open-source/ragel/
Hans-Peter Diettrich
2019-09-21 10:26:03 UTC
Antworten
Permalink
Post by Andreas Weber
Hallo an alle,
ich verwende seit knapp 4 Jahren immer wieder den Ragel [1] Generator
für Parser auf Atmel/Microchip AVRs z.B. für UART Empfangsroutinen.
Was verwendet ihr so, sobald die Grammatik etwas komplizierter wird? Lex
wäre ja auch eine Möglichkeit.
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk. C verfügt ja bereits über Konvertierungsroutinen,
und wenn sich beide Seiten an diese halten, und sinnvolle Trennzeichen
zwischen zwei Werten und Records einstreuen, wo sollten dann Probleme
herkommen?

DoDi
Andreas Weber
2019-09-21 17:09:12 UTC
Antworten
Permalink
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Post by Hans-Peter Diettrich
und wenn sich beide Seiten an diese halten, und sinnvolle Trennzeichen
zwischen zwei Werten und Records einstreuen,
Dazu müsste man beide Seiten selbst in der Hand haben. Sobald du an ein
bestehendes Protokoll ran musst, kann man sich das nicht mehr aussuchen.

-- Andy
Hergen Lehmann
2019-09-21 18:37:05 UTC
Antworten
Permalink
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Eine komplizierte Grammatik ist in jedem Fall kompliziert, egal welche
Werkzeuge man nutzt.

Wenn man das Prinzip verstanden hat, ist der Aufwand, um eine formal
korrekte Definition für einen Parser-Generator zu schreiben oder den
Parser gleich selbst zu schreiben, nicht sooo unterschiedlich.
Das gilt umso mehr dann, wenn der vom Generator erzeugte Codestil nicht
recht in die verwendete Umgebung passt und man auch noch eine
Interface-Schicht bauen müsste.

Hergen
Andreas Weber
2019-09-22 10:48:26 UTC
Antworten
Permalink
Hallo Hergen,
Post by Hergen Lehmann
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Eine komplizierte Grammatik ist in jedem Fall kompliziert, egal welche
Werkzeuge man nutzt.
Warum versuchen mich hier Leute davon zu überzeugen KEIN Werkzeug dafür
einzusetzen?

Das fühlt sich für mich an als ob mir jemand erklärt:
"Verwende doch Assembler, mach BRAUCHT keinen C Compiler. Das geht auch
alles so. Die libc braucht man nicht, kann man auch in Assembler
machen." Ich hoffe wir müssen an dieser Stelle nun keine Diskussion
führen, warum man heute eben nicht mehr Assembler schreiben sollte ohne
einen wirklich, wirklich guten Grund.
Post by Hergen Lehmann
Wenn man das Prinzip verstanden hat, ist der Aufwand, um eine formal
korrekte Definition für einen Parser-Generator zu schreiben oder den
Parser gleich selbst zu schreiben, nicht sooo unterschiedlich.
Ich habe über 10 Jahre die Parser selbst geschrieben. Mit Ragel kann ich
mir den Zustandsautomaten visualisieren lassen (graphviz dot) was die
Entwicklung deutlich vereinfacht und gleich noch als Dokumentation
taugt. Die Lesbarkeit und damit die Wartbarkeit für andere ist IMHO auch
deutlich höher.
Post by Hergen Lehmann
Das gilt umso mehr dann, wenn der vom Generator erzeugte Codestil nicht
recht in die verwendete Umgebung passt und man auch noch eine
Interface-Schicht bauen müsste.
Klar. In dem von mir angesprochenen Fall integriert sich das aber super
in avr-gcc und AVR libc.


Ich fühle mich an die Diskussion mit Studenten erinnert, dass man
git/mercurial/subversion gar nicht braucht, weil man ja die Order
einfach wegkopieren und umbenennen kann.

Danke für deine Meinung, Gruß Andy
olaf
2019-09-22 11:27:28 UTC
Antworten
Permalink
Post by Andreas Weber
Warum versuchen mich hier Leute davon zu überzeugen KEIN Werkzeug dafür
einzusetzen?
Vermutlich weil es denen zu komplex ist. :-)

Ich hab fuer solche Anwendungen auf Microcontrollern auch schon flex
genutzt und wuerde es jederzeit wieder machen.

Vorteile:
Sehr flexibel, es ist eine kleinigkeit da mal eben einen
neues Kommando hinzuzufuegen.

Weil die nutzung so einfach ist, wenn man einmal damit umgehen kann,
nutzt man es auch fuer Kleinigkeiten (z.B Debuginterface) wo man sonst
eher denken wuerde: "Och, noe, dafuer bin ich jetzt zu faul"

Nachteile: Erzeugt ziemlich grossen C-Source. Das bekommt man von
Hand bestimmt effizienter hin. Allerdings ist das bei den
fetten Flash heutiger Controller kein Problem.
Post by Andreas Weber
taugt. Die Lesbarkeit und damit die Wartbarkeit für andere ist IMHO auch
deutlich höher.
Nicht zwangslaeufig weil die sich ja auch mit dem verwendeten
Generator auskennen muessen und ihn auch haben muessen.


Olaf
Johannes Bauer
2019-09-22 15:23:26 UTC
Antworten
Permalink
Post by Andreas Weber
Post by Hergen Lehmann
Post by Andreas Weber
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Eine komplizierte Grammatik ist in jedem Fall kompliziert, egal welche
Werkzeuge man nutzt.
Warum versuchen mich hier Leute davon zu überzeugen KEIN Werkzeug dafür
einzusetzen?
Kann ich dir nicht beantworten.

Was genau stört dich denn an der Ragel-Syntax bzw. was für Features
hättest du gerne, die im Moment fehlen? Kannst du eventuell eine
Beispielgrammatik teilen um zu illustrieren, wie du es im Moment (als
Workaround) löst und was du gerne hättest?

Eventuell kommen dann bessere Tipps.
Viele Grüße,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Andreas Weber
2019-09-23 18:15:56 UTC
Antworten
Permalink
Hi Johannes,
Post by Johannes Bauer
Post by Andreas Weber
Post by Hergen Lehmann
Post by Andreas Weber
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Eine komplizierte Grammatik ist in jedem Fall kompliziert, egal welche
Werkzeuge man nutzt.
Warum versuchen mich hier Leute davon zu überzeugen KEIN Werkzeug dafür
einzusetzen?
Kann ich dir nicht beantworten.
Was genau stört dich denn an der Ragel-Syntax bzw. was für Features
hättest du gerne, die im Moment fehlen?
Ich bin bisher mit Ragel wirklich voll und ganz zufrieden und kann
bisher alles damit abbilden was ich möchte. Wollte eigentlich nur
wissen, was andere so verwenden. Dass das in so eine "angeregte
Diskussion" ausufert, hätte ich nicht gedacht.

Danke, Gruß Andy
Stefan Reuther
2019-09-22 08:48:04 UTC
Antworten
Permalink
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Auch bei komplexeren Grammatiken ist das kein Hexenwerk.

Je nach dem, was für ein Protokoll das ist, will man da auch sowas wie
Fehlerbehandlung haben. Wenn also irgendwo ein Trennzeichen verschluckt
wird, soll der Parser sich davon erholen können und nicht nur "parse
error" sagen und bis zum nächsten Powercycle bockig sein. Das in einer
Grammatik auszudrücken ist zwar möglich, aber umständlich. Mit einem
eigenen Parser hat man da durchaus einfachere Möglichkeiten (und sei es
sowas wie "mit dem eigenen Parser die Paketierung zerlegen, und die
Paket-Payloads dann mit was generiertem").


Stefan
Hans-Peter Diettrich
2019-09-22 10:55:58 UTC
Antworten
Permalink
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Wäre C kompliziert genug?

Anscheinend werden nur LL(1) Grammatiken akzeptiert, und für die läßt
sich ein Lexer von Hand leicht erzeugen. Bei wirklich komplizierten
Grammatiken sind ggf. Umformungen notwendig, die nur jemand durchführen
kann, der sich mit Grammatiken so gut auskennt daß er weiß, wie ein
Parser funktioniert und ihn entsprechend auch selbst schreiben kann.

DoDi
Johannes Bauer
2019-09-22 15:32:27 UTC
Antworten
Permalink
Post by Hans-Peter Diettrich
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Wäre C kompliziert genug?
Wenn *das* stimmen würde, dann würde ich das gerne mal sehen. Denn eine
vollständige, fehlerfreie C-Grammatik "von Hand" zu schreiben, ohne
Werkzeugunterstützung, halte ich für so gut wie unmöglich. Insofern,
wenn du das wirklich gemacht hast, würde ich das gerne von dir lernen.
Deine Chance, dein Können unter Beweis zu stellen.

Meine persönliche Vermutung, die sich mit deinen bisherigen Äußerungen
allerdings viel besser deckt, ist, dass das lediglich pures Geschwätz
ist. Vermutlich hast du einen Parser für urgendein Subset von C
geschrieben, der bei jeder minimalen Deviation im Codestil schon
krachend auseinanderfällt.
Post by Hans-Peter Diettrich
Anscheinend werden nur LL(1) Grammatiken akzeptiert, [...]
C ist defintiv kein LL(1), das weißt du ja sicherlich.

Gruß,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Gerhard Hoffmann
2019-09-22 18:43:33 UTC
Antworten
Permalink
Post by Johannes Bauer
Post by Hans-Peter Diettrich
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Wäre C kompliziert genug?
Wenn *das* stimmen würde, dann würde ich das gerne mal sehen. Denn eine
vollständige, fehlerfreie C-Grammatik "von Hand" zu schreiben, ohne
Werkzeugunterstützung, halte ich für so gut wie unmöglich. Insofern,
wenn du das wirklich gemacht hast, würde ich das gerne von dir lernen.
Deine Chance, dein Können unter Beweis zu stellen.
Meine persönliche Vermutung, die sich mit deinen bisherigen Äußerungen
allerdings viel besser deckt, ist, dass das lediglich pures Geschwätz
ist. Vermutlich hast du einen Parser für urgendein Subset von C
geschrieben, der bei jeder minimalen Deviation im Codestil schon
krachend auseinanderfällt.
Post by Hans-Peter Diettrich
Anscheinend werden nur LL(1) Grammatiken akzeptiert, [...]
C ist defintiv kein LL(1), das weißt du ja sicherlich.
Gruß,
Johannes
Pascal-Compiler waren schon immer mit rekursivem Abstieg, und
sogar der gcc war nur bis Version 3 yacc/bison-basiert und hat
jetzt einen handgeschnitzten Parser.

Wenn's praktisch alle so machen, dann muss es wohl möglich sein;
das mit dem leeren Geschwätz ist also ein Bumerang.

Dass man für ernsthafte Sprachen die Symboltabelle massieren muss,
ist unschön, aber wirklich context-frei ist in der Praxis wenig.

Was ist foo *bar? Eine Variablen-Deklaration? Eine Multiplikation?

Ausführliche Diskussion in :

<
https://stackoverflow.com/questions/6319086/are-gcc-and-clang-parsers-really-handwritten
Gruß, Gerhard
Johannes Bauer
2019-09-22 19:10:50 UTC
Antworten
Permalink
Post by Gerhard Hoffmann
Pascal-Compiler waren schon immer mit rekursivem Abstieg, und
sogar der gcc war nur bis Version 3 yacc/bison-basiert und hat
jetzt einen handgeschnitzten Parser.
Weil sie den C und C++ gemerged haben. Und C++ /hat/ keine
wohldefinierte Grammatik mehr. Ist also wirklich schwierig, dafür einen
Parser zu schreiben. Das sind unter anderem, nur für den Parser, etwa
41000 Zeilen Code, mehr als ein Megabyte Quellcode. Das ist also etwas,
das nicht mal eben so hinzuschreiben ist.
Post by Gerhard Hoffmann
Wenn's praktisch alle so machen, dann muss es wohl möglich sein;
das mit dem leeren Geschwätz ist also ein Bumerang.
Insofern stehe ich zu meiner Aussage und widerspreche, dass es
"praktische alle" eben mit handgeschnitzten Parsern machen. Im
Gegenteil, wenn du mal suchst:

https://github.com/SilverScar/C-Language-Parser
Ist Lex/Yacc-basiert

https://github.com/eliben/pycparser
Nutzt ply

https://github.com/praeclarum/CLanguage
Nutzt jay

https://github.com/awi29/C-parser
Nutzt Lex/Yacc

https://github.com/vickenty/lang-c
Nutzt rustpeg

Die Wenigsten schreiben also einen Lexer/Parser "von Hand". Noch
weniger, wenn es keinen triftigen Grund dafür gibt (bei GCC ist
wiegesagt C++ der Grund).
Post by Gerhard Hoffmann
Dass man für ernsthafte Sprachen die Symboltabelle massieren muss,
ist unschön, aber wirklich context-frei ist in der Praxis wenig.
Was ist  foo *bar?  Eine Variablen-Deklaration? Eine Multiplikation?
Ich habe ja schon geschrieben, C ist kein LL(1). Keine mir bekannte
(nicht-esoterische) Programmiersprache ist LL(1), so nebenbei.

Gruß,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Hans-Peter Diettrich
2019-09-22 22:34:35 UTC
Antworten
Permalink
Post by Johannes Bauer
Post by Hans-Peter Diettrich
Post by Andreas Weber
Post by Hans-Peter Diettrich
Meine Lexer und Parser habe ich bisher immer selbst geschrieben, das ist
IMO kein Hexenwerk.
Dann hast du bis jetzt vielleicht keine komplizierte Grammatik gehabt.
Wäre C kompliziert genug?
Wenn *das* stimmen würde, dann würde ich das gerne mal sehen. Denn eine
vollständige, fehlerfreie C-Grammatik "von Hand" zu schreiben, ohne
Werkzeugunterstützung, halte ich für so gut wie unmöglich. Insofern,
wenn du das wirklich gemacht hast, würde ich das gerne von dir lernen.
Deinem Geschwätz nach kommen mir Zweifel an Deiner Lernfähigkeit :-(
Post by Johannes Bauer
Deine Chance, dein Können unter Beweis zu stellen.
Hatte ich seinerzeit als "ToPas" bei SourceForge reingestellt.
Post by Johannes Bauer
Meine persönliche Vermutung, die sich mit deinen bisherigen Äußerungen
allerdings viel besser deckt, ist, dass das lediglich pures Geschwätz
ist.
Dein Vermutungslevel ist als unbrauchbar notiert. Vielleicht informierst
Du Dich mal über den VisualBasic Discompiler zur Justierung Deiner Meinung.
Post by Johannes Bauer
Vermutlich hast du einen Parser für urgendein Subset von C
geschrieben, der bei jeder minimalen Deviation im Codestil schon
krachend auseinanderfällt.
Auch hier ist das Gegenteil der Fall. Mein Parser hat aufgedeckt, daß
Microsofts Header zu Visual C nicht standardardkonform sind, ein
Workaround wurde eingebaut. Dazu noch ein paar Erweiterungen für gcc.
Post by Johannes Bauer
Post by Hans-Peter Diettrich
Anscheinend werden nur LL(1) Grammatiken akzeptiert, [...]
C ist defintiv kein LL(1), das weißt du ja sicherlich.
Bis auf 1 Ausnahme ist C98 erstaunlicherweise LL(1), insgesamt also
LL(2). Das Fehlen einer offiziellen LL-Grammatik sagt ja definitiv
nichts über eine Sprache aus :-]

DoDi
Johannes Bauer
2019-09-23 07:12:55 UTC
Antworten
Permalink
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Deine Chance, dein Können unter Beweis zu stellen.
Hatte ich seinerzeit als "ToPas" bei SourceForge reingestellt.
Sehr gut. Endlich lieferst du mal was. Ich habe mal meine VM angeworfen
und dein Meisterwerk getestet:

https://imgur.com/a/McpnjZb

Schon beim einfachen Gerumklicken fliegen einem "Access Violations" nur
so um die Ohren, dass es kracht! Das fand ich MEGA witzig, weil du ja,
in deiner ach so oberlehrerhaften Art, ja kürzlich erst von Korrektheit
von Programmen geschwafelt hast und Pascal über C erhoben. Genau die
Bugs, die du angeblich durch Pascal vermeidest hast du offenbar so
dutzendfach in deinem Programmchen drin, dass es UNBENUTZBAR wird. Sehr
hübsche Demonstration, den Screenshot sollte man sich einrahmen.

Danach nochmal neugestartet, nichtdeterminsitisch fliegt einem eine
Access Violation schon beim BLOSSEN START des Programms um die Ohren.
Gacker! Ist das eine neue Form nichtdeterministischer Programmierung?
Wow, ich bin echt beeindruckt.

Aber zum Kernstück. Deinem Parser, der ja, wir errinern uns an meine
Post by Hans-Peter Diettrich
eine vollständige, fehlerfreie C-Grammatik "von Hand" zu schreiben,
ohne Werkzeugunterstützung, halte ich für so gut wie unmöglich
Keywords für dich, DoDi, zum mitschreiben:
- vollständig
- fehlerfrei

Okay, okay, das ist also die Messlatte. Siebenzeiler in C:

int foo(int y, ...) {
int *x[12];
x[3] = x[9];
x[10] = *(&(*(x + 3)));
"foo";
return 0;
}

Einfach, oder? Das ist korrektes C. Na dann!

*TOMMELWIRBEL*

error translation_unit

<loriot>Ach!</loriot>

Wer hätte das gedacht, DoDi? Dass es richtig schwer ist, eine
fehlerfreie Grammatik hinzukriegen? Danke, dass du das schön bewiesen hast.

Das ist genau der Grund, warum man Parser Generatoren erfunden hat, weil
es Leute gibt, denen aufgefallen ist, dass einem Menschen halt
Cornercases oft durch die Lappen gehen. So wie dir.
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Meine persönliche Vermutung, die sich mit deinen bisherigen Äußerungen
allerdings viel besser deckt, ist, dass das lediglich pures Geschwätz
ist.
Dein Vermutungslevel ist als unbrauchbar notiert.
Bestätigt, wolltest du schreiben. Siehe oben.
Post by Hans-Peter Diettrich
Vielleicht informierst
Du Dich mal über den VisualBasic Discompiler zur Justierung Deiner Meinung.
Ja sorry aber "VisualBasic Discompiler" ist offenbar so ein
unbrauchbarer Suchbegriff, dass Google gleich sagt: "Showing results for
Visual Basic Decompiler"

Ich habe also keine Ahnung, worauf du hinaus willst. Du aber offenbar
auch nicht, sondern willst ja wohl nur von deinem Turbofail ablenken.
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Vermutlich hast du einen Parser für urgendein Subset von C
geschrieben, der bei jeder minimalen Deviation im Codestil schon
krachend auseinanderfällt.
Auch hier ist das Gegenteil der Fall.
Ähm, kracht bei einem Siebenzeiler auseinander. Hat micht genau FÜNF
Minuten gebraucht, den Testcase zu finden. Ich habe mehr Zeit damit
verbracht, die Screenshots im Gimp zu editieren, als damit, dir
Stümperei nachzuweisen.
Post by Hans-Peter Diettrich
Mein Parser hat aufgedeckt, daß
...das händische Schreiben korrekter, vollständiger Parser richtig
schwer ist.
Post by Hans-Peter Diettrich
Post by Johannes Bauer
C ist defintiv kein LL(1), das weißt du ja sicherlich.
Bis auf 1 Ausnahme ist C98 erstaunlicherweise LL(1),
C ist also kein LL(1), richtig.

Immerhin, muss man dir zu Gute halten, hast du ausnahmsweise was
geliefert, statt immer nur heiße Luft zu produzieren. Auch wenn es jetzt
halt nicht dein Argument gestärkt hat, sondern exakt das Gegenteil bewiesen.

Gruß,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Gerhard Hoffmann
2019-09-23 12:15:25 UTC
Antworten
Permalink
Post by Johannes Bauer
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Deine Chance, dein Können unter Beweis zu stellen.
Hatte ich seinerzeit als "ToPas" bei SourceForge reingestellt.
Sehr gut. Endlich lieferst du mal was. Ich habe mal meine VM angeworfen
https://imgur.com/a/McpnjZb
Schon beim einfachen Gerumklicken fliegen einem "Access Violations" nur
so um die Ohren, dass es kracht! Das fand ich MEGA witzig, weil du ja,
in deiner ach so oberlehrerhaften Art, ja kürzlich erst von Korrektheit
von Programmen geschwafelt hast und Pascal über C erhoben. Genau die
Bugs, die du angeblich durch Pascal vermeidest hast du offenbar so
dutzendfach in deinem Programmchen drin, dass es UNBENUTZBAR wird. Sehr
hübsche Demonstration, den Screenshot sollte man sich einrahmen.
Danach nochmal neugestartet, nichtdeterminsitisch fliegt einem eine
Access Violation schon beim BLOSSEN START des Programms um die Ohren.
Gacker! Ist das eine neue Form nichtdeterministischer Programmierung?
Wow, ich bin echt beeindruckt.
Aber zum Kernstück. Deinem Parser, der ja, wir errinern uns an meine
Post by Hans-Peter Diettrich
eine vollständige, fehlerfreie C-Grammatik "von Hand" zu schreiben,
ohne Werkzeugunterstützung, halte ich für so gut wie unmöglich
- vollständig
- fehlerfrei
int foo(int y, ...) {
int *x[12];
x[3] = x[9];
x[10] = *(&(*(x + 3)));
"foo";
return 0;
}
Einfach, oder? Das ist korrektes C. Na dann!
*TOMMELWIRBEL*
error translation_unit
<loriot>Ach!</loriot>
Wer hätte das gedacht, DoDi? Dass es richtig schwer ist, eine
fehlerfreie Grammatik hinzukriegen? Danke, dass du das schön bewiesen hast.
Das ist genau der Grund, warum man Parser Generatoren erfunden hat, weil
es Leute gibt, denen aufgefallen ist, dass einem Menschen halt
Cornercases oft durch die Lappen gehen. So wie dir.
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Meine persönliche Vermutung, die sich mit deinen bisherigen Äußerungen
allerdings viel besser deckt, ist, dass das lediglich pures Geschwätz
ist.
Dein Vermutungslevel ist als unbrauchbar notiert.
Bestätigt, wolltest du schreiben. Siehe oben.
Post by Hans-Peter Diettrich
Vielleicht informierst
Du Dich mal über den VisualBasic Discompiler zur Justierung Deiner Meinung.
Ja sorry aber "VisualBasic Discompiler" ist offenbar so ein
unbrauchbarer Suchbegriff, dass Google gleich sagt: "Showing results for
Visual Basic Decompiler"
Ich habe also keine Ahnung, worauf du hinaus willst. Du aber offenbar
auch nicht, sondern willst ja wohl nur von deinem Turbofail ablenken.
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Vermutlich hast du einen Parser für urgendein Subset von C
geschrieben, der bei jeder minimalen Deviation im Codestil schon
krachend auseinanderfällt.
Auch hier ist das Gegenteil der Fall.
Ähm, kracht bei einem Siebenzeiler auseinander. Hat micht genau FÜNF
Minuten gebraucht, den Testcase zu finden. Ich habe mehr Zeit damit
verbracht, die Screenshots im Gimp zu editieren, als damit, dir
Stümperei nachzuweisen.
Post by Hans-Peter Diettrich
Mein Parser hat aufgedeckt, daß
...das händische Schreiben korrekter, vollständiger Parser richtig
schwer ist.
Post by Hans-Peter Diettrich
Post by Johannes Bauer
C ist defintiv kein LL(1), das weißt du ja sicherlich.
Bis auf 1 Ausnahme ist C98 erstaunlicherweise LL(1),
C ist also kein LL(1), richtig.
Immerhin, muss man dir zu Gute halten, hast du ausnahmsweise was
geliefert, statt immer nur heiße Luft zu produzieren. Auch wenn es jetzt
halt nicht dein Argument gestärkt hat, sondern exakt das Gegenteil bewiesen.
Wenn hier einer den Oberlehrer macht, dann du.
Und er muss dir auch nichts liefern, du hast nichts bei ihm gekauft.
Post by Johannes Bauer
*TOMMELWIRBEL*
Wirklich bewiesen hast du garnix. Du hast ein paar Exotencompiler
aufgezählt die einen Parsergenerator benutzen, aber die wichtigen
Compiler, die jeder hernimmt, wie gcc oder clang benutzen rekursiven
Abstieg. Und der gcc frisst dein Beispiel in einer halben Millisekunde,
problemlos, bis auf ein paar Bemerkungen, dass das Beispiel nix
Sinnvolles macht.

Pascal nimmt auch rekursiven Abstieg. Und da sind Bösartigkeiten
wie das with-statement drinnen:

with record_variablenliste do begin ... end

und zwischen begin & end sind die Komponenten der records plötzlich
keine rec.a und rec.b mehr, sondern einfach nur noch a und b.
Wenn's zufällig globale a und b gab, dann gibt's die eben vorrübergehend
nicht mehr. Bring das mal einem Parsergenerator nahe, wenn Variablen-
namen eben zwischendurch für etwas völlig anderes mit möglicherweise
einem anderen Typ stehen.

In Jensen-Wirth's Pascal, User Manual and Report (insgesamt ein
beeindruckend dünnes Heftchen für seine Wichtigkeit) ist im Anhang
die ganze Grammatik in BNF und die Blasendiagramme für den Parser
drinnen.

Und das ganze UCSD-Pascalsystem konnte man auf einem Z80 mit
AT-Floppies compilieren.

Ja, für den SCPI-Parser auf dem BeagleBoneBlack nehme ich
schon den yacc/bison und gcc. Für jeden Topf den passenden Deckel.

Gerhard
Johannes Bauer
2019-09-23 12:31:08 UTC
Antworten
Permalink
Post by Gerhard Hoffmann
Und er muss dir auch nichts liefern, du hast nichts bei ihm gekauft.
Wenn jemand groß Sprüche klopft, wie einfach das doch alles von Hand
sei, Lexer/Parser für komplexe Grammatiken zu schreiben (zum Beispiel
der von C), und dann in der Praxis halt schon bei simpelsten Beispielen
voll auf die Nase fliegt, dann ist das ja schon ein interessantes Ergebnis.

Klar muss er nichts liefern, hat er ja bisher auch nie. Sobald es
konkret wird, immer schön kneifen. Typisch Schäwtzer eben.
Post by Gerhard Hoffmann
Post by Johannes Bauer
*TOMMELWIRBEL*
Wirklich bewiesen hast du garnix.
Doch, dass der Parser, den DoDi geschrieben hat, eben nur (wie ich
ursprünglich vermutet hatte) ein (beliebiges) Subset von C parst. Wenn
du das bestreitest, kannst du es ja gerne selber ausprobieren.
Post by Gerhard Hoffmann
Du hast ein paar Exotencompiler
aufgezählt die einen Parsergenerator benutzen,
Das sind keine Compiler, hast du die Links mal angesehen? Die erzeugen
teilweise nur einen AST und sind Libraries.
Post by Gerhard Hoffmann
aber die wichtigen
Compiler, die jeder hernimmt, wie gcc oder clang benutzen rekursiven
Abstieg.
Das ist *professionelle* Software. Mit hunderttausenden Personenstunden,
die da reingeflossen sind, sowohl in clang als auch in gcc. Und ich habe
ausführlich beschrieben, warum die das so machen -- sowohl clang als
auch gcc parsen eben auch C++, für das es keine ausdefinierte Grammatik
gibt (als Bonus gibt's bessere Diagnostics dazu). Insofern sind die als
Beispiel *völlig* ungeeignet, denn es ging grundsätzlich darum, ob und
wie schwierig es ist, Lexer/Parser von Hand zu schreiben.

Ohne Not schreibt *niemand* einen Parser von Hand, auch nicht gcc und
clang. Und wenn man sich dazu entscheidet, ist das *weitaus*
schwieriger, als einen Parsergenerator zu nehmen.
Post by Gerhard Hoffmann
Pascal nimmt auch rekursiven Abstieg. Und da sind Bösartigkeiten
with record_variablenliste do begin ... end
und zwischen begin & end sind die Komponenten der records plötzlich
keine  rec.a und rec.b mehr, sondern einfach nur noch a und b.
Wenn's zufällig globale a und b gab, dann gibt's die eben vorrübergehend
nicht mehr. Bring das mal einem Parsergenerator nahe, wenn Variablen-
namen eben zwischendurch für etwas völlig anderes mit möglicherweise
einem anderen Typ stehen.
Ich weiß echt nicht, wieso du ständig mit Pascal anfängst, das hat mit
dem Thema überhaupt nichts zu tun. Ich habe nie bestritten, dass
Recursive Descent ein ordentliches oder geeignetes Parsing-Verfahren
ist. Ich sage lediglich, dass das Schreiben eines Parsers von Hand
RICHTIG viel schwieriger ist, als einen Parsergenerator zu nehmen und
dass man deswegen dafür einen RICHTIG guten Grund (und viel, viel mehr
Zeit) braucht. Und bin extrem skeptisch wenn sich jemand hinstellt und
sagt "das hab ich schon gemacht, war ganz einfach". Weil >40000 Zeilen
Code zu schreiben, nur fürs Parsing, ist eben NICHT einfach.
Post by Gerhard Hoffmann
Ja, für den SCPI-Parser auf dem BeagleBoneBlack nehme ich
schon den yacc/bison und gcc. Für jeden Topf den passenden Deckel.
Ja, da gehe ich mit. Wenn es einen guten Grund gibt, klar, dann schreibt
man sich seinen eigenen Parser. Damit kommen eine interessante Vorteile,
aber auch eben einige gewichtige Nachteile mit. Aber grundsätzlich die
Komplexität zu trivialisieren ist kein guter Ansatz.

Gruß,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Stefan Reuther
2019-09-24 17:18:31 UTC
Antworten
Permalink
Post by Johannes Bauer
Post by Gerhard Hoffmann
Und er muss dir auch nichts liefern, du hast nichts bei ihm gekauft.
Wenn jemand groß Sprüche klopft, wie einfach das doch alles von Hand
sei, Lexer/Parser für komplexe Grammatiken zu schreiben (zum Beispiel
der von C), und dann in der Praxis halt schon bei simpelsten Beispielen
voll auf die Nase fliegt, dann ist das ja schon ein interessantes Ergebnis.
Ich warte ja auf das Gegenbeispiel, also: deinen C-Parser.
Post by Johannes Bauer
Post by Gerhard Hoffmann
aber die wichtigen
Compiler, die jeder hernimmt, wie gcc oder clang benutzen rekursiven
Abstieg.
Das ist *professionelle* Software. Mit hunderttausenden Personenstunden,
die da reingeflossen sind, sowohl in clang als auch in gcc. Und ich habe
ausführlich beschrieben, warum die das so machen -- sowohl clang als
auch gcc parsen eben auch C++, für das es keine ausdefinierte Grammatik
gibt
*Das* ist Geschwätz. Selbstverständlich hat C++ eine Grammatik. Zu
finden im Standard-Dokument unter "Annex A" sowie in Fragmenten in den
einzelnen Kapiteln. Sie ist halt nur nicht LL(1).
Post by Johannes Bauer
Ohne Not schreibt *niemand* einen Parser von Hand, auch nicht gcc und
clang. Und wenn man sich dazu entscheidet, ist das *weitaus*
schwieriger, als einen Parsergenerator zu nehmen.
Nein. Sage ich als einer, der routinemäßig Parser per Hand baut.
Post by Johannes Bauer
Post by Gerhard Hoffmann
Pascal nimmt auch rekursiven Abstieg. Und da sind Bösartigkeiten
with record_variablenliste do begin ... end
(Das ist übrigens parserseitig völlig trivial. Für Pascal musst du nicht
wissen, was das Wort 'x' bedeutet, um aus 'x(y)' einen AST bauen zu können.)
Post by Johannes Bauer
Post by Gerhard Hoffmann
und zwischen begin & end sind die Komponenten der records plötzlich
keine rec.a und rec.b mehr, sondern einfach nur noch a und b.
Wenn's zufällig globale a und b gab, dann gibt's die eben vorrübergehend
nicht mehr. Bring das mal einem Parsergenerator nahe, wenn Variablen-
namen eben zwischendurch für etwas völlig anderes mit möglicherweise
einem anderen Typ stehen.
Ich weiß echt nicht, wieso du ständig mit Pascal anfängst, das hat mit
dem Thema überhaupt nichts zu tun. Ich habe nie bestritten, dass
Recursive Descent ein ordentliches oder geeignetes Parsing-Verfahren
ist. Ich sage lediglich, dass das Schreiben eines Parsers von Hand
RICHTIG viel schwieriger ist, als einen Parsergenerator zu nehmen und
dass man deswegen dafür einen RICHTIG guten Grund (und viel, viel mehr
Zeit) braucht. Und bin extrem skeptisch wenn sich jemand hinstellt und
sagt "das hab ich schon gemacht, war ganz einfach". Weil >40000 Zeilen
Code zu schreiben, nur fürs Parsing, ist eben NICHT einfach.
Das, was du beim Schreiben der Grammatik sparst - wenn überhaupt was -
zahlst du beim Debuggen drauf. Wo muss ich jetzt die Aktionen
platzieren? Wie bekomme ich das Speicherleck-frei? Wie bekomme ich
gescheite Fehlermeldungen außer "parse error"? Wie erhole ich mich am
besten von einem Parser-Fehler? (Nächstes Semikolon suchen? Oder doch
lieber geschweifte Klammern? Oder 'END'-Schlüsselwort?)

Und - und das ist einer der Gründe, einen C-Parser per Hand zu machen -
in einem händischen Parser ist es trivial, Feedback zu geben, was für
ein Ding 'x' in 'x*y[3]' ist, denn abhängig davon wird der Rest
geparsed. Mit einem generierten Parser muss man damit durch ein paar
Ebenen Generat (yacc, lex) durch und dabei Annahmen treffen, wie der
generierte Code sich benimmt.


Stefan
Johannes Bauer
2019-09-24 18:47:51 UTC
Antworten
Permalink
Post by Stefan Reuther
Post by Johannes Bauer
Wenn jemand groß Sprüche klopft, wie einfach das doch alles von Hand
sei, Lexer/Parser für komplexe Grammatiken zu schreiben (zum Beispiel
der von C), und dann in der Praxis halt schon bei simpelsten Beispielen
voll auf die Nase fliegt, dann ist das ja schon ein interessantes Ergebnis.
Ich warte ja auf das Gegenbeispiel, also: deinen C-Parser.
Nur weil einen Parser von Hand schreiben schwer ist, heißt das noch
lange nicht, dass einen Parser mit Generator schreiben leicht ist.

Aber wenn ich ein Beispiel liefern würde, dann kann ich dir immerhin
versichern, dass das nicht so grütze-mäßig Segfaulten würde wie DoDis
Beispiel. Denn DAS ist Pfusch, völlig egal wie man parst.
Post by Stefan Reuther
Post by Johannes Bauer
auch gcc parsen eben auch C++, für das es keine ausdefinierte Grammatik
gibt
*Das* ist Geschwätz. Selbstverständlich hat C++ eine Grammatik. Zu
finden im Standard-Dokument unter "Annex A"
Du kannst offenbar keine Standards lesen. Denn da steht ganz klar
zuerstmal: Annex A (informative) -- muss ich dir jetzt den Unterschied
zwischen informative und normative erklären?

Und dann nochmal überdeutlich: "This summary of C ++ syntax is intended
to be an aid to comprehension. It is not an exact statement of the
language."
Post by Stefan Reuther
sowie in Fragmenten in den
einzelnen Kapiteln.
Genau, verteilt über ~1300 Seiten, aber eben nicht ausdefiniert (und
genau das habe ich geschrieben, keine ausdefinierte Grammatik).
Post by Stefan Reuther
Sie ist halt nur nicht LL(1).
Hat auch nie irgendjemand behauptet, völliges Strohmann-Argument.
Post by Stefan Reuther
Post by Johannes Bauer
Ohne Not schreibt *niemand* einen Parser von Hand, auch nicht gcc und
clang. Und wenn man sich dazu entscheidet, ist das *weitaus*
schwieriger, als einen Parsergenerator zu nehmen.
Nein. Sage ich als einer, der routinemäßig Parser per Hand baut.
Puh, naja, das ist jetzt Aussage gegen Aussage. Du findest das Schreiben
von Hand einfach, ich habe gerne Unterstützung von Werkzeugen.
Post by Stefan Reuther
Das, was du beim Schreiben der Grammatik sparst - wenn überhaupt was -
zahlst du beim Debuggen drauf. Wo muss ich jetzt die Aktionen
platzieren? Wie bekomme ich das Speicherleck-frei? Wie bekomme ich
gescheite Fehlermeldungen außer "parse error"? Wie erhole ich mich am
besten von einem Parser-Fehler? (Nächstes Semikolon suchen? Oder doch
lieber geschweifte Klammern? Oder 'END'-Schlüsselwort?)
Das ist wohl richtig, eine ordentliche Grammatik zu schreiben ist auch
alles andere als leicht. Und tatsächlich ist Debugging von Grammatiken
elendige Arbeit.
Post by Stefan Reuther
Und - und das ist einer der Gründe, einen C-Parser per Hand zu machen -
in einem händischen Parser ist es trivial, Feedback zu geben, was für
ein Ding 'x' in 'x*y[3]' ist, denn abhängig davon wird der Rest
geparsed. Mit einem generierten Parser muss man damit durch ein paar
Ebenen Generat (yacc, lex) durch und dabei Annahmen treffen, wie der
generierte Code sich benimmt.
Einen Tod muss man sterben. Vermutlich ist dann wohl ausschlaggebend,
womit man am meisten Erfahrung hat.

Viele Grüße,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Stefan Reuther
2019-09-25 15:51:02 UTC
Antworten
Permalink
Post by Johannes Bauer
Post by Stefan Reuther
Post by Johannes Bauer
Wenn jemand groß Sprüche klopft, wie einfach das doch alles von Hand
sei, Lexer/Parser für komplexe Grammatiken zu schreiben (zum Beispiel
der von C), und dann in der Praxis halt schon bei simpelsten Beispielen
voll auf die Nase fliegt, dann ist das ja schon ein interessantes Ergebnis.
Ich warte ja auf das Gegenbeispiel, also: deinen C-Parser.
Nur weil einen Parser von Hand schreiben schwer ist, heißt das noch
lange nicht, dass einen Parser mit Generator schreiben leicht ist.
Aber wenn ich ein Beispiel liefern würde, dann kann ich dir immerhin
versichern, dass das nicht so grütze-mäßig Segfaulten würde wie DoDis
Beispiel.
Da wäre ich mir nicht so sicher, denn Ressourcenmanagement zumindest mit
yacc ist nicht einfach. Wer gackert muss auch legen.

(Mein zweites größeres Parserprojekt war vor >20 Jahren bei "Jugend
Forscht", ist also nicht so, dass ich nicht legen könnte.)
Post by Johannes Bauer
Post by Stefan Reuther
Post by Johannes Bauer
auch gcc parsen eben auch C++, für das es keine ausdefinierte Grammatik
gibt
*Das* ist Geschwätz. Selbstverständlich hat C++ eine Grammatik. Zu
finden im Standard-Dokument unter "Annex A"
Du kannst offenbar keine Standards lesen. Denn da steht ganz klar
zuerstmal: Annex A (informative) -- muss ich dir jetzt den Unterschied
zwischen informative und normative erklären?
Danke, sehr freundlich. (Mein ca. fünftes größeres Parserprojekt war
Teil eines C++-Compilers für das VFiasco-Projekt. C++-Standard kenn ich.)
Post by Johannes Bauer
Und dann nochmal überdeutlich: "This summary of C ++ syntax is intended
to be an aid to comprehension. It is not an exact statement of the
language."
Das ist die Zusammenfassung der Fragmente. Nicht normativ, weil die
normativen Teile nebst der semantischen Bedingungen in den anderen
Kapiteln stehen, und weil dir niemand zusichert, in dem Anhang nichts
vergessen zu haben.
Post by Johannes Bauer
Post by Stefan Reuther
sowie in Fragmenten in den
einzelnen Kapiteln.
Genau, verteilt über ~1300 Seiten, aber eben nicht ausdefiniert (und
genau das habe ich geschrieben, keine ausdefinierte Grammatik).
Was wäre denn eine "ausdefinierte Grammatik"?

Die ernsthafte Schwäche, die diese Grammatik hat, ist, dass sie zwischen
den Ebenen "lexikalische Analyse", "Präprozessor" und "syntaktische
Analyse" nicht sauber trennt. Jedem Praktiker ist das egal. Regeln wie
"maximum munch" (also dass 'inti' ein Wort ist und nicht das gleiche wie
'int i') werden quasi immer in Prosa angegeben, nicht in der Grammatik.


Stefan
Johannes Bauer
2019-09-27 08:37:06 UTC
Antworten
Permalink
Post by Stefan Reuther
Post by Johannes Bauer
Nur weil einen Parser von Hand schreiben schwer ist, heißt das noch
lange nicht, dass einen Parser mit Generator schreiben leicht ist.
Aber wenn ich ein Beispiel liefern würde, dann kann ich dir immerhin
versichern, dass das nicht so grütze-mäßig Segfaulten würde wie DoDis
Beispiel.
Da wäre ich mir nicht so sicher, denn Ressourcenmanagement zumindest mit
yacc ist nicht einfach. Wer gackert muss auch legen.
Du vergisst die Messlatte: DoDi's Programm stürzt schon ab, wenn man es
lediglich STARTET.

Ich bin mir extrem sicher, dass ich ein Programm hinkriege, dass nicht
beim Start abstürzt. Eines, das nicht "F:\DoDi\..." als hardgecodete
Pfade enthält.

Und einen Parser kann man auch in einer Programmiersprache schreiben,
die Ressourcenmanagement übernimmt, ich bevorzuge Python wenn
Performance nicht kritisch ist.
Post by Stefan Reuther
(Mein zweites größeres Parserprojekt war vor >20 Jahren bei "Jugend
Forscht", ist also nicht so, dass ich nicht legen könnte.)
Joa und ich habe produktiven, sicherheitskritsichen Kernelcode
geschrieben, der jahrelang unterbrechungsfrei laufen muss. Da kann man
sich keine Ressourcenleaks erlauben, nicht mal die Kleinsten.
Post by Stefan Reuther
Post by Johannes Bauer
Post by Stefan Reuther
*Das* ist Geschwätz. Selbstverständlich hat C++ eine Grammatik. Zu
finden im Standard-Dokument unter "Annex A"
Du kannst offenbar keine Standards lesen. Denn da steht ganz klar
zuerstmal: Annex A (informative) -- muss ich dir jetzt den Unterschied
zwischen informative und normative erklären?
Danke, sehr freundlich.
Na du musst dich schon entscheiden. Entweder du unterstellst mir
Geschwätz, kannst das ordentlich belegen und ich halte meine Schnauze.
Oder du unterstellst mir Geschwätz, lieferst unzureichende Belege und
bekommst eine entsprechend unfreundliche Antwort. Beides geht nicht.
Post by Stefan Reuther
(Mein ca. fünftes größeres Parserprojekt war
Teil eines C++-Compilers für das VFiasco-Projekt. C++-Standard kenn ich.)
Mag ja sein, trotzdem hast du einen INFORMATIVEN Teil als "Beleg"
angeführt. Einen Teil, der also als Beleg völlig untauglich ist, weil er
formal eben NICHT Teil der Spezifikation ist. Und selbst wenn er es wäre
ganz klar drin steht, dass es eben nicht den Sprachumfang abdeckt.
Post by Stefan Reuther
Post by Johannes Bauer
Und dann nochmal überdeutlich: "This summary of C ++ syntax is intended
to be an aid to comprehension. It is not an exact statement of the
language."
Das ist die Zusammenfassung der Fragmente. Nicht normativ, weil die
normativen Teile nebst der semantischen Bedingungen in den anderen
Kapiteln stehen, und weil dir niemand zusichert, in dem Anhang nichts
vergessen zu haben.
Und selbst die Fragmente sind horrend unvollständig. Ich nehme mir ein
beliebiges Beispiel raus: "14.2. Names of template specializations".
Eine popelige Grammatik, evtl 15 Zeilen lang. Gefolgt von 1 1/2 Seiten
Prosa, die dann genau sagt wie die zu interpretieren ist.

Das ist keine formale Beschreibung einer Sprache. Das ist Prosa.
Post by Stefan Reuther
Post by Johannes Bauer
Post by Stefan Reuther
sowie in Fragmenten in den
einzelnen Kapiteln.
Genau, verteilt über ~1300 Seiten, aber eben nicht ausdefiniert (und
genau das habe ich geschrieben, keine ausdefinierte Grammatik).
Was wäre denn eine "ausdefinierte Grammatik"?
Eine formale Beschreibung, die man im idealfall direkt einem Parser
vorlegen kann, also maschinenlesbar ist. C++ ist aber als Sprache so
kompliziert, dass ich vermute, dass das wohl nicht (mehr?) machbar ist.
Deswegen nutzt man eben viel Prosa und Beispiele, um zu verdeutlichen,
was gemeint ist.
Post by Stefan Reuther
Die ernsthafte Schwäche, die diese Grammatik hat, ist, dass sie zwischen
den Ebenen "lexikalische Analyse", "Präprozessor" und "syntaktische
Analyse" nicht sauber trennt. Jedem Praktiker ist das egal. Regeln wie
"maximum munch" (also dass 'inti' ein Wort ist und nicht das gleiche wie
'int i') werden quasi immer in Prosa angegeben, nicht in der Grammatik.
Ich würde sagen, die ernsthafteste Schwäche sind die extrem
komplizierten Disambiguation Regeln. Die wirklich korrekt zu
implementieren ist (auch aufgrund der mangelhaften Definition als
textuelle Repräsentation) extrem schwierig und das zeigt sich auch immer
wieder bei Beispielen, die von einem Compiler gefressen werden und von
einem anderen nicht.

C++ ist halt Stückelwerk. Außerdem sind ihnen offenbar irgendwann die
Tokens ausgegangen, sonst hätten wir nicht jahrelang elendige Probleme
gehabt mir trivialsten Mist wie

std::vector<std::vector<std::string>>

bzw eben der früher notwendigen Variante

std::vector<std::vector<std::string> >

Wenn mich meiner Errinerung nicht täuscht, sind die ntowendigen
Disambiguation Regeln dafür erst mit C++11 dazugekommen. Das ist einfach
nur gruselig.

Gruß,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Hans-Peter Diettrich
2019-09-27 19:22:06 UTC
Antworten
Permalink
Das hat nichts mit schwammiger Disambiguierung zu tun, das ist ein ganz
normaler "maximum munch" Lexer, der, wenn man ihm keinen Tipp gibt, '>>'
als ein Token parsed.
Schon K&R hat >>, ==, ++ usw. als eigenständige Tokens definiert. Selbst
für +++ wurde geregelt, welche Tokens das ergibt. Und wenn wir schon
dabei sind, das "dangling else" wird auch weit einfacher in der
semantischen Prüfung des Parsers aufgelöst als in der Grammatik.

Mich stört da mehr das "long long", das eine eigene Bedeutung erhalten
hat, nicht aber "short short". Ist eigentlich heutzutage auch "long
signed long" ein gültiger Typ, und wenn ja welcher?
a := sqrt(.5);
(parsed nicht, weil '(.' als '[' interpretiert wird.)
Sofern man Digraphen als Option eingeschaltet hat. Heutige Compiler
kennen möglicherweise garkeine Di-/Trigraphen mehr, oder ignorieren sie
per Default. Delphi unterscheidet inzwischen sogar Kommentare in { } und
(* *), die eigentlich gleich interpretiert werden müßten. So kann man
ganze Codeblöcke mit Kommentaren ggf. nochmal mit der anderen
Schreibweise auskommentieren.

DoDi
Stefan Reuther
2019-09-28 09:58:21 UTC
Antworten
Permalink
Post by Hans-Peter Diettrich
Das hat nichts mit schwammiger Disambiguierung zu tun, das ist ein ganz
normaler "maximum munch" Lexer, der, wenn man ihm keinen Tipp gibt, '>>'
als ein Token parsed.
Schon K&R hat >>, ==, ++ usw. als eigenständige Tokens definiert. Selbst
für +++ wurde geregelt, welche Tokens das ergibt. Und wenn wir schon
dabei sind, das "dangling else" wird auch weit einfacher in der
semantischen Prüfung des Parsers aufgelöst als in der Grammatik.
Mich stört da mehr das "long long", das eine eigene Bedeutung erhalten
hat, nicht aber "short short". Ist eigentlich heutzutage auch "long
signed long" ein gültiger Typ, und wenn ja welcher?
"long signed long" ist das gleiche wie "long long".

Dafür gibt es wenigstens einen Compiler, der "long short" für einen
24-Bit-Typen kennt (MPLAB C18). Was sollte denn "short short" sein? Bei
den üblichen Größen mit "char" = 8 Bit, "short" = 16 Bit bliebe ja nur
ein 12-Bit-Typ übrig. Hardwareunterstützung dafür dürfte dann doch eher
selten in freier Natur anzutreffen sein. Einfach, weil sich der
Programmierer von der Straße nichts ohne 8-Bit-Bytes mehr vorstellen kann.
Post by Hans-Peter Diettrich
a := sqrt(.5);
(parsed nicht, weil '(.' als '[' interpretiert wird.)
Sofern man Digraphen als Option eingeschaltet hat. Heutige Compiler
kennen möglicherweise garkeine Di-/Trigraphen mehr, oder ignorieren sie
per Default.
Zumindest die Turbo-Pascal-Compiler hatten keine mir bekannte
Möglichkeit, das auszuschalten.
Post by Hans-Peter Diettrich
Delphi unterscheidet inzwischen sogar Kommentare in { } und
(* *), die eigentlich gleich interpretiert werden müßten. So kann man
ganze Codeblöcke mit Kommentaren ggf. nochmal mit der anderen
Schreibweise auskommentieren.
Das wiederum hatte Turbo Pascal auch.


Stefan
Hans-Peter Diettrich
2019-09-28 11:48:19 UTC
Antworten
Permalink
Post by Stefan Reuther
Post by Hans-Peter Diettrich
Das hat nichts mit schwammiger Disambiguierung zu tun, das ist ein ganz
normaler "maximum munch" Lexer, der, wenn man ihm keinen Tipp gibt, '>>'
als ein Token parsed.
Schon K&R hat >>, ==, ++ usw. als eigenständige Tokens definiert. Selbst
für +++ wurde geregelt, welche Tokens das ergibt. Und wenn wir schon
dabei sind, das "dangling else" wird auch weit einfacher in der
semantischen Prüfung des Parsers aufgelöst als in der Grammatik.
Mich stört da mehr das "long long", das eine eigene Bedeutung erhalten
hat, nicht aber "short short". Ist eigentlich heutzutage auch "long
signed long" ein gültiger Typ, und wenn ja welcher?
"long signed long" ist das gleiche wie "long long".
Warum? Ich hätte auf "signed long" getippt.
Post by Stefan Reuther
Dafür gibt es wenigstens einen Compiler, der "long short" für einen
24-Bit-Typen kennt (MPLAB C18). Was sollte denn "short short" sein? Bei
den üblichen Größen mit "char" = 8 Bit, "short" = 16 Bit bliebe ja nur
ein 12-Bit-Typ übrig. Hardwareunterstützung dafür dürfte dann doch eher
selten in freier Natur anzutreffen sein. Einfach, weil sich der
Programmierer von der Straße nichts ohne 8-Bit-Bytes mehr vorstellen kann.
Das hat dann aber nichts mit einem C Standard zu tun, sondern ist eine
compilerspezifische Erweiterung.
Post by Stefan Reuther
Post by Hans-Peter Diettrich
a := sqrt(.5);
(parsed nicht, weil '(.' als '[' interpretiert wird.)
Sofern man Digraphen als Option eingeschaltet hat. Heutige Compiler
kennen möglicherweise garkeine Di-/Trigraphen mehr, oder ignorieren sie
per Default.
Zumindest die Turbo-Pascal-Compiler hatten keine mir bekannte
Möglichkeit, das auszuschalten.
Deshalb schrieb ich ja "heutige" Compiler :-]

DoDi

Johannes Bauer
2019-09-28 11:43:46 UTC
Antworten
Permalink
Post by Johannes Bauer
Post by Stefan Reuther
Das ist die Zusammenfassung der Fragmente. Nicht normativ, weil die
normativen Teile nebst der semantischen Bedingungen in den anderen
Kapiteln stehen, und weil dir niemand zusichert, in dem Anhang nichts
vergessen zu haben.
Und selbst die Fragmente sind horrend unvollständig. Ich nehme mir ein
beliebiges Beispiel raus: "14.2. Names of template specializations".
Eine popelige Grammatik, evtl 15 Zeilen lang. Gefolgt von 1 1/2 Seiten
Prosa, die dann genau sagt wie die zu interpretieren ist.
Das nennt sich - ich wiederhole mich - semantische Bedingungen. Von
Trivialitäten wie Brainfuck abgesehen kommt kaum eine Sprache ohne aus.
Klar, aber die Komplexität der in Prosa geschriebenen semantischen
Bedingungen übersteigt die der Grammatik eben bei Weitem. Der Effekt ist
bei C++ eben wirklich ausgeprägt.
Post by Johannes Bauer
Eine formale Beschreibung, die man im idealfall direkt einem Parser
vorlegen kann, also maschinenlesbar ist. C++ ist aber als Sprache so
kompliziert, dass ich vermute, dass das wohl nicht (mehr?) machbar ist.
Deswegen nutzt man eben viel Prosa und Beispiele, um zu verdeutlichen,
was gemeint ist.
Du kannst die Grammatik einem ausreichend fähigen Parsergenerator
vorlegen. Der wird dann halt *mehr* erkennen als nur gültige
C++-Programme, da die semantischen Bedingungen die gültigen Programme
*einschränken* ("eine Variable muss vor der Verwendung deklariert sein"
usw.).
Umso mehr Bedingungen es gibt, die diese Programme einschränken, umso
nutzloser ist die reine formale Grammatik. Weil dann kann ich
prinzipiell für jede Sprache eine allgemeingültige Grammatik angeben:

PROGRAM := chr(0..255)*

Supereinfach, und korrekt dazu. Parst jedes gültige C++-Programm. Und
halt noch mehr, als semantische Bedingung gebe ich an muss zusätzlich
den C++-Standard erfüllen. Feddich ist der Lack.

Ist aber halt super nutzlos, so eine Grammatik.
Diese Disambiguierungsregeln hat es zum Teil von C geerbt. 'a * b;' ist
ein expression-statement oder eine Deklaration.
C ist im Vergleich zu C++ absoluter Kinderkram. Die Komplexität von C++
würde ich, bauchgefühlsmäßig, als mindestens Faktor 10 höher einschätzen.
Post by Johannes Bauer
Wenn mich meiner Errinerung nicht täuscht, sind die ntowendigen
Disambiguation Regeln dafür erst mit C++11 dazugekommen. Das ist einfach
nur gruselig.
Das hat nichts mit schwammiger Disambiguierung zu tun, das ist ein ganz
normaler "maximum munch" Lexer, der, wenn man ihm keinen Tipp gibt, '>>'
als ein Token parsed.
Schon klar. Aber es geht nicht darum, wieso der Parser das so parst,
sondern was per Definition die *korrekte* Art des Parsens ist. Und, wenn
mich meine Errinerung nicht täuscht, war eben

std::vector<std:vector<std::string>>

Formal gesehen vor C++x ein Syntaxfehler. Ich glaube mich daran zu
errinern, dass sowohl der MS C++-Compiler als auch der icc trotzdem das
geparst haben, was "gemeint" war, und nur der gcc sich daran
verschluckte. Und meiner Errinerung nach war gcc eben formal "korrekt".
Aber das ist alles jetzt schon ewig her, bin mir in den Details nicht
mehr ganz sicher.

Das verdeutlicht aber genau das Problem, das ich anspreche: Jemand, der
einen Compiler schreibt, versucht das "richtige" zu machen, weil die
formale Definition eben unvollständig oder klobig ist. Da wackelt der
Schwanz mit dem Hund.

Gruß,
Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Hans-Peter Diettrich
2019-09-23 17:07:03 UTC
Antworten
Permalink
Post by Gerhard Hoffmann
Post by Johannes Bauer
Immerhin, muss man dir zu Gute halten, hast du ausnahmsweise was
geliefert, statt immer nur heiße Luft zu produzieren. Auch wenn es jetzt
halt nicht dein Argument gestärkt hat, sondern exakt das Gegenteil bewiesen.
Du hast nur bewiesen, daß Du einen Compiler nicht korrekt installieren
kannst. Dein Problem, wenn dann benötigte Dateien nicht gefunden werden.
Post by Gerhard Hoffmann
Wenn hier einer den Oberlehrer macht, dann du.
Und er muss dir auch nichts liefern, du hast nichts bei ihm gekauft.
Laß gut sein, ich laß ihn weiter in meinem Filter schmoren. Mir fehlt
nur noch ein Filter für Antworten auf seine Trollereien.
Post by Gerhard Hoffmann
Wirklich bewiesen hast du garnix. Du hast ein paar Exotencompiler
aufgezählt die einen Parsergenerator benutzen,
Wobei ich mich frage, wie der C Preprozessor in einen generierten Parser
eingebaut werden kann. Aber die Antwort kenne ich inzwischen schon,
Johannes kann das latürnich ;-)

DoDi
Johannes Bauer
2019-09-23 18:08:46 UTC
Antworten
Permalink
Post by Hans-Peter Diettrich
Post by Johannes Bauer
Immerhin, muss man dir zu Gute halten, hast du ausnahmsweise was
geliefert, statt immer nur heiße Luft zu produzieren. Auch wenn es jetzt
halt nicht dein Argument gestärkt hat, sondern exakt das Gegenteil bewiesen.
Du hast nur bewiesen, daß Du einen Compiler nicht korrekt installieren
kannst. Dein Problem, wenn dann benötigte Dateien nicht gefunden werden.
Aaaaaaaahahahahahaha!

Ja, klar. Wenn Dateien nicht gefunden werden, versucht er mal auf
Adresse 0x7 zuzugreifen und löst eine allgemeine Schutzverletzung aus.
Ist klar, die Fehlerbehandung der Profis. Perfekte Erklärung!

Gott, du bist so armselig mit deinen dumm-dreisten Ausreden und
ständigen Herumlügereien. Ekelhaft und widerlich.
Post by Hans-Peter Diettrich
Laß gut sein, ich laß ihn weiter in meinem Filter schmoren.
Neeeeeeeeein oh neeeeeeein, die allerschlimmste Strafe von allen. In
deinem Filter zu "schmoren". Jetzt entgehen mir deine altklugen
Ratschläge also in Zukunft, ich bin untröstlich.
Post by Hans-Peter Diettrich
Mir fehlt
nur noch ein Filter für Antworten auf seine Trollereien.
Dass du nicht mal in der Lage bist, einen Newsreader zu bedienen,
überrascht sicherlich niemanden mehr.

Alles Liebe,
Dein Johannes
--
"Performance ist nicht das Problem, es läuft ja nachher beides auf der
selben Hardware." -- Hans-Peter Diettrich in d.s.e.
Gerhard Hoffmann
2019-09-22 11:40:33 UTC
Antworten
Permalink
Post by Andreas Weber
Hallo an alle,
ich verwende seit knapp 4 Jahren immer wieder den Ragel [1] Generator
für Parser auf Atmel/Microchip AVRs z.B. für UART Empfangsroutinen.
Was verwendet ihr so, sobald die Grammatik etwas komplizierter wird? Lex
wäre ja auch eine Möglichkeit.
TIA, Gruß Andy
[1] https://www.colm.net/open-source/ragel/
Den kannte ich noch nicht, danke für's Aufschlauen.

Mit dem guten alten yacc und seinen Nachfahren (bison) müsste
es auch gehen. Links/rechts-rekursiv mit 1 token look-ahead.
Hat bisher bei mir für alles gereicht.

Da kommt auch nur eine Matrix raus und eine function, die inputs
entgegennimmt und an den passenden Stellen die Aktionen triggert.

Der yacc war übrigens ursprünglich nicht für den Compilerbau
vorgesehen, sondern zum automatisierten Übersetzen von Zustands-
Automaten in Weinberger-Arrays. Weinberger-Arrays sind so was
ähnliches wie PALs, nur älter und nur maskenprogrammierbar.

Das ist der gleiche Weinberger, der für das W in awk steht.
(Aho, Weinberger, Kernighan). Die ganze UNIX/C-Truppe bei AT&T
waren eigentlich Halbleiterleute und Digitaldesigner.
Unix und C waren nur "Abfallprodukte".

Gruß, Gerhard
olaf
2019-09-22 12:59:30 UTC
Antworten
Permalink
Post by Gerhard Hoffmann
(Aho, Weinberger, Kernighan). Die ganze UNIX/C-Truppe bei AT&T
waren eigentlich Halbleiterleute und Digitaldesigner.
Unix und C waren nur "Abfallprodukte".
Natuerlich! Die ganzen Programmierer sind nur Abfallprodukte der
Hardwareentwicklung. Ich erzaehle denen das andauernd, aber sie wollen
es einfach nicht akzeptieren. :)

Olaf
Loading...