compilerbau:interpreter:start
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | compilerbau:interpreter:start [2024/08/31 12:03] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Interpreter ====== | ||
+ | <WRAP center round tip 60%> | ||
+ | Im folgenden findest Du die Beschreibung des Interpreters. Den [[.test: | ||
+ | </ | ||
+ | Ein Interpreter nimmt das Ergebnis des Parsevorgangs (i.d.R. einen Abstract Syntax Tree) und führt es aus. Für unsere einfache Programmiersprache (mathematische Terme mit +, -, *, /, (, ), Variablen und Zahlen) bedeutet dies, den Wert des gesamten Terms zu berechnen. Dazu muss der Interpreter natürlich die Belegungen der Variablen kennen, die im Term enthalten sind. Gespeichert werden sie in der gleichnamigen '' | ||
+ | |||
+ | |||
+ | <code java> | ||
+ | public class Interpreter { | ||
+ | |||
+ | /** | ||
+ | * Speichert Zuordnungen von Variablenbezeichnern zu Werten: | ||
+ | */ | ||
+ | private HashMap< | ||
+ | |||
+ | /** | ||
+ | * Belegt die Variable mit Bezeichner bezeichner mit dem Wert wert. | ||
+ | * | ||
+ | * @param bezeichner | ||
+ | * Bezeichner der Variablen | ||
+ | * @param wert | ||
+ | * Wert der Variablen | ||
+ | */ | ||
+ | public void belegeVariable(String bezeichner, double wert) { | ||
+ | variablenbelegung.put(bezeichner, | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | Befüllt wird die Variablenliste vor der Termberechnung mit der Methode '' | ||
+ | |||
+ | |||
+ | <code java> | ||
+ | /** | ||
+ | * Berechnet - ausgehend vom übergebenen Knoten - den Wert des Terms, der | ||
+ | * durch den Knoten und den darunterhängenden Teilbaum gegeben ist. | ||
+ | * | ||
+ | * @param knoten | ||
+ | * Wurzel des Teilbaums, dessen Termwert berechnet werden soll | ||
+ | * @return Wert des Terms | ||
+ | */ | ||
+ | public double interpretiere(Knoten knoten) { | ||
+ | |||
+ | switch(knoten.getToken().getTokenType()) { | ||
+ | case plus : | ||
+ | return interpretiere(knoten.getLinks()) | ||
+ | + interpretiere(knoten.getRechts()); | ||
+ | |||
+ | case minus : | ||
+ | return interpretiere(knoten.getLinks()) | ||
+ | - interpretiere(knoten.getRechts()); | ||
+ | |||
+ | case mal : | ||
+ | return interpretiere(knoten.getLinks()) | ||
+ | * interpretiere(knoten.getRechts()); | ||
+ | |||
+ | case geteilt : | ||
+ | return interpretiere(knoten.getLinks()) | ||
+ | / interpretiere(knoten.getRechts()); | ||
+ | |||
+ | case negation : | ||
+ | return - interpretiere(knoten.getLinks()); | ||
+ | |||
+ | case text : | ||
+ | |||
+ | String variablenbezeichner = knoten.getToken().getText(); | ||
+ | |||
+ | Double wert = variablenbelegung.get(variablenbezeichner); | ||
+ | |||
+ | if(wert == null) { | ||
+ | | ||
+ | + variablenbezeichner + " ist nicht bekannt.", | ||
+ | | ||
+ | } | ||
+ | |||
+ | return wert; | ||
+ | |||
+ | case zahl : | ||
+ | return knoten.getToken().getZahl(); | ||
+ | |||
+ | | ||
+ | return 0; // sollte nie vorkommen | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | Die Methode sieht sich den '' | ||
+ | <code java> | ||
+ | switch(knoten.getToken().getTokenType()) { | ||
+ | case plus : | ||
+ | return interpretiere(knoten.getLinks()) | ||
+ | + interpretiere(knoten.getRechts()); | ||
+ | </ | ||
+ | |||
+ | Ist der '' | ||
+ | |||
+ | < | ||
+ | case text : | ||
+ | |||
+ | String variablenbezeichner = knoten.getToken().getText(); | ||
+ | |||
+ | Double wert = variablenbelegung.get(variablenbezeichner); | ||
+ | |||
+ | if(wert == null) { | ||
+ | | ||
+ | + variablenbezeichner + " ist nicht bekannt.", | ||
+ | | ||
+ | } | ||
+ | |||
+ | return wert; | ||
+ | |||
+ | </ | ||
+ | |||
+ | Ist der '' | ||
+ | |||
+ | < | ||
+ | case zahl : | ||
+ | return knoten.getToken().getZahl(); | ||
+ | |||
+ | </ | ||
+ | |||
+ | Die Methode '' | ||
+ | |||
+ | < | ||
+ | | ||
+ | return variablenbelegung.toString(); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | [[..ebnf: |