Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
programmieren:schritte:interpreter:start [2016/02/18 06:39] – martin | programmieren:schritte:interpreter:start [2021/12/29 10:40] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Interpreter ====== | ||
+ | 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 | ||
+ | * @throws Exception | ||
+ | */ | ||
+ | public double interpretiere(Knoten knoten) throws Exception { | ||
+ | |||
+ | 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) { | ||
+ | throw new Exception(" | ||
+ | + variablenbezeichner + " ist nicht bekannt." | ||
+ | } | ||
+ | |||
+ | return wert; | ||
+ | |||
+ | case zahl: | ||
+ | return knoten.getToken().getZahl(); | ||
+ | |||
+ | default: | ||
+ | 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 '' | ||
+ | |||
+ | <code java> | ||
+ | case text: | ||
+ | |||
+ | String variablenbezeichner = knoten.getToken().getText(); | ||
+ | |||
+ | Double wert = variablenbelegung.get(variablenbezeichner); | ||
+ | |||
+ | if (wert == null) { | ||
+ | throw new Exception(" | ||
+ | + variablenbezeichner + " ist nicht bekannt." | ||
+ | } | ||
+ | |||
+ | return wert; | ||
+ | </ | ||
+ | |||
+ | Ist der '' | ||
+ | |||
+ | <code java> | ||
+ | case zahl: | ||
+ | return knoten.getToken().getZahl(); | ||
+ | </ | ||
+ | |||
+ | Die Methode '' | ||
+ | |||
+ | <code java> | ||
+ | /** | ||
+ | * Nur zu Debuggingzwecken | ||
+ | * | ||
+ | * @return | ||
+ | * String, der alle Variablen zusammen mit ihrer Belegung in der Form | ||
+ | * variablenbezeichner = wert | ||
+ | * enthält. | ||
+ | */ | ||
+ | public String getBelegungAlsString() { | ||
+ | |||
+ | String s = ""; | ||
+ | |||
+ | for (String bezeichner : variablenbelegung.keySet().toArray( | ||
+ | new String[0])) { | ||
+ | s += bezeichner + " = " + variablenbelegung.get(bezeichner) + " | ||
+ | } | ||
+ | |||
+ | return s; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Hier geht's weiter mit einer Beschreibung des [[programmieren: |