DAS POSTING, AUF DAS ICH ANTWORTE, IST AUF EINMAL WEG???
Was habe ich jetzt falsch gemacht oder gedrückt???
Hi Danilo!
Danke, dass du dich noch damit auseinandersetzt.
ERSTENS:
Ein bisschen entsetzt mich, dass Kapitel-8-Parser das akzeptiert, der muss eine Fehlermeldung ausgeben!!!!!
Meiner tut das!
Also der Compiler von Kapitel 8 müsste hängenbleiben bei diesem Code:
Die Version von Kapitel 8 hat nämlich noch
keine Vergleichsoperatoren und ruft außerdem als Default-Option in Statement() immer den Expression-Parser mit Expression() auf. Also das sollte so nicht funktionieren!
ZWEITENS:
Wenn ich vorgreifen darf auf Kapitel 9
(EDIT: Wird zu einem späteren Zeitpunkt kommen, vorher verbesserter Mathe Parser), dann poste ich, was der Kapitel 9
(?) Parser ausgibt (auch hier muss ich noch etwas zaubern, weil ich immer noch auf Expression() "defaulte", aber ich bin noch im Entwicklungsstadium:
Also wir haben es hier mit einem typischen Dangling Else zu tun.
In diesem Wikipedia-Artikel(
http://de.wikipedia.org/wiki/Dangling_else) ist ein identes Beispiel mit Zahlen, daran habe ich mich gehalten, als ich die Toy-C-Grammatik-Logik gemacht habe:
Wikipedia hat geschrieben:In diesem Beispiel erwarten einige Nutzer, dass für den Fall der Variablen der Wert zugewiesen wird. Der Compiler bezieht den else-Zweig allerdings auf die letzte (!!!!) if-Abfrage.
Also sollte sich also das else auf das
letzte if beziehen.
Ich rücke meinen Code also schnell mal so ein, wie die Sache wirklich gemeint ist:
Annahme b<>1, also die erste If-Abfrage geht auf FALSE:
Code: Alles auswählen
if (b=1) ---------------.
if (a=3) |
print_a_ist_3 |
else |
print_else |
v
* hinter print_else
Ist doch so? Sag mir bitte, wenn ich mich täusche!
Mein Compiler macht dasselbe daraus:
Code: Alles auswählen
push Global B
push Const 1
eq
JF IF0 ----------------------. JF = Jump if False
push Global A |
push Const 3 |
eq |
JF IF1 |
push Global PRINT_A_IST_3 |
JF IF2 |
[IF1] |
push Global PRINT_ELSE |
[IF2] v
[IF0] * hinter print_else
Annahme b=1, also die erste If-Abfrage geht auf TRUE:
Annahme a=0, also die zweite If-Abfrage geht auf FALSE, jetzt müssten wir zu ELSE kommen, oder?
Code: Alles auswählen
if (b=1) TRUE
if (a=3) FALSE
print_a_ist_3 |
else |
print_else <----' nimmt else-Zweig
Mein Compiler mach das daraus:
Code: Alles auswählen
push Global B
push Const 1
eq
JF IF0 TRUE (weiter gehts)
push Global A |
push Const 3 |
eq v
JF IF1 FALSE (jump)
push Global PRINT_A_IST_3 |
JF IF2 v
[IF1] * nimmt else-Zweig
push Global PRINT_ELSE
[IF2]
[IF0]
Nehmen wir das 2. Beispiel aus der Wikipedia (ich habs gleich umgewandelt, damit mein Compiler das isst).
a=0 --> a = FALSE
Code: Alles auswählen
if (a = 1) FALSE
{ |
if(b = 1) |
b_ist_true |
} |
else v
else_zweig_von_a * else-Zweig kommt
Compiler:
Code: Alles auswählen
push Global A
push Const 1
eq FALSE
JF IF0 |
push Global B |
push Const 1 |
eq |
JF IF1 |
push Global B_IST_TRUE |
[IF1] |
JF IF2 v
[IF0] * else-Zweig kommt
push Global ELSE_ZWEIG_VON_A
[IF2]
a=TRUE, b=TRUE, else-Zweig darf jetzt NICHT KOMMEN.
Code: Alles auswählen
if (a = 1) TRUE
{ |
if(b = 1) TRUE
b_ist_true |
} |
else |
else_zweig_von_a v
* else-Zweig kommt NICHT
Compiler:
Code: Alles auswählen
push Global A
push Const 1
eq TRUE
JF IF0 |
push Global B |
push Const 1 |
eq |
JF IF1 TRUE
push Global B_IST_TRUE |
[IF1] |
JF IF2 ÜBERSPRINGEN
[IF0] |
push Global ELSE_ZWEIG_VON_A v
[IF2] * else-Zweig kommt NICHT
Und so weiter: also für mich passt das eigentlich so.
Er springt auch bei a=TRUE und b=FALSE zuverlässig über den Else-Zweig (doppelt JF IF1 -> JF IF2)
LG Puretom