Expression (arithmetische Ausdrücke)

Werbung
1
Expression (arithmetische Ausdrücke)
Beispiel
$ CLASSPATH=. java Expression
2+3*4
14.0
Grammatikregeln -- Backus-Naur-Form (BNF)
Formal besteht eine Grammatik aus einer Menge von Eingabesymbolen, einer Menge von
Grammatikbegriffen, daraus einem Startbegriff, und einer Menge von Regeln, das heißt,
bestimmten Paaren von Folgen von Grammatikbegriffen und Eingabesymbolen; alle Mengen
und Folgen müssen endlich sein.
Typischerweise schreibt man nur die Regeln auf und verlangt bei kontextfreien Grammatiken,
daß die linke Seite einer Regel immer ein Grammatikbegriff sein muß. Nach Konvention steht
der Startbegriff auf der linken Seite der ersten Regel und man faßt rechte Seiten zum gleichen
Grammatikbegriff als Alternativen zusammen. Die Wiederholungen der Syntaxgraphen muß
man durch rekursive Verweise modellieren. Für arithmetische Ausdrücke sieht das etwa so
aus:
sum : product | sum ’+’ product | sum ’-’ product ;
product : term | product ’*’ term | product ’/’ term | product ’%’ term ;
term : ’+’ term | ’-’ term | ’(’ sum ’)’ | Number ;
trennt linke und rechte Seite, | trennt Alternativen, ; steht nach allen rechten Seiten zum
gleichen Grammatikbegriff. Eingabesymbole werden mit einfachen Anführungszeichen zitiert.
Da Number nicht links vorkommt, muß Number (implizit) eine Klasse von Eingabesymbolen
repräsentieren. Man könnte auch folgende Regeln hinzufügen:
:
Number : digit | Number digit ;
digit : ’0’ | ’1’ | ’2’ | ’3’ | ’4’ | ’5’ | ’6’ | ’7’ | ’8’ | ’9’ ;
In unserem Beispiel liefert das Scanner-Objekt als Objekt einer Unterklasse von
java.io.StreamTokenizer das Eingabesymbol Number als ein erkanntes Symbol, aber auch alle
anderen Zeichen wie +, -, usw. einzeln.
2
Grammatikregeln -- Erweiterte Backus-Naur-Form (EBNF)
Syntaxgraphen korrespondieren wesentlich intuitiver zu Grammatikregeln, wenn man sich auf
Schreibweisen für Wiederholungen und relativ standardisierte Graphen einigt, zum Beispiel
one
alt
two
alt : ( one | two ) ;
( )
|
zur Zusammenfassung
für Alternativen
{ }
einmal oder mehrfach
[ ]
höchstens einmal
some
body
some : { body } ;
opt
body
opt : [ body ] ;
many
body
many : [{ body }] ;
kombiniert: beliebig oft
EBNF ist als Schreibweise für Wiederholungen eine verkürzende Schreibweise für BNF. Für die
meisten Menschen ist EBNF intuitiver als BNF. Die traditionelle Schreibweise für
Wiederholungen in EBNF hat Probleme bei 1-n Wiederholungen. Hier muß man Teile der
Grammatik verdoppeln.
konventionelle Schreibweise:
{...}
0-n mal wiederholen
[...]
0 oder 1 mal erkennen
unsere Schreibweise:
{...}
1-n mal wiederholen
[...]
0 oder 1 mal erkennen
Analog zu den folgenden Syntaxgraphen sehen arithmetische Ausdrücke dann etwa so aus:
sum : product [{ (’+’|’-’) product }];
product : term [{ (’*’|’/’|’%’) term }];
term : [{’+’|’-’}] ( Number | ’(’ sum ’)’ ) ;
3
Syntaxgraph
Die zu der EBNF-Grammatik der arithmetischen Ausdrücke
sum : product [{ (’+’|’-’) product }];
product : term [{ (’*’|’/’|’%’) term }];
term : [{’+’|’-’}] ( Number | ’(’ sum ’)’ ) ;
korrespondierenden Syntaxgraphen kennen Sie bereits (teilweise) aus der Vorlesung:
rekursiver Abstieg
Idee: Pro Graph wird eine Funktion implementiert, die diesen Teil der Grammatik erkennt. Die
Funktionen rufen sich gegenseitig (auch rekursiv) auf. Man steigt so in Richtung der Blätter
(auch rekursiv) in der Erkennung ab. Hat die Funktion einen Teil erkannt, führt sie
entsprechende Aktionen aus. Im Expression-Beispiel könnte das Ergebnis des Teilausdrucks
sofort berechnet werden, oder es wird wie in der Vorlesung ein Baum gebaut, der die erkannte
Informationen repräsentiert. Wenn alle Knoten und Blätter im Baum Unterklassen von
java.lang.Number sind, kann der Wert des arithmetischen Ausdrucks über die Methoden der
Number-Klasse in verschiedenen Typen berechnet werden.
4
Bäume für arithmetische Ausdrücke
Hier zwei Beispiel für Bäume, die einen arithm. Ausdruck speichern. Das Programm gibt nun
auch den Baum textuell aus.
• 5-6*8:
-
5
*
6
8
$ pwd; make stdin
...../java99/Uebungen/Blatt6/AddOn/expr
CLASSPATH=.. java expr.Expression
5-6*8
tree:
BinarySub
5
BinaryMul
6
8
-43.0
• 9-+-9*-(-3*(3-2))
9
*
-
-
9
*
3
3
2
Expression kann (noch) nicht / und % als binäre und + und - als unäre Operatoren. Auch das
Klammern von Ausdrücken bleibt noch zu tun. Beides wird eine Aufgabe des neuen
Aufgabenblatts sein.
Herunterladen