Skip to content
Snippets Groups Projects
Commit e7588d06 authored by Chris's avatar Chris
Browse files

Feature: Hilfemeldung für interpret funktionen. closes #1.

parent 334130be
Branches
No related tags found
1 merge request!1Master
%% Cell type:markdown id: tags:
# GOTO-Programme
Die letzte Programmiersprache, die wir betrachten ist GOTO.
Die Syntax eines GOTO-Programms ist wie folgt definiert:
* Ein GOTO-Programm besteht aus Markierten Anweisungen $M_1: A_1; M_2: A_2; ... M_m: A_m;$
* Die Markierungen beginnen bei 1 und steigen immer um 1 an.
* Jede Anweisung wird durch 1 Semicolon abgeschlossen (ein GOTO-Programm endet immer mit einem Semicolon)
* Anweisungen $A_i$ dürfen dabei sein:
* Zuweisung $x_i:=x_j+c$, $x_i:=x_j-c$ und $x_i:=c$ für $c\in\mathbb{N}$
* Unbedingter Sprung $GOTO\ M_i$
* Bedingter Sprung $IF\ x_i=c\ THEN\ GOTO\ M_j$
* Abbruchanweisung $HALT$
%% Cell type:markdown id: tags:
Die Semantik eines GOTO-Programms lässt sich wie folgt verstehen:
Das Programm startet an der mit $M_1$ markierten Anweisung und führt diese aus.
Ist diese eine Zuweisung oder ein bedingter Sprung, dessen Bedingung nicht erfüllt ist, so wird mit der nächsten Anweisung weiter gemacht.
Wenn ein unbedingter Sprung oder ein bedingter Sprung miterfüllter Bedingung ausgeführt wird, wird an der entsprechenden Markierung fortgefahren.
Bei einer Abbruchanweisung hält das Programm sofort an und der Wert von $x_0$ wird zurück gegeben.
Da ein GOTO-Programm stets von einem $HALT$ beendet wird, ist die letze Anweisung in einem GOTO-Programm immer $HALT$ oder $GOTO$.
%% Cell type:markdown id: tags:
Eine Funktion heißt GOTO-berechenbar, falls es ein GOTO-Programm gibt, das mit $n_1,...,n_k$ in den Variablen $x_1,...,x_k$ gestartet wird und mit $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$ endet, falls $f(n_1,n_2,...,n_k)$ definiert ist. Andernfalls stoppt das GOTO-Programm nicht.
Ein Beispiel dafür ist die 2er-Potenz $f(n) = n^2$:
%% Cell type:code id: tags:
``` python
%run ./Interpreter/gotointerpreter.py
```
%% Output
Help on function interpret in module __main__:
interpret(program, timeout=60)
Funktion zum Ausführen eines GOTO-Programms.
:param program: GOTO-Programm als String 'M1: A1; M2: A2; ... Mn: An;'
:param timeout: Zeit nach der die Ausführung eines Programms pausiert wird.
Gibt eine Möglichkeit zum Abbrechen bei einer Endlosschleife.
Ein Wert von 0 deaktiviert den Timeout.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem GOTO-Programm zurück.
:usage interpret('M1: x0 := x0 + 1; M2: IF x0 = 10 THEN GOTO M4; M3: GOTO M1; M4: HALT;')
%% Cell type:code id: tags:
``` python
interpret('''
M1:x1:=6;
M2:x2:=8;
M3:x0:=x1+0;
M4:IF x2=0 THEN GOTO M8;
M5:x0:=x0 + 1;
M6:x2:=x2 − 1;
M7:GOTO M4;
M8:HALT;''')
```
%% Output
14
%% Cell type:code id: tags:
``` python
interpret('M1: x0 := x0 + 1; M2: IF x0 = 10 THEN GOTO M4; M3: GOTO M1; M4: HALT;')
```
%% Output
10
...@@ -283,5 +283,16 @@ class GOTOInterpreter: ...@@ -283,5 +283,16 @@ class GOTOInterpreter:
def interpret(program, timeout=60): def interpret(program, timeout=60):
"""Funktion zum Ausführen eines GOTO-Programms.
:param program: GOTO-Programm als String 'M1: A1; M2: A2; ... Mn: An;'
:param timeout: Zeit nach der die Ausführung eines Programms pausiert wird.
Gibt eine Möglichkeit zum Abbrechen bei einer Endlosschleife.
Ein Wert von 0 deaktiviert den Timeout.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem GOTO-Programm zurück.
:usage interpret('M1: x0 := x0 + 1; M2: IF x0 = 10 THEN GOTO M4; M3: GOTO M1; M4: HALT;')"""
interpreter = GOTOInterpreter(timeout) interpreter = GOTOInterpreter(timeout)
return interpreter.interpret(program) return interpreter.interpret(program)
if __name__ == '__main__':
help(interpret)
...@@ -2,6 +2,7 @@ import lexer ...@@ -2,6 +2,7 @@ import lexer
import sys import sys
import operator import operator
import re import re
from IPython.display import clear_output
class ErrorHandler: class ErrorHandler:
...@@ -21,6 +22,7 @@ class ErrorHandler: ...@@ -21,6 +22,7 @@ class ErrorHandler:
self.line_number += value self.line_number += value
def handle_break(self): def handle_break(self):
clear_output(wait=True)
print('BREAK in Zeile ' + str(self.line_number)) print('BREAK in Zeile ' + str(self.line_number))
print('Aktueller Zustand:') print('Aktueller Zustand:')
for k, v in self.interpreter.values.items(): for k, v in self.interpreter.values.items():
...@@ -249,5 +251,13 @@ class LOOPInterpreter: ...@@ -249,5 +251,13 @@ class LOOPInterpreter:
def interpret(program): def interpret(program):
"""Funktion zum Ausführen eines LOOP-Programms.
:param program: LOOP-Programm als String 'x1 := 4; LOOP x1 DO x0:=x0+1 END'
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem LOOP-Programm zurück.
:usage interpret('x1:=10; x2:=8; x0:=x2+0; LOOP x1 DO x0:=x0+1 END')"""
interpreter = LOOPInterpreter() interpreter = LOOPInterpreter()
return interpreter.interpret(program) return interpreter.interpret(program)
if __name__ == '__main__':
help(interpret)
...@@ -2,6 +2,7 @@ import lexer ...@@ -2,6 +2,7 @@ import lexer
from loopinterpreter import LOOPInterpreter, ErrorHandler from loopinterpreter import LOOPInterpreter, ErrorHandler
import re import re
import signal import signal
from IPython.display import clear_output
class Timeout: class Timeout:
...@@ -18,6 +19,7 @@ class Timeout: ...@@ -18,6 +19,7 @@ class Timeout:
def interrupt(self, sig_num, stack_frame): def interrupt(self, sig_num, stack_frame):
try: try:
clear_output(wait=True)
abort = input('''Die Funktion rechnet relativ lange. abort = input('''Die Funktion rechnet relativ lange.
Vielleicht liegt eine Endlosschleife vor. Vielleicht liegt eine Endlosschleife vor.
Möchten sie abbrechen? [J,n]:''') Möchten sie abbrechen? [J,n]:''')
...@@ -184,5 +186,16 @@ class WHILEInterpreter(LOOPInterpreter): ...@@ -184,5 +186,16 @@ class WHILEInterpreter(LOOPInterpreter):
def interpret(program, timeout=60): def interpret(program, timeout=60):
"""Funktion zum Ausführen eines WHILE-Programms.
:param program: WHILE-Programm als String 'x1:=10; x2:=8; x0:=x2+0; WHILE x1 /=0 DO x0:=x0+1; x1:=x1-1 END'
:param timeout: Zeit nach der die Ausführung eines Programms pausiert wird.
Gibt eine Möglichkeit zum Abbrechen bei einer Endlosschleife.
Ein Wert von 0 deaktiviert den Timeout.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem WHILE-Programm zurück.
:usage interpret('x1:=10; x2:=8; x0:=x2+0; WHILE x1 /=0 DO x0:=x0+1; x1:=x1-1 END')"""
interpreter = WHILEInterpreter(timeout) interpreter = WHILEInterpreter(timeout)
return interpreter.interpret(program) return interpreter.interpret(program)
if __name__ == '__main__':
help(interpret)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# LOOP-Programme # LOOP-Programme
Im Folgenden werden wir Konzepte von prozeduralen Programmiersprachen kennenlernen. Als erste einfache Programmiersprache betrachten wir LOOP. Im Folgenden werden wir Konzepte von prozeduralen Programmiersprachen kennenlernen. Als erste einfache Programmiersprache betrachten wir LOOP.
Die Syntax solcher Programme ist definiert durch: Die Syntax solcher Programme ist definiert durch:
* $x_i := c$, $x_i := x_j + c$ und $x_i := x_j - c$ mit $i,j,c \in \mathbb{N}$ sind LOOP-Programme * $x_i := c$, $x_i := x_j + c$ und $x_i := x_j - c$ mit $i,j,c \in \mathbb{N}$ sind LOOP-Programme
* Falls $P_1$ und $P_2$ LOOP-Programme sind ist $P_1; P_2$ ein LOOP-Programm * Falls $P_1$ und $P_2$ LOOP-Programme sind ist $P_1; P_2$ ein LOOP-Programm
* Falls $P$ ein LOOP-Programm ist und $x_i$ nicht in $P$ vorkommt, so ist auch $LOOP\ x_i\ DO\ P\ END$ ein LOOP-Programm. * Falls $P$ ein LOOP-Programm ist und $x_i$ nicht in $P$ vorkommt, so ist auch $LOOP\ x_i\ DO\ P\ END$ ein LOOP-Programm.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Die Semantik von LOOP-Programmen lässt sich wie folgt verstehen: Die Semantik von LOOP-Programmen lässt sich wie folgt verstehen:
* Wenn eine k-stellige Funktion $f(n_1,n_2,...,n_k)$ berechnet wird sind die Startwerte $n_1,...,n_k\in\mathbb{N}$ in den Variablen $x_1,...,x_k$. * Wenn eine k-stellige Funktion $f(n_1,n_2,...,n_k)$ berechnet wird sind die Startwerte $n_1,...,n_k\in\mathbb{N}$ in den Variablen $x_1,...,x_k$.
* Die restlichen Variablen starten mit dem Wert 0. * Die restlichen Variablen starten mit dem Wert 0.
* Zuweisungen $x_i := c$, $x_i := x_j + c$ werden wie üblich interpretiert. Bei $x_i := x_j - c$ wird $x_i$ auf 0 gesetzt, falls $c\geq x_j$ ist. * Zuweisungen $x_i := c$, $x_i := x_j + c$ werden wie üblich interpretiert. Bei $x_i := x_j - c$ wird $x_i$ auf 0 gesetzt, falls $c\geq x_j$ ist.
* Bei $P_1; P_2$ wird erst $P_1$ und dann $P_2$ ausgeführt. * Bei $P_1; P_2$ wird erst $P_1$ und dann $P_2$ ausgeführt.
* Das Programm $P$ in $LOOP\ x_i\ DO\ P\ END$ wird so oft ausgeführt, wie der Wert von $x_i$ zu Beginn des LOOPs ist. * Das Programm $P$ in $LOOP\ x_i\ DO\ P\ END$ wird so oft ausgeführt, wie der Wert von $x_i$ zu Beginn des LOOPs ist.
* Das Programm stoppt mit dem Wert $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$. * Das Programm stoppt mit dem Wert $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Eine Funktion heißt LOOP-berechenbar, falls es ein LOOP-Programm gibt, das mit $n_1,...,n_k$ in den Variablen $x_1,...,x_k$ gestartet wird und mit $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$ endet. Eine Funktion heißt LOOP-berechenbar, falls es ein LOOP-Programm gibt, das mit $n_1,...,n_k$ in den Variablen $x_1,...,x_k$ gestartet wird und mit $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$ endet.
Ein Beispiel dafür ist die Addition $f(n_1, n_2) = n_1 + n_2$: Ein Beispiel dafür ist die Addition $f(n_1, n_2) = n_1 + n_2$:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
%run Interpreter/loopinterpreter.py %run Interpreter/loopinterpreter.py
``` ```
%% Output
Help on function interpret in module __main__:
interpret(program)
Funktion zum Ausführen eines LOOP-Programms.
:param program: LOOP-Programm als String 'x1 := 4; LOOP x1 DO x0:=x0+1 END'
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem LOOP-Programm zurück.
:usage interpret('x1:=10; x2:=8; x0:=x2+0; LOOP x1 DO x0:=x0+1 END')
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
interpret(''' interpret('''
x1:=3; x1:=3;
x2:=6; x2:=6;
LOOP x1 DO LOOP x1 DO
x2≔ x2 + 1 x2≔ x2 + 1
END; END;
x0≔ x2 + 0''') x0≔ x2 + 0''')
``` ```
%% Output %% Output
9 9
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Für die Visualisierung und das Verständnis haben wir die Syntax um das Keyword BREAK ereitert. Für die Visualisierung und das Verständnis haben wir die Syntax um das Keyword BREAK ereitert.
Wenn dieses erreicht wird, wird der Zustand ausgegeben und man wird gefragt, ob fortgefahren oder abgebrochen werden soll. Wenn dieses erreicht wird, wird der Zustand ausgegeben und man wird gefragt, ob fortgefahren oder abgebrochen werden soll.
Dabei werden Variablen, denen noch kein Wert zugewiesen wurde ignoriert. Dabei werden Variablen, denen noch kein Wert zugewiesen wurde ignoriert.
Im folgenden Fall wird $x_0$ nicht verändet, da $x_2$ nie zugewiesen wurde und die Schleife somit nicht ausgeführt wird. Im folgenden Fall wird $x_0$ nicht verändet, da $x_2$ nie zugewiesen wurde und die Schleife somit nicht ausgeführt wird.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
interpret(''' interpret('''
x1:=5; x1:=5;
x0:=2; x0:=2;
LOOP x2 DO LOOP x2 DO
x0:=1 x0:=1
BREAK BREAK
END END
''') ''')
``` ```
%% Output %% Output
BREAK in Zeile 5 BREAK in Zeile 5
Aktueller Zustand: Aktueller Zustand:
Variable x1: 5 Variable x1: 5
Variable x0: 2 Variable x0: 2
Drücke ENTER zum Fotfahren oder schreibe EXIT zum Beenden: Drücke ENTER zum Fotfahren oder schreibe EXIT zum Beenden:
2 2
......
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# WHILE-Programme # WHILE-Programme
Um LOOP-Programme zu erweitern führen wir eine WHILE-Schleife ein und erhalten damit die WHILE-Programme. Um LOOP-Programme zu erweitern führen wir eine WHILE-Schleife ein und erhalten damit die WHILE-Programme.
Die Syntax solcher WHILE-Programme ist definiert durch: Die Syntax solcher WHILE-Programme ist definiert durch:
* Jedes LOOP-Programm ist ein WHILE-Programm * Jedes LOOP-Programm ist ein WHILE-Programm
* Falls $P_1$ und $P_2$ WHILE-Programme sind ist $P_1; P_2$ ein WHILE-Programm * Falls $P_1$ und $P_2$ WHILE-Programme sind ist $P_1; P_2$ ein WHILE-Programm
* Falls $P$ ein WHILE-Programm ist, so ist auch $WHILE\ x_i\neq 0\ DO\ P\ END$ ein WHILE-Programm. * Falls $P$ ein WHILE-Programm ist, so ist auch $WHILE\ x_i\neq 0\ DO\ P\ END$ ein WHILE-Programm.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Die Semantik von WHILE-Programmen ist analog zu der von LOOP-Programmen zu verstehen. Die Semantik von WHILE-Programmen ist analog zu der von LOOP-Programmen zu verstehen.
Der einzige Unterschied sind die WHILE-Schleifen. Der einzige Unterschied sind die WHILE-Schleifen.
Das Programm P in einer WHILE-Schleife wird solange wiederholt, wie $x_i \neq 0$ ist. Das Programm P in einer WHILE-Schleife wird solange wiederholt, wie $x_i \neq 0$ ist.
Dabei ist zu beachten, dass $x_i$ in P vorkommen sollte, da es sonst nicht verändert wird. Dabei ist zu beachten, dass $x_i$ in P vorkommen sollte, da es sonst nicht verändert wird.
Dies ist ein Unterschied zu LOOP-Programmen, da $x_i$ in dem entsprechenden LOOP nicht verwendet werden darf. Dies ist ein Unterschied zu LOOP-Programmen, da $x_i$ in dem entsprechenden LOOP nicht verwendet werden darf.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Eine Funktion heißt WHILE-berechenbar, falls es ein WHILE-Programm gibt, das mit $n_1,...,n_k$ in den Variablen $x_1,...,x_k$ gestartet wird und mit $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$ endet, falls $f(n_1,n_2,...,n_k)$ definiert ist. Andernfalls stoppt das WHILE-Programm nicht. Eine Funktion heißt WHILE-berechenbar, falls es ein WHILE-Programm gibt, das mit $n_1,...,n_k$ in den Variablen $x_1,...,x_k$ gestartet wird und mit $f(n_1,n_2,...,n_k)$ in der Variablen $x_0$ endet, falls $f(n_1,n_2,...,n_k)$ definiert ist. Andernfalls stoppt das WHILE-Programm nicht.
Ein Beispiel dafür ist die 2er-Potenz $f(n) = n^2$: Ein Beispiel dafür ist die 2er-Potenz $f(n) = n^2$:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
%run Interpreter/whileinterpreter.py %run Interpreter/whileinterpreter.py
``` ```
%% Output
Help on function interpret in module __main__:
interpret(program, timeout=60)
Funktion zum Ausführen eines WHILE-Programms.
:param program: WHILE-Programm als String 'x1:=10; x2:=8; x0:=x2+0; WHILE x1 /=0 DO x0:=x0+1; x1:=x1-1 END'
:param timeout: Zeit nach der die Ausführung eines Programms pausiert wird.
Gibt eine Möglichkeit zum Abbrechen bei einer Endlosschleife.
Ein Wert von 0 deaktiviert den Timeout.
:returns integer: Gibt bei Abbruch -1 und sonst den Wert von x0 nach dem WHILE-Programm zurück.
:usage interpret('x1:=10; x2:=8; x0:=x2+0; WHILE x1 /=0 DO x0:=x0+1; x1:=x1-1 END')
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
interpret(''' interpret('''
x1:=10; x1:=10;
x0:=1; x0:=1;
WHILE x1 /= 0 DO WHILE x1 /= 0 DO
x2:=x0+0; x2:=x0+0;
LOOP x2 DO LOOP x2 DO
x0:=x0+1 x0:=x0+1
END; END;
x1:=x1-1 x1:=x1-1
END''') END''')
``` ```
%% Output %% Output
1024 1024
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Ein weiteres Beispiel ist die Funktion f(n) = n mod 2 Ein weiteres Beispiel ist die Funktion f(n) = n mod 2
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
interpret(''' interpret('''
x1:=16; x1:=16;
x2:=x1-1; x2:=x1-1;
WHILE x2!=0 DO WHILE x2!=0 DO
x1:=x1-2; x1:=x1-2;
x2:=x2-2 x2:=x2-2
END; END;
x0:=x1+0 x0:=x1+0
''') ''')
``` ```
%% Output %% Output
0 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment