From 98e6eed4407b9482d78bf94862bdf32bffd23e8f Mon Sep 17 00:00:00 2001
From: Chris <Christopher.Happe@uni-duesseldorf.de>
Date: Tue, 17 Nov 2020 11:53:04 +0100
Subject: [PATCH] WHILE-Interpreter aus LOOP-Interpreter erstellt

---
 .../kapitel-8/Interpreter/whileinterpreter.py | 132 ++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 info4/kapitel-8/Interpreter/whileinterpreter.py

diff --git a/info4/kapitel-8/Interpreter/whileinterpreter.py b/info4/kapitel-8/Interpreter/whileinterpreter.py
new file mode 100644
index 0000000..8a5cb75
--- /dev/null
+++ b/info4/kapitel-8/Interpreter/whileinterpreter.py
@@ -0,0 +1,132 @@
+from loopinterpreter import LOOPInterpreter
+import re
+
+
+class WHILEInterpreter(LOOPInterpreter):
+    def __init__(self):
+        super().__init__()
+        self.regex_to_token = [(re.compile(r'\d+'), 'NUMBER'),
+                               (re.compile(r'x\d+'), 'IDENTIFIER'),
+                               (re.compile(r'\+'), 'PLUS'),
+                               (re.compile(r'-'), 'MINUS'),
+                               (re.compile(r':=|≔|!='), 'EQUALS'),
+                               (re.compile(r'/=|≠'), 'NOTEQUALS'),
+                               (re.compile(r'LOOP'), 'LOOP'),
+                               (re.compile(r'WHILE'), 'WHILE'),
+                               (re.compile(r'DO'), 'DO'),
+                               (re.compile(r'END'), 'END'),
+                               (re.compile(r';'), 'SEMICOLON'),
+                               (re.compile(r'BREAK'), 'BREAK'),
+                               (re.compile(r'\n', re.MULTILINE), 'LINEBREAK'),
+                               (re.compile(r'\s+'), 'WHITESPACE'),
+                               (re.compile(r'[^\n]*'), 'UNKNOWN')]
+
+    def process_program(self, forbidden_identifiers, current_token):
+        if current_token is None or current_token.k not in ['IDENTIFIER', 'LOOP']:
+            self.error_handler.handle_error("Keine passende Anweisung gefunden\n" +
+                                            "Erwartet: IDENTIFIER (x0, x1, ...) oder LOOP")
+        elif current_token.k == 'IDENTIFIER':
+            current_token = self.process_assignment(forbidden_identifiers, current_token)
+        elif current_token.k == 'LOOP':
+            current_token = self.process_loop(forbidden_identifiers, current_token)
+        elif current_token.k == 'WHILE':
+            current_token = self.process_while(forbidden_identifiers, current_token)
+        return current_token
+
+    def verify_program(self, forbidden_identifiers, current_token):
+        if current_token is None or current_token.k not in ['IDENTIFIER', 'LOOP']:
+            self.error_handler.handle_error("Keine passende Anweisung gefunden\n" +
+                                            "Erwartet: IDENTIFIER (x0, x1, ...) oder LOOP")
+        elif current_token.k == 'IDENTIFIER':
+            current_token = self.verify_assignment(forbidden_identifiers, current_token)
+        elif current_token.k == 'LOOP':
+            current_token = self.verify_loop(forbidden_identifiers, current_token)
+        elif current_token.k == 'WHILE':
+            current_token = self.verify_while(forbidden_identifiers, current_token)
+        return current_token
+
+    def process_while(self, forbidden_identifiers, current_token):
+        identifier_token = self.next_nonempty_token('WHILE', 'IDENTIFIER (x0, x1, ...)')
+        if not identifier_token.k == 'IDENTIFIER':
+            self.error_handler.handle_error('IDENTIFIER in WHILE erwartet.')
+        if identifier_token.v in forbidden_identifiers:
+            self.error_handler.handle_error('Identifier ' + identifier_token.v +
+                                            ' ist bereits in Loop vorhanden und darf nicht verwendet werden.')
+        if not self.next_nonempty_token("WHILE", "UNGLEICH").k == 'NOTEQUALS':
+            self.error_handler.handle_error('UNGLEICH in WHILE erwartet.')
+
+        zero_token = self.next_nonempty_token("WHILE", "0")
+        if not zero_token.k == 'NUMBER':
+            self.error_handler.handle_error('0 in WHILE erwartet.')
+        if not int(zero_token.v) == 0:
+            self.error_handler.handle_error('0 in WHILE erwartet.')
+
+        if identifier_token.v in self.values:
+            while_value = int(self.values.get(identifier_token.v))
+        else:
+            while_value = 0
+
+        saved_position = self.lex.current_position
+        saved_line = self.error_handler.line_number
+
+        if while_value == 0:
+            end_found = False
+            while not end_found:
+                token = self.verify_program(forbidden_identifiers, self.next_token())
+                if token is None or token.k not in ['SEMICOLON', 'END']:
+                    self.error_handler.handle_error("SEMICOLON oder END in WHILE erwartet.")
+                elif token.k == 'SEMICOLON':
+                    continue
+                elif token.k == 'END':
+                    end_found = True
+
+        while not while_value == 0:
+            self.lex.current_position = saved_position
+            self.error_handler.line_number = saved_line
+            end_found = False
+            while not end_found:
+                token = self.process_program(forbidden_identifiers, self.next_token())
+                if token is None or token.k not in ['SEMICOLON', 'END']:
+                    self.error_handler.handle_error("SEMICOLON oder END in WHILE erwartet.")
+                elif token.k == 'SEMICOLON':
+                    continue
+                elif token.k == 'END':
+                    end_found = True
+            if identifier_token.v in self.values:
+                while_value = int(self.values.get(identifier_token.v))
+            else:
+                while_value = 0
+
+        return self.next_token()
+
+    def verify_while(self, forbidden_identifiers, current_token):
+        identifier_token = self.next_nonempty_token("WHILE", "IDENTIFIER")
+        if not identifier_token.k == 'IDENTIFIER':
+            self.error_handler.handle_error('IDENTIFIER in WHILE erwartet.')
+        if identifier_token.v in forbidden_identifiers:
+            self.error_handler.handle_error("Identifier " + identifier_token.v +
+                                            " ist bereits in Loop vorhanden und darf nicht verwendet werden.")
+        if not self.next_nonempty_token("WHILE", "UNGLEICH").k == 'NOTEQUALS':
+            self.error_handler.handle_error('UNGLEICH in WHILE erwartet.')
+
+        zero_token = self.next_nonempty_token("WHILE", "0")
+        if not zero_token.k == 'NUMBER':
+            self.error_handler.handle_error('0 in WHILE erwartet.')
+        if not int(zero_token.v) == 0:
+            self.error_handler.handle_error('0 in WHILE erwartet.')
+
+        end_found = False
+        while not end_found:
+            token = self.verify_program(forbidden_identifiers, self.next_token())
+            if token is None or token.k not in ['SEMICOLON', 'END']:
+                self.error_handler.handle_error("SEMICOLON oder END in WHILE erwartet.")
+            elif token.k == 'SEMICOLON':
+                continue
+            elif token.k == 'END':
+                end_found = True
+
+        return self.next_token()
+
+def interpret(program):
+    interpreter = WHILEInterpreter()
+    interpreter.interpret(program)
\ No newline at end of file
-- 
GitLab