int expression () { term (); if (p [j] == '+') expression(); } int term () { factor (); if (( p [j] == '(') || letter (p [j])) term (); } int factor () { if (p [j] == '(') { expression (); if (p [j] == ')') j++; else error (); } else if (letter (p [j])) { } else error (); if (p [j] != '*') ... else { } }Wenn man jetzt hinguckt, ich habe es ja am Anfang mit Expr (), Term (), Factor () gemacht, angelehnt an - Bakus Naur - ich habe ja auch gedacht - der Unterschied ist, dass es halt kein Malzeichen gibt. Also, dass es das gleiche ist - ohne Mal - dass die aneinander stehen.
expr ::= term | term + expr term ::= factor | factor * term factor ::= (expr) | id | const
Und wenn man das hinmacht ist das
expr () { term () if ( PLUS ) expr (); } term () { factor () if (MAL) term (); } factor () { if (ID)... if ( '(' ) expr if (! ')' Fehler }
das ist ja ähnlich. Wenn man kein Mal hat, dann lässt man es halt weg. An anderer Stelle, steht ja bei Robert Sedgewick, dass Compiler mit Vorrausschau gibt. Das heisst, erstens macht man bei Bakus Naur die Linksrekursion weg und wenn nicht, kann das oder auch in anderen Fällen und in dem nicht, bedeuten: Dass man mit Vorausschau arbeiten muss. Das heisst, die gehört ja eigentlich in den letzten Ausdruck. Es gibt so Sachen, da macht die eine Funktion eine Vorausschau für die andere und wenn das so ruft, ruft es die andere auf und die macht es noch mal
wenn man sich das jetzt anschaut - wenn man sich den Compiler vom regulären Ausdruck anschaut ist es ja genau - das ist ja so zu sagen, der Parser für Arithmetische Ausdrücke, ohne das Mal. Das Mal ist halt weg.
Nur, so lustig es klingt, das Mal hängt dann wieder mit der Klammer zusammen. Wie man sieht muss man nur an dieser Stelle modifizieren - Das heisst das ist genau das gleiche, wie Arithmetische ohne Mal
Jetzt ist das