Semikolon nach Funktion (Klausurfrage-Fehler finden im Code)
-
Bashar schrieb:
pointercrash() schrieb:
Um eine Leeranweisung für "pedantic" da rauszufischen braucht es extra- Fleiß.
Nicht wirklich. Wenn die Grammatik so gebaut ist, dass das leere Semikolon auf eine Deklaration matcht (siehe Vorposting), dann wirst du als nächstes diese Deklaration verarbeiten. Dabei merkst du es auf jeden Fall, wenn alle Teile leer sind. Den "Fleiß" zum Formulieren der Fehlermeldung kann man wohl gerade noch aufbringen
Bin ich nicht ganz Deiner Meinung, wenn ich auf die "scharfen" Bestandteile einer (möglichen) Deklaration warte, ist das üblicherweise kein Semikolon und damit der Parser in einem Zustand, in dem er das Semikolon genausogut überlesen kann. Erst wenn anderer Kram eingelesen wurde, muß er sich beim Semikolon Gedanken machen, ob das stimmen kann. Ist aber ziemlich egal, ob ein Funktionstyp gefordert wird oder nicht, nach einer abgeschlossenen Funktion darf er es einfach überlesen oder auch nicht, scharf wird das Semikolon erst, wenn das "~" oder das "m" (Deine foo und main- Bsp's.) auf dem Tisch landen. Im Filescope untergebracht macht das keinen Unterschied.
Wer will ein Semikolon auswerten, wenn es nichts auszuwerten gibt? Klar kann man das so bauen, aber wozu? Natürlich ist mir klar, daß es keinen echten Aufwand bedeutet, da auf pedantic zu prüfen und 'ne warning rauszuhauen. Ist halt nur eine Sinnlos- Prüfung, die Rechenzeit kostet. Ich kenne nur leider keinen Compilerbauer, der mir diese lebenswichtige Frage beantwortet, wie sowas wirklich gebaut wird.
-
Ich weiß ja nicht, was du für Erfahrungen mit Compilerbau hast, aber normalerweise warte ich nicht auf "scharfe Bestandteile", sondern nehme die Reduktionen so, wie sie kommen. Die Produktion für "declaration" würde also genau dann reduziert werden, wenn das Semikolon gerade gesehen wird.
[Übrigens nur in C++. In C89 ist das mit dermain()
anders gelöst, als ich dachte, dort kann man also aus "declaration" nicht ";" ableiten.]
-
Bashar schrieb:
Ich weiß ja nicht, was du für Erfahrungen mit Compilerbau hast,
Hab' schon jede Menge Parser und ein paar Interpreter gebaut, aber Null Ahnung, wie man "echte" Compiler designed.
Bashar schrieb:
... sondern nehme die Reduktionen so, wie sie kommen. Die Produktion für "declaration" würde also genau dann reduziert werden, wenn das Semikolon gerade gesehen wird.
[Übrigens nur in C++. In C89 ist das mit dermain()
anders gelöst, als ich dachte, dort kann man also aus "declaration" nicht ";" ableiten.]Das kapier' ich momentan nicht, hast Du mir einen Link, wo ich ein bißchen Lesen kann und dann ggf. nachfragen?
-
pointercrash() schrieb:
Ich hätte mich auch gerne in das Grauen verklausulierten Englischs gestürzt, aber wo find' ich den Standard im Internet?
TC3-Draft:
www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdfpointercrash() schrieb:
In C89 und C++ wäre es sogar syntaktisch eine, da alle Teile einer Deklaration optional sind
Dort ist der leere String auch eine Deklaration?
Edit:
Und noch ein Blödheitspunkt.
-
mngbd schrieb:
TC3-Draft: www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
Danke, in Bibliothek verewigt!
mngbd schrieb:
pointercrash() schrieb:
In C89 und C++ wäre es sogar syntaktisch eine, da alle Teile einer Deklaration optional sind
Ne, das war ich nicht, sondern Bashar.
-
pointercrash() schrieb:
Bashar schrieb:
... sondern nehme die Reduktionen so, wie sie kommen. Die Produktion für "declaration" würde also genau dann reduziert werden, wenn das Semikolon gerade gesehen wird.
[Übrigens nur in C++. In C89 ist das mit dermain()
anders gelöst, als ich dachte, dort kann man also aus "declaration" nicht ";" ableiten.]Das kapier' ich momentan nicht, hast Du mir einen Link, wo ich ein bißchen Lesen kann und dann ggf. nachfragen?
Uff, mit Links wird das schwierig, wie wärs mit Büchern? Das Drachenbuch ist sehr beliebt ... aber Spaß beiseite. In der C++-Grammatik steht ungefähr sowas drin:
simple-declaration: decl-specifier-seq_opt init-declarator-list_opt ";"
In Yacc umgesetzt sieht das etwa so aus:
simple_declaration: decl_specifier_seq_opt init_declarator_list_opt SEMICOLON { $$ = handle_simple_declaration($1, $2); } ; decl_specifier_seq_opt: { $$ = 0; /* empty */ } | decl_specifier_seq { $$ = $1; } ; init_declarator_list_opt: { $$ = 0; /* empty */ } | init_declarator_list { $$ = $1; } ;
(Könnte sein, dass das einen Konflikt enthält, dass man das also noch ein bisschen umbauen muss, aber das ist für die Diskussion glaub ich irrelevant.)
In dem Moment, in dem der Parser in diesem syntaktischen Zusammenhang das Semikolon gelesen hat, führt er den Code
$$ = handle_simple_declaration($1, $2);
aus. Wenn die vorherigen Produktionen den leer-Zweig durchlaufen haben, ist das eben so, die semantischen Werte der Werte der Nichtterminale decl_specifier_seq_opt und init_declarator_list_opt sind dann halt 0. Die Funktion handle_simple_declaration muss darauf vorbereitet sein. Falls beide gleichzeitig 0 sind, kann man entweder keine Deklaration erzeugen oder eine Fehlermeldung ausgeben.In C ist das, was hier decl_specifier_seq heißt, nicht optional. Es muss eine Speicherklasse oder einen Typ beinhalten. Es wäre aber trotzdem denkbar, dass man das ähnlich wie ich oben löst, und beim Bauen der Deklaration nachguckt, ob man mindestens eine Speicherklasse oder einen Typ dabeihat.
-
Bashar schrieb:
In dem Moment, in dem der Parser in diesem syntaktischen Zusammenhang das Semikolon gelesen hat, führt er den Code
$$ = handle_simple_declaration($1, $2);
aus. Wenn die vorherigen Produktionen den leer-Zweig durchlaufen haben, ist das eben so, die semantischen Werte der Werte der Nichtterminale decl_specifier_seq_opt und init_declarator_list_opt sind dann halt 0. Die Funktion handle_simple_declaration muss darauf vorbereitet sein. Falls beide gleichzeitig 0 sind, kann man entweder keine Deklaration erzeugen oder eine Fehlermeldung ausgeben.In C ist das, was hier decl_specifier_seq heißt, nicht optional. Es muss eine Speicherklasse oder einen Typ beinhalten. Es wäre aber trotzdem denkbar, dass man das ähnlich wie ich oben löst, und beim Bauen der Deklaration nachguckt, ob man mindestens eine Speicherklasse oder einen Typ dabeihat.
Darf ich das als Dummie mal so subsummieren: Der Parser pfeift sich alles rein, bis er auf das Semikolon trifft und erst dann guckt er nach, ob er aus dem Kram davor eine declaration basteln kann?
-
Nicht ganz. Er baut nicht aus Müll + Semikolon auf einmal eine Deklaration, sondern er baut zwischendurch immer wieder kleine Teil-Syntaxbäume für die ganzen Bestandteile einer Deklaration und packt das auf den Stack. Wenn er jetzt beim Antreffen des Semikolons im richtigen Zustand ist (eine Deklaration kann ja z.B. nicht innerhalb eines Ausdrucks stehen, d.h. ein Semikolon in einem Ausdruck bedeutet auch etwas anderes) und auf dem Stack ein Teilbaum für init-declarator-list_opt und declaration-specifier_seq_opt liegen (was eigentlich auch Teil des Parserzustandes ist), dann baut er eine Deklaration (und führt meine semantische Aktion aus, d.h. ruft handle_simple_declaration auf).
Das ist jetzt das Prinzip des Bottom-Up-Parsers gewesen, wie es z.B. yacc umsetzt. Top-Down-Parser funktionieren ein bisschen anders.
-
Bashar schrieb:
Nicht ganz. Er ... baut zwischendurch immer wieder kleine Teil-Syntaxbäume für die ganzen Bestandteile einer Deklaration und packt das auf den Stack. Wenn er jetzt beim Antreffen des Semikolons im richtigen Zustand ist (eine Deklaration kann ja z.B. nicht innerhalb eines Ausdrucks stehen, d.h. ein Semikolon in einem Ausdruck bedeutet auch etwas anderes) und auf dem Stack ein Teilbaum für init-declarator-list_opt und declaration-specifier_seq_opt liegen (was eigentlich auch Teil des Parserzustandes ist), dann baut er eine Deklaration (und führt meine semantische Aktion aus, d.h. ruft handle_simple_declaration auf).
OK, Danke! Den Rest hab' ich mir bei LEXandYACC zusammengelesen. Wow, ziemlich aufwendig - Du befasst Dich wohl nicht nur zum Spaß damit, was?
Glücklicherweise mußte ich noch nie auf solche Tools zurückgreifen, meine Problemstellungen waren dafür einfach zu schlicht.
-
pointercrash() schrieb:
Du befasst Dich wohl nicht nur zum Spaß damit, was?
Der Spaß war zuerst, dann kam das "nicht nur zum Spaß" dazu