diff --git a/info4/kapitel-8/Interpreter/interpreter.py b/info4/kapitel-8/Interpreter/interpreter.py index 088afa1935209694b55fdd0e0583b695bd52757f..ba38dad1f77e702031bfaab050bdddb168a4ce29 100644 --- a/info4/kapitel-8/Interpreter/interpreter.py +++ b/info4/kapitel-8/Interpreter/interpreter.py @@ -23,15 +23,16 @@ def process_assignment(token_queue, position, value_list, forbidden_identifiers) value_1 = 0 if token_queue[position + 2].k == 'NUMBER': - value_1 += int(token_queue[position + 2].v) + value_1 = int(token_queue[position + 2].v) value_list.update({identifier_1: value_1}) - return position+3, value_list + return position + 3, value_list if not token_queue[position + 2].k == 'IDENTIFIER': raise SyntaxError("IDENTIFIER in Zuweisung erwartet.") identifier_2 = token_queue[position + 2].v if identifier_2 in forbidden_identifiers: - raise Exception("Identifier " + identifier_2 + " ist bereits in Loop vorhanden und darf nicht verwendet werden.") + raise Exception( + "Identifier " + identifier_2 + " ist bereits in Loop vorhanden und darf nicht verwendet werden.") if identifier_2 in value_list: value_2 = value_list.get(identifier_2) @@ -49,28 +50,123 @@ def process_assignment(token_queue, position, value_list, forbidden_identifiers) value_list.update({identifier_1: value_1}) return position + 5, value_list + +def verify_assignment(token_queue, position, forbidden_identifiers): + identifier_1 = token_queue[position].v + if identifier_1 in forbidden_identifiers: + raise Exception("Identifier " + identifier_1 + "ist bereits in Loop vorhanden und darf nicht verwendet werden.") + if not token_queue[position + 1].k == 'EQUALS': + raise SyntaxError(":= in Zuweisung erwartet.") + + if token_queue[position + 2].k == 'NUMBER': + return position + 3 + + if not token_queue[position + 2].k == 'IDENTIFIER': + raise SyntaxError("IDENTIFIER in Zuweisung erwartet.") + identifier_2 = token_queue[position + 2].v + if identifier_2 in forbidden_identifiers: + raise Exception( + "Identifier " + identifier_2 + " ist bereits in Loop vorhanden und darf nicht verwendet werden.") + + if not token_queue[position + 4].k == 'NUMBER': + raise SyntaxError("NUMBER in Zuweisung erwartet.") + if not token_queue[position + 3].k in ['PLUS', 'MINUS']: + raise SyntaxError("PLUS oder MINUS in Zuweisung erwartet.") + + return position + 5 + + +def verify_loop(token_queue, position, forbidden_identifiers): + identifier_token = token_queue[position + 1] + if not identifier_token.k == 'IDENTIFIER': + raise SyntaxError('IDENTIFIER in LOOP erwartet.') + if identifier_token.v in forbidden_identifiers: + raise SyntaxError( + "Identifier " + identifier_token.v + "ist bereits in Loop vorhanden und darf nicht verwendet werden.") + if not token_queue[position + 2].k == 'DO': + raise SyntaxError('DO in LOOP erwartet.') + + forbidden_identifiers.append(identifier_token.v) + + end_found = False + while not end_found: + position = verify_program(token_queue, position, forbidden_identifiers) + if token_queue[position].k == 'SEMICOLON': + position = position + 1 + continue + elif token_queue[position].k == 'END': + end_found = True + else: + raise SyntaxError("SEMICOLON oder END erwartet.") + + forbidden_identifiers.remove(identifier_token.v) + return position + 1 + + +def verify_program(token_queue, position, forbidden_identifiers): + current_key = token_queue[position].k + if current_key == 'IDENTIFIER': + try: + current_position = verify_assignment(token_queue, position, forbidden_identifiers) + except IndexError: + raise Exception("Frühzeitiges Ende einer Zuweisung.") + elif current_key == 'LOOP': + try: + current_position = verify_loop(token_queue, position, forbidden_identifiers) + except IndexError: + raise Exception("Frühzeitiges Ende eines LOOPs") + else: + raise SyntaxError("Keine passende Anweisung gefunden") + return current_position + + def process_loop(token_queue, position, value_list, forbidden_identifiers): - identifier_token = token_queue[position+1] + identifier_token = token_queue[position + 1] if not identifier_token.k == 'IDENTIFIER': raise SyntaxError('IDENTIFIER in LOOP erwartet.') - if not token_queue[position+2].k == 'DO': + if identifier_token.v in forbidden_identifiers: + raise SyntaxError( + "Identifier " + identifier_token.v + "ist bereits in Loop vorhanden und darf nicht verwendet werden.") + if not token_queue[position + 2].k == 'DO': raise SyntaxError('DO in LOOP erwartet.') - number_of_loops = int(value_list.get(identifier_token.v)) + if identifier_token.v in value_list: + number_of_loops = int(value_list.get(identifier_token.v)) + else: + number_of_loops = 0 saved_position = position + 3 forbidden_identifiers.append(identifier_token.v) + + # TODO increment position without changing values when number of loops = 0 + if number_of_loops == 0: + end_found = False + position = saved_position + while not end_found: + position = verify_program(token_queue, position, forbidden_identifiers) + if token_queue[position].k == 'SEMICOLON': + position = position + 1 + continue + elif token_queue[position].k == 'END': + end_found = True + else: + raise SyntaxError("SEMICOLON oder END erwartet.") + for index in range(number_of_loops): position = saved_position end_found = False - while(not end_found): + while not end_found: position, value_list = process_program(token_queue, position, value_list, forbidden_identifiers) if token_queue[position].k == 'SEMICOLON': position = position + 1 continue elif token_queue[position].k == 'END': end_found = True - else: raise SyntaxError("SEMICOLON oder END erwartet.") - return position+1, value_list + else: + raise SyntaxError("SEMICOLON oder END erwartet.") + + forbidden_identifiers.remove(identifier_token.v) + return position + 1, value_list + def process_program(token_queue, position, value_list, forbidden_identifiers): current_key = token_queue[position].k @@ -88,6 +184,7 @@ def process_program(token_queue, position, value_list, forbidden_identifiers): raise SyntaxError("Keine passende Anweisung gefunden") return current_position, values + def interpret(program): tokens = lexer.tokenize(program) current_position = 0 @@ -103,4 +200,7 @@ def interpret(program): return values.get("x0") return 0 + print(interpret(loop_program)) +print(interpret('''x1:= 2; +LOOP x1 DO x2 := 2 END; x0 := x2 + 1'''))