Exemple #1
0
def auto_download_plc_programs():
    """Downloads plc programs to track controllers"""
    logger.critical("Auto downloading plc programs")
    for i, track_controller in enumerate(track_system.green_track_controllers):

        if type(track_controller) != HWTrackCtrlConnector:
            source_code = ''
            for line in open(
                    'resources/Track Controller PLC Programs/Green{}.txt'.
                    format(i)):
                source_code += line

            output_file = 'CompiledOutput.txt'
            lex = Lexer(source_code)
            emitter = Emitter(output_file)
            par = Parser(lex, emitter)
            par.program("Green{}".format(i))

            track_controller.download_program(output_file)

    for i, track_controller in enumerate(track_system.red_track_controllers):
        source_code = ''
        for line in open(
                'resources/Track Controller PLC Programs/Red{}.txt'.format(
                    i + 12)):
            source_code += line

        output_file = 'CompiledOutput.txt'
        lex = Lexer(source_code)
        emitter = Emitter(output_file)
        par = Parser(lex, emitter)
        par.program("Red{}".format(i + 12))

        track_controller.download_program(output_file)
Exemple #2
0
def test_peek():
    """Tests the peek method

    PRECONDITIONS: Lexer made with input "test input"
    EXECUTION: lex.peek()
    POSTCONDITIONS: lex.peek returns 'e'
                    lex.current_character remains 't'

    """
    test_input = "test input"
    lex = Lexer(test_input)
    assert test_input[1] == lex.peek()
    assert test_input[0] == lex.current_character
Exemple #3
0
def test_next_character():
    """Tests the next_character method

    PRECONDITIONS: Lexer made with input "test input"
    EXECUTION: Call next_character repeatedly
    POSTCONDITIONS: current_character matches character in "test input"
                    current_position increments once per call

    """
    test_input = "test input"
    lex = Lexer(test_input)
    assert test_input + '\n' == lex.source_code
    assert test_input[0] == lex.current_character
    assert lex.current_position == 0

    for i, char in enumerate(test_input[1:]):
        lex.next_character()

        assert char == lex.current_character
        assert (i + 1) == lex.current_position

    lex.next_character()
    assert '\n' == lex.current_character

    lex.next_character()
    assert '\0' == lex.current_character
Exemple #4
0
    def compile_program(file_name):
        """Method used to invoke the PLC language compiler on the given file

        :param str file_name: Absolute path to the file to compile

        :return: Name of the output file. None if compilation failed
        """
        # Gather the source code from the file
        source_code = ''
        for line in open(file_name, 'r'):
            source_code = ''.join([source_code, line])

        # Create compiler elements
        output_file = 'CompiledOutput.txt'
        lex = Lexer(source_code)
        emitter = Emitter(output_file)
        par = Parser(lex, emitter)

        # Try to compile
        try:
            par.program(
                program_name=os.path.splitext(os.path.basename(file_name))[0])
            return output_file
        except CompilationError as compilation_error:
            alert = Alert("Compilation failed with error:\n {}".format(
                str(compilation_error)))
            alert.exec_()
            return None
def test_simple_program():
    """Tests the compilation of a simple program"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    par.program()

    assert par.emitter.requests == 'START_DOWNLOAD\n' \
                                   'CREATE_TAG input1 FALSE\n' \
                                   'CREATE_TAG output1 FALSE\n' \
                                   'CREATE_TASK PERIOD 1000 myTask\n' \
                                   'CREATE_ROUTINE Main\n' \
                                   'CREATE_RUNG\n' \
                                   'CREATE_INSTRUCTION XIO input1\n' \
                                   'CREATE_INSTRUCTION OTE output1\n' \
                                   'END_DOWNLOAD\n'
def test_multiple_mains():
    """Tests a program with multiple mains"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #10 : There can " \
           "only be one Main routine" == str(pytest_wrapped_e.value)
Exemple #7
0
def test_statement_tag_1(mock_emitter):
    """Test the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: No exception is thrown

    """
    source_code = "TAG myTag = TRUE\nTAG myTag = FALSE"
    par = Parser(Lexer(source_code), mock_emitter)
    par.program()
