diff --git a/info4/kapitel-8/Interpreter/whileinterpreter.py b/info4/kapitel-8/Interpreter/whileinterpreter.py new file mode 100644 index 0000000000000000000000000000000000000000..8a5cb756d88b9d6a46bbe9a85d864cb89e1ba768 --- /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