3 Einfache Terme

3.1 Summen von Zahlen
3.2 Produkte von Zahlen
3.3 Summen von Produkten
3.4 Einfache Potenzen

Zum vorigen Kapitel Zum Inhaltsverzeichnis Zum nächsten Kapitel


3.1 Summen von Zahlen

Nun wollen wir daran gehen, die Rechenarten in unserem "TermInterpreter" zu implementieren. Wir beginnen mit der einfachsten Rechenart, nämlich der Summe. Dabei wollen wir den Begriff der "Summe" nicht gar so eng fassen und auch Differenzen gleich mit ins Boot holen. Das folgende Syntax-Diagramm zeigt, was wir (zunächst) unter einer Summe verstehen wollen:

Syntax-Diagramm für Summen von Zahlen

Eine Summe besteht also (vorläufig) aus einer oder mehreren Zahlen, die durch die Terminalzeichen '+' oder '-' getrennt sind. Beachten Sie, dass der Fall zugelassen ist, dass überhaupt kein Rechenzeichen vorkommt: dann besteht die Summe eben nur aus einer Zahl! Nicht zugelassen ist aber, dass die Summe keine Zahl enthält. Damit ist z.B. der leere String keine Summe.

Die folgende Funktion setzt dieses Syntax-Diagramm um:
     function Summe(var s: String; var res: Double): Boolean;
       var r1 : Double;
           c  : Char;
       begin
       If Zahl(s, res) then begin       { Ersten Summanden holen                  }
         Result := True;
         c := GetFirstChar(s);
         While c in ['+', '-'] do begin { Solange eine Strichrechnung folgt :     }
           Delete(s, 1, 1);                 { Rechenzeichen löschen               }
           If Zahl(s, r1) then begin        { Nächsten Summanden holen...         }
             If c = '+' then
               res := res + r1              { und zur aktuellen Summe addieren... }
             else
               res := res - r1;             { ...bzw. von ihr subtrahieren        }
             c := GetFirstChar(s);
             end
           else begin                       { Kein Summand vorhanden ? => Fehler! }
             Result := False;               {  LastErrorMsg wird in Zahl gesetzt  }
             c      := #0;                  { While-Schleife verlassen }
             end;
           end;
         end
       else                             { Kein Summand da ? => Fehler!            }
         Result := False;               {     LastErrorMsg wird in Zahl gesetzt   }
       end;



Aufgaben:

  1. Summ, summ, summ...

    Kopieren Sie Ihr TermTester-Projekt in ein neues Verzeichnis. Bauen Sie dann die obige Funktion Summe in die Unit TermInterpreter ein. Ändern Sie die Funktion TermWert nun so ab, dass sie statt Zahl nun Summe aufruft.

    Testen Sie das Programm aus, ob es die Berechnung von Zahlensummen und -differenzen nun komplett beherrscht!
    [Lösungsvorschlag]




3.2 Produkte von Zahlen

Völlig analog zur Summe sind Produkte aufgebaut. Wir wollen uns hier zunächst auf Produkte aus Zahlen beschränken, dafür aber auch gleich die Quotienten ebenfalls zu den Produkten rechnen. Das entsprechende Syntax-Diagramm sieht dann so aus:

Syntax-Diagramm für Produkte von Zahlen



Aufgaben:

  1. Prod, prod, prod.....

    Kopieren Sie Ihr TermTester-Projekt in ein neues Verzeichnis. Bauen Sie dann eine dem obigen Syntax-Diagramm entsprechende Funktion Produkt in die Unit TermInterpreter ein. Ändern Sie die Funktion TermWert nun so ab, dass sie statt Summe nun Produkt aufruft.

    Testen Sie das Programm aus, ob es die Berechnung von Zahlenprodukten und -quotienten nun komplett beherrscht!
    [Lösungsvorschlag]



3.3 Summen von Produkten


Beim Einbau der letzten Erweiterung zu den Produkten haben wir die zuvor eingebauten Fähigkeiten zur Summenberechnung leider wieder verloren. Das ist nicht ganz im Sinne des Erfinders! Eigentlich wollen wir ja gleichzeitig Summen und Produkte berechnen können, aber wie soll das gehen? In TermWert kann ja nur eine der beiden Funktionen (Summe, Produkt) aufgerufen werden.

Betrachten wir ein Beispiel, in dem sowohl Strich- als auch Punktrechnung vorkommt:
     2*5,2 - 2,7*0,3 + 5*37/7 
Wenn wir diesen Term gliedern, ist er zunächst einmal eine Summe. Die Summanden dieser Summe sind aber ihrerseits Produkte! Wir müssen also zur Beschreibung dieser Situation die folgenden, leicht geänderten Syntax-Diagramme benutzen:

Syntax-Diagramm für Summen von Produkten




Aufgaben:

  1. Alles auf einmal!

    Bauen Sie Ihre Unit TermInterpreter so um, dass sie dem neuen Syntax-Diagramm für "Summen von Produkten" entspricht. Machen Sie sich klar, welche der beiden Parser-Funktionen "Summe" und "Produkt" im Quelltext zuerst aufgeführt werden muss!
    Testen Sie dann den neuen TermInterpreter mit gemischter Punkt und Strich-Rechnung! Kennt der Interpreter schon die "Punkt vor Strich"-Regel?
    [Lösungsvorschlag]




3.4 Einfache Potenzen


Gehen wir die letzte noch fehlende Rechenart an: das Potenzieren! Eine Potenz besteht aus einer Basis und einem Exponenten. Wenn der Exponent fehlt, können wir in Gedanken "hoch 1" ergänzen, so dass sich auch eine gewöhnliche Zahl als Potenz auffassen lässt. Damit erhalten wir für Potenzen das folgende Syntax-Diagramm:

Syntax-Diagramm für Potenzen von Zahlen

Um nun die Erkennung der Potenzen in unseren TermInterpreter einzubauen, definieren wir die Produkte um: sie sollen in Zukunft nicht mehr einfach nur Zahlen als Faktoren haben, sondern eben Potenzen, gemäß dem folgenden Syntax-Diagramm:

Syntax-Diagramm für Produkte aus Potenzen

Man kann diesen Vorgang auch so auffassen, dass wir die Zahlen nun zu Potenzen verallgemeinern. Damit ist in den bisher schon implementierten Parser-Funktionen jeder Aufruf von Zahl durch einen Aufruf von Potenz zu ersetzen. Wenn Sie aber den Quelltext Ihrer TermInterpreter-Unit aufmerksam studieren, werden Sie bald bemerken, dass das gar nicht so viele Stellen sind, an denen da nachgearbeitet werden muss!



Aufgaben:

  1. Hoch, höher, am höchsten...

    Machen Sie Ihren TermInterpreter fit für die Potenzrechnung:

    1. Stellen Sie wieder eine Kopie Ihres "TermTester"-Projekts in einem neuen Verzeichnis her, damit Sie die alte Version behalten.

    2. Ergänzen Sie Ihre Unit "TermInterpreter" um eine Funktion Potenz, die das obige Syntax-Diagramm realisiert. Überlegen Sie sich genau, wo in Ihrem Quelltext diese Funktion positioniert werden muss! Binden Sie sie dann entsprechend in den TermInterpreter ein, indem Sie sie von der Funktion Produkt aus aufrufen.

    3. Testen Sie das Programm mit verschiedenen zulässigen und unzulässigen Eingaben!
      Woran liegt es eigentlich, dass dieser Interpreter schon die "Hoch vor Punkt"-Regel befolgt?
    [Lösungsvorschlag]




Zum vorigen Kapitel Zum Inhaltsverzeichnis Zum nächsten Kapitel