Exemple #8
0
def test_statement_task_2(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: No exception is thrown

    """
    source_code = "TASK<EVENT=myEvent> myTask"
    par = Parser(Lexer(source_code), mock_emitter)

    par.statement()
Exemple #9
0
def test_statement_routine_success(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: No exception is thrown

    """
    source_code = "ROUTINE Main"
    par = Parser(Lexer(source_code), mock_emitter)
    par.stack.append('TASK')

    par.statement()
Exemple #10
0
def test_statement_rung_2(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: No exception is thrown

    """
    source_code = "RUNG myRung"
    par = Parser(Lexer(source_code), mock_emitter)
    par.stack.append('ROUTINE')

    par.statement()
Exemple #11
0
def test_statement_task_3(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: Exception is thrown with correct error message

    """
    source_code = "TASK<CONTINUOUS> myTask"
    par = Parser(Lexer(source_code), mock_emitter)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.statement()
    assert "Parsing error line #0 : Invalid task type CONTINUOUS" == str(pytest_wrapped_e.value)
Exemple #12
0
def test_statement_tag_3(mock_emitter):
    """Test for a tag name being too long

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: Exception is thrown with correct error message

    """
    source_code = "TAG myLongTagName = FALSE"
    par = Parser(Lexer(source_code), mock_emitter)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #0 : Tag name myLongTagName "\
           "too long. The limit is 7 characters" == str(pytest_wrapped_e.value)
Exemple #13
0
def test_statement_tag_2(mock_emitter):
    """Test the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: Exception is thrown with correct error message

    """
    source_code = "TAG myTag = notAKeyword"
    par = Parser(Lexer(source_code), mock_emitter)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #1 : Expected "\
           "FALSE, but found notAKeyword" == str(pytest_wrapped_e.value)
Exemple #14
0
def test_statement_end(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: No exception is thrown

    """
    source_code = "ENDRUNG\nENDROUTINE\nENDTASK"
    par = Parser(Lexer(source_code), mock_emitter)
    par.stack.append('TASK')
    par.stack.append('ROUTINE')
    par.stack.append('RUNG')
    par.main_flag = True

    par.program()
Exemple #15
0
def test_statement_routine_failure(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: Exception is thrown

    """
    source_code = "ROUTINE "
    par = Parser(Lexer(source_code), mock_emitter)
    par.stack.append('TASK')

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.statement()
    assert "Parsing error line #1 : Expected "\
           "IDENTIFIER, but found \n" == str(pytest_wrapped_e.value)
Exemple #16
0
def test_statement_instructions(mock_emitter):
    """Tests the statement method

    PRECONDITIONS: Create parser with line source_code
    EXECUTION: par.statement()
    POSTCONDITION: No exception is thrown

    """
    source_code = "XIC tag\nXIO tag\nOTE tag\nOTL tag\nOTU tag\nJSR routine\nEMIT event\nRET"
    par = Parser(Lexer(source_code), mock_emitter)

    # Add tag to the symbols to avoid errors
    par.tags.add('tag')
    par.events.add('event')
    par.routines.add('routine')

    par.program()
Exemple #17
0
def test_get_token_failure_1():
    """Tests the get_token method

    PRECONDITIONS: Lexer made with input "TASK<PERIOD=10.> myTask # This is my task"
    EXECUTION: lex.get_token() repeatedly
    POSTCONDITIONS: sys.exit is called

    """
    test_input = "TASK<PERIOD=10.> myTask # This is my task"
    lex = Lexer(test_input)

    lex.get_token()
    lex.get_token()
    lex.get_token()
    lex.get_token()

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        lex.get_token()
    assert "Lexing error line #1 : Illegal character in number" == str(
        pytest_wrapped_e.value)
def test_missing_end():
    """Test program with missing ENDROUTINE"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #10 : Missing matching ENDROUTINE" == str(
        pytest_wrapped_e.value)
def test_no_tag():
    """Test program that uses a nonexistent tag"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input2\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #6 : Referencing tag "\
           "input2 before assignment" == str(pytest_wrapped_e.value)
def test_low_period():
    """Test program with a period less than 20ms"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=10> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #2 : Period below allowable limit 20" == str(
        pytest_wrapped_e.value)
def test_missing_main():
    """Tests a program that is missing a main routine"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE myRoutine\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #11 : There must be a " \
           "single Main routine" == str(pytest_wrapped_e.value)
def test_nonexistent_event():
    """Test program that uses a nonexistent event"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "EMIT MissingEvent\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #12 : Emitted event MissingEvent does not " \
           "correspond to a task" == str(pytest_wrapped_e.value)
def test_nonexistent_routine():
    """Test program that jumps to a nonexistent routine"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "JSR MissingRoutine\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #12 : Routine "\
           "MissingRoutine does not exist" == str(pytest_wrapped_e.value)
def test_too_many_ends():
    """Test program that too many end statements"""
    code = "TAG input1 = FALSE\n" \
           "TAG output1 = FALSE\n" \
           "TASK<PERIOD=1000> myTask\n" \
           "ROUTINE Main\n" \
           "RUNG\n" \
           "XIO input1\n" \
           "OTE output1\n" \
           "ENDRUNG\n" \
           "ENDROUTINE\n" \
           "ENDTASK\n" \
           "ENDTASK\n"

    lex = Lexer(code)
    emit = Emitter('TestProgram')
    par = Parser(lex, emit)

    with pytest.raises(CompilationError) as pytest_wrapped_e:
        par.program()
    assert "Parsing error line #12 : Too many end statements" == str(
        pytest_wrapped_e.value)
Exemple #25
0
def test_get_token_success():
    """Tests the get_token method

    PRECONDITIONS: Lexer made with input "TASK<PERIOD=10.50> myTask # This is my task"
    EXECUTION: lex.get_token() repeatedly
    POSTCONDITIONS: get_token() returns the correct token

    """
    test_input = "TASK<PERIOD=10.50> myTask # This is my task"
    lex = Lexer(test_input)

    token = lex.get_token()
    assert TokenType.TASK == token.type
    assert "TASK" == token.text

    token = lex.get_token()
    assert TokenType.OPEN_ANGLE == token.type
    assert "<" == token.text

    token = lex.get_token()
    assert TokenType.PERIOD == token.type
    assert "PERIOD" == token.text

    token = lex.get_token()
    assert TokenType.EQ == token.type
    assert "=" == token.text

    token = lex.get_token()
    assert TokenType.NUMBER == token.type
    assert "10.50" == token.text

    token = lex.get_token()
    assert TokenType.CLOSE_ANGLE == token.type
    assert ">" == token.text

    token = lex.get_token()
    assert TokenType.IDENTIFIER == token.type
    assert "myTask" == token.text

    token = lex.get_token()
    assert TokenType.NEWLINE == token.type
    assert "\n" == token.text

    token = lex.get_token()
    assert TokenType.EOF == token.type
    assert "" == token.text