Skip to content
Snippets Groups Projects
Select Git revision
  • fb16cd9ca310af86142edb4ef8d9fba471611f79
  • master default protected
2 results

HDCTopicManager.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    whileinterpreter.py 6.74 KiB
    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'\s+', re.MULTILINE), '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', 'WHILE']:
                self.error_handler.handle_error("Keine passende Anweisung gefunden\n" +
                                                "Erwartet: IDENTIFIER (x0, x1, ...), LOOP oder WHILE")
            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', 'WHILE']:
                self.error_handler.handle_error("Keine passende Anweisung gefunden\n" +
                                                "Erwartet: IDENTIFIER (x0, x1, ...), LOOP oder WHILE")
            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 not self.next_nonempty_token("WHILE", "DO").k == 'DO':
                self.error_handler.handle_error('DO 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.')
    
            if not self.next_nonempty_token("WHILE", "DO").k == 'DO':
                self.error_handler.handle_error('DO 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()
        return interpreter.interpret(program)