Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
general
stups
prob-teaching-notebooks
Commits
3047fa72
Commit
3047fa72
authored
Dec 21, 2020
by
Chris
Browse files
Feature: Homeomorphic Embedding für Interpreter
parent
98d1fdca
Changes
5
Hide whitespace changes
Inline
Side-by-side
info4/kapitel-8/Interpreter/gotointerpreter.py
View file @
3047fa72
import
lexer
from
loopinterpreter
import
ErrorHandler
from
whileinterpreter
import
Timeout
from
whileinterpreter
import
State
import
re
import
operator
...
...
@@ -126,6 +127,13 @@ class GOTOInterpreter:
self
.
error_handler
.
handle_error
(
'GOTO zu nicht vorhandener Markierung'
)
self
.
lex
.
current_position
=
self
.
marker_to_position
.
get
(
marker_number
)
self
.
error_handler
.
line_number
=
self
.
marker_to_line
.
get
(
marker_number
)
if
self
.
test_homeomorphic_embedding
:
new_state
=
State
(
self
.
lex
.
current_position
,
self
.
values
)
for
state
in
self
.
state_list
:
if
state
.
less_or_equal
(
new_state
):
self
.
error_handler
.
handle_endless_loop
()
self
.
state_list
.
append
(
new_state
)
return
self
.
next_token
()
def
verify_goto
(
self
,
goto_token
):
...
...
@@ -261,12 +269,14 @@ class GOTOInterpreter:
current_token
=
self
.
verify_halt
(
current_token
)
return
current_token
def
interpret
(
self
,
program
,
values
=
None
):
def
interpret
(
self
,
program
,
values
=
None
,
test_homeomorphic_embedding
=
False
):
try
:
with
Timeout
(
self
.
timeout
):
self
.
halted
=
False
self
.
lex
=
lexer
.
Lexer
(
self
.
regex_to_token
,
program
)
self
.
error_handler
=
ErrorHandler
(
program
,
self
)
self
.
state_list
=
[]
self
.
test_homeomorphic_embedding
=
test_homeomorphic_embedding
self
.
values
=
values
if
values
is
None
:
self
.
values
=
{}
...
...
@@ -284,7 +294,7 @@ class GOTOInterpreter:
return
-
1
def
interpret
(
program
,
value_list
=
None
,
timeout
=
60
):
def
interpret
(
program
,
value_list
=
None
,
timeout
=
60
,
debug
=
False
):
"""Funktion zum Ausführen eines GOTO-Programms.
:param program: GOTO-Programm als String 'M1: A1; M2: A2; ... Mn: An;'
:param value_list: Array von Integern ([v1, ..., vn]).
...
...
@@ -292,6 +302,7 @@ def interpret(program, value_list=None, timeout=60):
: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.
:param debug Boolean der angibt ob mit Homeomorphic Embedding auf mögliche Endlosschleifen geprüft werden soll.
: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
)
...
...
@@ -302,7 +313,7 @@ def interpret(program, value_list=None, timeout=60):
if
not
isinstance
(
value
,
int
)
or
value
<
0
or
not
int
(
value
)
==
value
:
raise
ValueError
(
"Variablen können nur natürliche Zahlen zugewiesen bekommen."
)
values
.
update
({
'x'
+
str
(
index
+
1
):
value
})
return
interpreter
.
interpret
(
program
,
values
)
return
interpreter
.
interpret
(
program
,
values
,
debug
)
if
__name__
==
'__main__'
:
...
...
info4/kapitel-8/Interpreter/loopinterpreter.py
View file @
3047fa72
...
...
@@ -31,6 +31,9 @@ class ErrorHandler:
if
user_input
.
lower
()
==
'exit'
:
raise
KeyboardInterrupt
def
handle_endless_loop
(
self
):
self
.
handle_error
(
"Mögliche Endlosschleife gefunden."
)
class
LOOPInterpreter
:
def
__init__
(
self
):
...
...
info4/kapitel-8/Interpreter/test_goto_interpreter.py
View file @
3047fa72
...
...
@@ -206,3 +206,11 @@ class GOTOInterpreterTest(TestCase):
interpret
(
'M1: x0:=1;'
,
[
0.2
])
with
self
.
assertRaises
(
ValueError
):
interpret
(
'M1: x0:=4;'
,
[
'EINS'
])
def
test_homeomorphic_embedding
(
self
):
with
self
.
assertRaises
(
SyntaxError
):
interpret
(
'M1: x1:=1; M2: IF x1 = 0 THEN GOTO M5;'
'M3: x1:=x1+1; M4: GOTO M2; M5: HALT;'
,
timeout
=
0
,
debug
=
True
)
with
self
.
assertRaises
(
SyntaxError
):
interpret
(
'M1: x1:=100; M2: IF x1 = 0 THEN GOTO M5;'
'M3: x1:=x1+1; M4: GOTO M2; M5: HALT;'
,
timeout
=
0
,
debug
=
True
)
info4/kapitel-8/Interpreter/test_while_interpreter.py
View file @
3047fa72
...
...
@@ -133,3 +133,10 @@ class WHILEInterpreterTest(LOOPInterpreterTest):
interpret
(
'x0:=1'
,
[
0.2
])
with
self
.
assertRaises
(
ValueError
):
interpret
(
'x0:=4'
,
[
'EINS'
])
def
test_homeomorphic_embedding
(
self
):
with
self
.
assertRaises
(
SyntaxError
):
interpret
(
'x1:=1; WHILE x1 != 0 DO x1:=x1+1 END'
,
timeout
=
0
,
debug
=
True
)
with
self
.
assertRaises
(
SyntaxError
):
interpret
(
'''x1:=100; WHILE x1 != 0 DO x1:=x1-1 END;
x1 = 1; WHILE x1 != 0 DO x1:=x1+1 END'''
,
timeout
=
0
,
debug
=
True
)
info4/kapitel-8/Interpreter/whileinterpreter.py
View file @
3047fa72
...
...
@@ -3,7 +3,7 @@ from loopinterpreter import LOOPInterpreter, ErrorHandler
import
re
import
signal
from
IPython.display
import
clear_output
from
copy
import
deepcopy
class
Timeout
:
def
__init__
(
self
,
time
):
...
...
@@ -29,6 +29,25 @@ Möchten sie abbrechen? [J,n]:''')
except
EOFError
:
pass
class
State
:
def
__init__
(
self
,
linenumber
,
values
):
self
.
values
=
deepcopy
(
values
)
self
.
linenumber
=
linenumber
def
less_or_equal
(
self
,
other
):
if
self
.
linenumber
>
other
.
linenumber
:
return
False
values1
=
self
.
values
values2
=
other
.
values
different_keys
=
[
k
for
k
in
values1
if
values1
.
get
(
k
)
!=
values2
.
get
(
k
)]
+
\
[
k
for
k
in
values2
if
values1
.
get
(
k
)
is
None
]
for
key
in
different_keys
:
if
values1
.
get
(
key
)
>
0
and
(
values2
.
get
(
key
)
is
None
or
values2
.
get
(
key
)
<
values1
.
get
(
key
)):
return
False
return
True
class
WHILEInterpreter
(
LOOPInterpreter
):
def
__init__
(
self
,
timeout
=
60
):
...
...
@@ -112,6 +131,13 @@ class WHILEInterpreter(LOOPInterpreter):
end_found
=
True
while
not
while_value
==
0
:
if
self
.
test_homeomorphic_embedding
:
new_state
=
State
(
self
.
lex
.
current_position
,
self
.
values
)
for
state
in
self
.
state_list
:
if
state
.
less_or_equal
(
new_state
):
self
.
error_handler
.
handle_endless_loop
()
self
.
state_list
.
append
(
new_state
)
self
.
lex
.
current_position
=
saved_position
self
.
error_handler
.
line_number
=
saved_line
end_found
=
False
...
...
@@ -159,11 +185,13 @@ class WHILEInterpreter(LOOPInterpreter):
return
self
.
next_token
()
def
interpret
(
self
,
program
,
values
=
None
):
def
interpret
(
self
,
program
,
values
=
None
,
test_homeomorphic_embedding
=
False
):
try
:
with
Timeout
(
self
.
timeout
):
self
.
lex
=
lexer
.
Lexer
(
self
.
regex_to_token
,
program
)
self
.
error_handler
=
ErrorHandler
(
program
,
self
)
self
.
test_homeomorphic_embedding
=
test_homeomorphic_embedding
self
.
state_list
=
[]
self
.
values
=
values
if
values
is
None
:
self
.
values
=
{}
...
...
@@ -187,7 +215,7 @@ class WHILEInterpreter(LOOPInterpreter):
return
-
1
def
interpret
(
program
,
value_list
=
None
,
timeout
=
60
):
def
interpret
(
program
,
value_list
=
None
,
timeout
=
60
,
debug
=
False
):
"""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 value_list: Array von Integern ([v1, ..., vn]).
...
...
@@ -195,6 +223,7 @@ def interpret(program, value_list=None, timeout=60):
: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.
:param debug: Boolean der angibt ob mit Homeomorphic Embedding auf mögliche Endlosschleifen geprüft werden soll.
: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
)
...
...
@@ -205,7 +234,7 @@ def interpret(program, value_list=None, timeout=60):
if
not
isinstance
(
value
,
int
)
or
value
<
0
or
not
int
(
value
)
==
value
:
raise
ValueError
(
"Variablen können nur natürliche Zahlen zugewiesen bekommen."
)
values
.
update
({
'x'
+
str
(
index
+
1
):
value
})
return
interpreter
.
interpret
(
program
,
values
)
return
interpreter
.
interpret
(
program
,
values
,
debug
)
if
__name__
==
'__main__'
:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment