Station - Ein Interpreter für strukturierte MiniPython-Programme

Aufgabe des Interpreters

Aufgabe des Interpretes ist es, strukturierte MiniPython-Programme (Schritt für Schritt) auszuführen.

Die Arbeitsweise des Interpreters soll am dolgenden Beispiel-Programm verdeutlicht werden.

[
  ['=', ('VAR', 'x'), [('ZAHL', '9')]],
  ['=', ('VAR', 'y'), [('ZAHL', '6')]],
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]

Der Interpreter transformiert jeweils das noch auszuführende Restprogramm und den aktuellen Variablenzustand:

Restprogramm:
[
  ['=', ('VAR', 'x'), [('ZAHL', '9')]],
  ['=', ('VAR', 'y'), [('ZAHL', '6')]],
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]
Variablenzustand:
{}

------------------------------------------------------------------

Restprogramm:
[
  ['=', ('VAR', 'y'), [('ZAHL', '6')]],
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]

Variablenzustand:
{'x' -> 9}

------------------------------------------------------------------

Restprogramm:
[
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]
Variablenzustand:
{'x' -> 9, 'y' -> 6}

----------------------- Bedingung wahr ---------------------------

Restprogramm:
[
  ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
    ], 
    [
      ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
    ]
  ],
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]
Variablenzustand:
{'x' -> 9, 'y' -> 6}

----------------------- Bedingung falsch ---------------------------

Restprogramm:
[
  ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]],
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]
Variablenzustand:
{'x' -> 9, 'y' -> 6}

------------------------------------------------------------------

Restprogramm:
[
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]
Variablenzustand:
{'x' -> 3, 'y' -> 6}

------------------------------------------------------------------

...

------------------------------------------------------------------

Restprogramm:
[
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]
Variablenzustand:
{'x' -> 3, 'y' -> 3}

---------------------- Bedingung falsch --------------------------

Restprogramm:
[
]
Variablenzustand:
{'x' -> 3, 'y' -> 3}

Alles klar?

Implementierung des Interpreters

Zur Verwaltung des Variablenzustans wird ein Objekt der Klasse Variablenzustand benutzt. Dieses Objekt stellt Operationen bereit, mit denen ein Variablenwert ermittelt und auch ein Variablenwert neu gesetzt werden kann.

class Variablenzustand(object):
    def __init__(self):
        self.variablen = {}

    def initVariablen(self, v):
        self.variablen = {}
        for bezeichner in v:
            self.variablen[bezeichner] =0

    def getVariable(self, bezeichner):
        return self.variablen[bezeichner]

    def setVariable(self, bezeichner, wert):
        self.variablen[bezeichner] = wert

    def setVariablenzustand(self, zustand):
        self.variablen = zustand

Der Interpreter wird durch ein Objekt der Klasse InterpreterWhileList realisiert. Dieses Objekt verfügt insbesondere über eine Methode anweisungAusfuehren, die letztlich für das Auswerten von Anweisungen zuständig ist.

class InterpreterWhileList(object):
    def __init__(self, v):
        self.programm = None
        self.variablenzustand = v

    def setProgramm(self, p):
        self.programm = p

    def getProgramm(self):
        return self.programm

    def getVariablenzustand(self):
        return self.variablenzustand

    def anweisungAusfuehren(self):
        if self.programm != []:
            anweisung = self.programm[0]
            bezeichner = anweisung[0]
            if bezeichner == "=":
                self.verarbeiteZuweisung(anweisung)
                self.programm = self.programm[1:]
            if bezeichner == "pass":
                self.programm = self.programm[1:]
            elif bezeichner == "while":
                bedingung = anweisung[1]
                if self.verarbeiteBedingung(bedingung):
                    self.programm = anweisung[2] + self.programm
                else:
                    self.programm = self.programm[1:]
            elif bezeichner == "if":
                bedingung = anweisung[1]
                if self.verarbeiteBedingung(bedingung):
                    self.programm = anweisung[2] + self.programm[1:]
                else:
                    self.programm = anweisung[3] + self.programm[1:]

    def verarbeiteZuweisung(self, anweisung):
        variable = anweisung[1][1]
        term = anweisung[2]
        self.variablenzustand.setVariable(variable, self.wertTerm(term))

    def wertOperand(self, operand):
        if operand[0] == "ZAHL":
            return int(operand[1])
        elif operand[0] == "VAR":
            return self.variablenzustand.getVariable(operand[1])

    def wertTerm(self, term):
        if len(term) == 1:
            return self.wertOperand(term[0])
        else:
            wertOperand1 = self.wertOperand(term[1])
            wertOperand2 = self.wertOperand(term[2])
            op = term[0]
            if op == "+":
                return wertOperand1 + wertOperand2
            elif op == "-":
                return wertOperand1 - wertOperand2
                
    def verarbeiteBedingung(self, bedingung):
        wertOperand1 = self.wertOperand(bedingung[1])
        wertOperand2 = self.wertOperand(bedingung[2])
        rel = bedingung[0]
        if rel == "==":
            return (wertOperand1 == wertOperand2)
        elif rel == "!=":
            return (wertOperand1 != wertOperand2)
        elif rel == "<":
            return (wertOperand1 < wertOperand2)
        elif rel == "<=":
            return (wertOperand1 <= wertOperand2)

Objekte der vorgestellten Klassen können jetzt direkt genutzt werden, um strukturierte MiniPython-Programme auszuführen.

from interpreterWhileList import *
from variablenzustand import *

# Testprogramm
programm = [
  ['=', ('VAR', 'x'), [('ZAHL', '9')]],
  ['=', ('VAR', 'y'), [('ZAHL', '6')]],
  ['while', ['!=', ('VAR', 'x'), ('VAR', 'y')], 
    [
      ['if', ['<=', ('VAR', 'x'), ('VAR', 'y')], 
        [
          ['=', ('VAR', 'y'), ['-', ('VAR', 'y'), ('VAR', 'x')]]
        ], 
        [
          ['=', ('VAR', 'x'), ['-', ('VAR', 'x'), ('VAR', 'y')]]
        ]
      ]
    ]
  ]
]

# Erzeugung des Interpreters
variablenzustand = Variablenzustand()
interpreter = InterpreterWhileList(variablenzustand)
# Initialisierung des Programms
interpreter.setProgramm(programm)

# Ausführung des Programms und Ausgabe der Zustände
print('Restprogramm:')
print(interpreter.programm)
print('Variablenzustand')
print(variablenzustand.variablen)
print('---------------------------')
while interpreter.getProgramm() != []:
    interpreter.anweisungAusfuehren()
    print('Restprogramm:')
    print(interpreter.programm)
    print('Variablenzustand')
    print(variablenzustand.variablen)
    print('---------------------------')

Aufgabe 1

Probiere das selbst einmal aus. Teste verschiedene strukturierte MiniPython-Programme.

X

Fehler melden

X

Suche