Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
lehrkraefte:blc:informatik:ffprg1-2020:stack-rechner [2021/04/28 14:01] Ivo Blöchliger [Stack (Stapelspeicher)] |
lehrkraefte:blc:informatik:ffprg1-2020:stack-rechner [2021/06/09 09:12] (current) Ivo Blöchliger |
||
---|---|---|---|
Line 68: | Line 68: | ||
* Input ''< | * Input ''< | ||
* Ausgabe '' | * Ausgabe '' | ||
- | Die Idee ist, den Eingabe-String Zeichen um Zeichen durchzugehen und zu entscheiden, | + | Die Idee ist, den Eingabe-String Zeichen um Zeichen durchzugehen und zu entscheiden, |
</ | </ | ||
Line 88: | Line 88: | ||
</ | </ | ||
</ | </ | ||
+ | |||
+ | ====== Auswerten eines Infix-Ausdrucks ====== | ||
+ | Die Idee ist, das Auswerten eines Ausdrucks rekursiv zu Programmieren: | ||
+ | * Ein Ausdruck ist eine Summe | ||
+ | * Eine Summe ist ein Produkt, eventuell gefolgt von +/- und einem weiteren Produkt (etc.) | ||
+ | * Ein Produkt ist ein Atom, eventuell gefolgt von */ und einem weiteren Atom (etc.) | ||
+ | * Ein Atom ist eines von folgenden Dingen: | ||
+ | * Ein negatives Vorzeichen, gefolgt von einem Atom | ||
+ | * Eine öffnende Klammer, gefolgt von einem Ausdruck, gefolgt von einer schliessenden Klammer | ||
+ | * Eine Zahl | ||
+ | |||
+ | In Python kann das z.B. wie folgt umgesetzt werden: | ||
+ | <code python infix-parser.py> | ||
+ | import inspect | ||
+ | |||
+ | class Parser: | ||
+ | def __init__(self, | ||
+ | self.code = "" | ||
+ | self.debug = debug | ||
+ | self.position = "" | ||
+ | self.token = "" | ||
+ | self.error = "" | ||
+ | | ||
+ | def show(self, msg="" | ||
+ | if self.debug: | ||
+ | caller = inspect.stack()[1][3] | ||
+ | print(self.code+" | ||
+ | print(" | ||
+ | | ||
+ | | ||
+ | def nextToken(self): | ||
+ | self.token = "" | ||
+ | # Leerschläge ignorieren | ||
+ | while self.position< | ||
+ | self.position+=1 | ||
+ | # Am Ende angekommen? | ||
+ | if self.position> | ||
+ | self.error = " | ||
+ | return | ||
+ | # Tokens mit einem Zeichen | ||
+ | if self.code[self.position] in " | ||
+ | self.token = self.code[self.position] | ||
+ | self.position+=1 | ||
+ | return | ||
+ | # Zahlen | ||
+ | while self.position< | ||
+ | self.token += self.code[self.position] | ||
+ | self.position+=1 | ||
+ | | ||
+ | | ||
+ | | ||
+ | def atom(self): | ||
+ | self.show() | ||
+ | if self.token==" | ||
+ | self.nextToken() | ||
+ | a = self.ausdruck() | ||
+ | if self.token!=" | ||
+ | self.error = " | ||
+ | self.show(self.error) | ||
+ | return None | ||
+ | self.nextToken() | ||
+ | self.show(" | ||
+ | return a | ||
+ | if self.token==" | ||
+ | self.nextToken() | ||
+ | a = -self.atom() | ||
+ | self.show(" | ||
+ | return a | ||
+ | a = float(self.token) | ||
+ | self.nextToken() | ||
+ | self.show(" | ||
+ | return a | ||
+ | | ||
+ | | ||
+ | def produkt(self): | ||
+ | self.show() | ||
+ | a = self.atom() | ||
+ | while self.error=="" | ||
+ | op = self.token | ||
+ | self.nextToken() | ||
+ | b = self.atom() | ||
+ | if op==" | ||
+ | a*=b | ||
+ | else: | ||
+ | a/=b | ||
+ | self.show(" | ||
+ | return a | ||
+ | | ||
+ | def summe(self): | ||
+ | self.show() | ||
+ | a = self.produkt() | ||
+ | self.show() | ||
+ | while self.error=="" | ||
+ | op = self.token | ||
+ | self.nextToken() | ||
+ | b = self.produkt() | ||
+ | if op==" | ||
+ | a+=b | ||
+ | else: | ||
+ | a-=b | ||
+ | self.show(" | ||
+ | return a | ||
+ | | ||
+ | def ausdruck(self): | ||
+ | return self.summe() | ||
+ | |||
+ | def evaluate(self, | ||
+ | self.code = code | ||
+ | self.position = 0 | ||
+ | self.error = "" | ||
+ | self.nextToken() | ||
+ | return self.ausdruck() | ||
+ | | ||
+ | | ||
+ | | ||
+ | p = Parser(False) | ||
+ | for test in [" | ||
+ | r = p.evaluate(test) | ||
+ | rr = eval(test) | ||
+ | if (r==rr): | ||
+ | print(test+" | ||
+ | else: | ||
+ | print(" | ||
+ | | ||
+ | |||
+ | </ | ||
+ | |||
+ |