#!/usr/bin/env python
#
# Aufgabe 1: Auswerten von Ausdrücken
# Python-Kurs SS 2003: http://www.inf.tu-dresden.de/python-kurs/
# Josef Spillner <js177634@inf.tu-dresden.de>
# Parser-Funktionen einbinden
import parser
# Fehlercodes
errstr = {
'math' : "arithmetic error(s):\t",
'rec' : "recursive variable(s):\t",
'undef' : "unknown variable(s):\t"
}
# Initialisierung
pstate = 1 # Parser aktiv
vars = {} # Hashtabelle aller Variablen
rec = {} # Hashtabelle für Rekursionen
reprint = 1 # Verschönerung der Ausgabe
behaviour = "compliant" # Abbruchverhalten (fast oder compliant)
errors = {} # Hashtabelle für Fehlermeldungen
# Evaluierung vorverarbeiteter Ausdrücke
def evaluate(s):
# Zahl
if type(s) == type(0.0):
return s
# Variable
if type(s) == type(""):
# Rekursion ausschließen
if vars.has_key(s):
if rec.has_key(s):
if behaviour == "fast":
return [errstr['rec'] + s]
else:
errors['rec'][s] = s
return 0
rec[s] = s;
ret = evaluate(vars[s])
del rec[s]
return ret
else:
if behaviour == "fast":
return [errstr['undef'] + s]
else:
errors['undef'][s] = s
return 0
# Initialisierung
op = s[0]
ret = evaluate(s[1])
if type(ret) == type([]):
return ret
# Abarbeitung einer Operation
for i in s[2:]:
x = evaluate(i)
if type(x) == type([]):
return x
if op == "+":
ret = ret + x
elif op == "-":
ret = ret - x
elif op == "*":
ret = ret * x
elif op == "/":
if x != 0:
ret = ret / x
else:
if behaviour == "fast":
return [errstr['math'] + "division by zero"]
else:
errors['math']['zero'] = "division by zero"
ret = 0
# Rückgabe
return ret
# Hauptprogramm
while pstate:
# Eingabe der Daten
l = raw_input(">")
if reprint:
q = "'" + l + "'"
q = q.replace("\t", "\\t")
print q
# Programm beenden?
if l == "%":
pstate = 0
else:
# Eingabe normalisieren
l = l.replace(" ", "")
l = l.replace("\t", "")
# Alles außer Kommentare und Leerzeilen auswerten
if l != "" and l[0] != "#":
# Zuweisungsoperation oder Berechnung
if l.count("=") > 0:
(var, value) = l.split("=")
if not parser.is_identifier(var):
print var +" is not an identifier"
else:
# Zuweisung oder Löschung
if value:
vars[var] = parser.parse_eq(value)
else:
if vars.has_key(var):
del vars[var]
else:
print var + " is not set"
if not reprint:
print
else:
# Berechnen des Parse-Baumes
list = parser.parse_eq(l)
# Parser-Fehler erkennen
if type(list) == type(()):
print list[0]
else:
if behaviour == "compliant":
errors['rec'] = {}
errors['undef'] = {}
errors['math'] = {}
result = evaluate(list)
# Berechnungs-Fehler erkennen
if type(result) == type([]):
print result[0]
else:
if behaviour == "compliant":
if len(errors['math']) == 0 and len(errors['undef']) == 0 and len(errors['rec']) == 0:
print result
else:
for i in errors['math'].keys():
print errstr['math'] + errors['math'][i]
for j in ["undef", "rec"]:
if len(errors[j]) > 0:
x = errstr[j]
y = ""
list = errors[j].keys()
list.sort()
for i in list:
if len(y) > 0:
y = y + ", "
y = y + errors[j][i]
print x + y
else:
print result
else:
if not reprint:
print
syntax highlighted by Code2HTML, v. 0.9.1