Skip to content
Snippets Groups Projects
Select Git revision
  • dadd7374c3098aada1f90e9c2d7c41149c35dcc0
  • master default protected
  • cran_version
3 results

copyNamesCLP.Rd

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    interpreter.py 4.03 KiB
    import lexer
    
    loop_program = '''x1 := 2;
    x2 := 3;
    x3 := x2 + 0;
    LOOP x1 DO
        x2 := x3 + 1;
        x3 := x2 + 0
    END;
    x0 := x2 + 0'''
    
    
    def process_assignment(token_queue, position, value_list, 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 identifier_1 in value_list:
            value_1 = value_list.get(identifier_1)
        else:
            value_1 = 0
    
        if token_queue[position + 2].k == 'NUMBER':
            value_1 += int(token_queue[position + 2].v)
            value_list.update({identifier_1: value_1})
            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.")
    
        if identifier_2 in value_list:
            value_2 = value_list.get(identifier_2)
        else:
            value_2 = 0
    
        if not token_queue[position + 4].k == 'NUMBER':
            raise SyntaxError("NUMBER in Zuweisung erwartet.")
        if token_queue[position + 3].k == 'PLUS':
            value_1 = value_2 + int(token_queue[position + 4].v)
        elif token_queue[position + 3].k == 'MINUS':
            value_1 = max(0, value_2 + token_queue[position + 4].v)
        else:
            raise SyntaxError("PLUS oder MINUS in Zuweisung erwartet.")
        value_list.update({identifier_1: value_1})
        return position + 5, value_list
    
    def process_loop(token_queue, position, value_list, forbidden_identifiers):
        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':
            raise SyntaxError('DO in LOOP erwartet.')
    
        number_of_loops = int(value_list.get(identifier_token.v))
        saved_position = position + 3
        forbidden_identifiers.append(identifier_token.v)
        for index in range(number_of_loops):
            position = saved_position
            end_found = False
            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
    
    def process_program(token_queue, position, value_list, forbidden_identifiers):
        current_key = token_queue[position].k
        if current_key == 'IDENTIFIER':
            try:
                current_position, values = process_assignment(token_queue, position, value_list, forbidden_identifiers)
            except IndexError:
                raise Exception("Frühzeitiges Ende einer Zuweisung.")
        elif current_key == 'LOOP':
            try:
                current_position, values = process_loop(token_queue, position, value_list, forbidden_identifiers)
            except IndexError:
                raise Exception("Frühzeitiges Ende eines LOOPs")
        else:
            raise SyntaxError("Keine passende Anweisung gefunden")
        return current_position, values
    
    def interpret(program):
        tokens = lexer.tokenize(program)
        current_position = 0
        values = {}
        forbidden_identifiers = []
        while current_position < len(tokens):
            current_position, values = process_program(tokens, current_position, values, forbidden_identifiers)
            if current_position < len(tokens) and not tokens[current_position].k == 'SEMICOLON':
                raise SyntaxError("Semicolon erwartet")
            else:
                current_position = current_position + 1
        if "x0" in values:
            return values.get("x0")
        return 0
    
    print(interpret(loop_program))