예제 #1
0
 def __init__(self, names, devices, network, monitors, scanner):
     """Initialise constants."""
     # Initialise parameters as variables of class
     self.scanner = scanner
     self.names = names
     self.devices = devices
     self.network = network
     self.monitors = monitors
     # Initialise symbol as an empty symbol
     self.symbol = Symbol()
     # Variable to store nº errors
     self.error_count = 0
     # List of error codes used in get_error_codes
     self.error_codes = []
     # Flag changed when an error is encountered and
     # set back to true when the parser recovers
     self.recovered_from_definition_error = True
     # Variables for  storing info for parsing
     self.current_device = Symbol()
     self.current_number = Symbol()
     self.identifier_list = []
     self.current_name = Symbol()
     self.current_port = Symbol()
     self.outputs_list = []
     self.inputs_list = []
     self.monitors_list = []
예제 #2
0
    def __init__(self, names, devices, network, monitors, scanner):
        """Initialise constants."""
        self.names = names
        self.devices = devices
        self.network = network
        self.monitors = monitors
        self.scanner = scanner

        self.symbol = Symbol()
        self.error_count = 0  # Total error count of errors during parsing
        self.err_flag = False  # Indicates comma/semicolon is stopping symbol

        # Global record of all possible errors
        [
            self.NO_DEVICES, self.NO_CONNECTIONS, self.NO_MONITORS,
            self.NO_END, self.NO_COLON, self.NO_COMMA, self.NO_SEMICOLON,
            self.NO_EQUALS, self.NO_NUMBER, self.NO_STRING, self.INVALID_LOGIC,
            self.NO_LEFTBRACKET, self.NO_RIGHTBRACKET, self.NO_EOF,
            self.UNUSED_INPUTS
        ] = self.names.unique_error_codes(15)

        # Populate occurrence of all errors in list for easy testing
        self.reported_errs = []

        # Logic types with configuration variables
        self.log_types_vars = [
            'CLOCK', 'SWITCH', 'AND', 'NAND', 'OR', 'NOR', 'SIGGEN'
        ]

        # Printing of errors to GUI
        self.print_gui = []

        # Store previous symbol
        self.prev_sym = Symbol()
        self.prev_sym.pos = 1  # EOF Error adjustment
        self.flag_prev_sym = False

        # Store an older and current symbol for dealing with semantic errors
        self.old_symbol = Symbol()
        self.old_symbol.pos = 1  # EOF Error adjustment
        self.older_symbol = Symbol()
        self.older_symbol.pos = 1  # EOF Error adjustment
        self.curr_symbol = Symbol()
        self.curr_symbol.pos = 1  # EOF Error adjustment
        self.flag_old_sym = False
예제 #3
0
def test_build_list(parser_device):
    """Test build_list"""
    scanner = parser_device.scanner
    parser_device.symbol = scanner.get_symbol()

    assert parser_device.build_list(scanner.DEVICETYPE, parser_device.device)

    parser_device.symbol = Symbol(scanner.NUMBER, 1, 0, 0)
    assert not parser_device.build_list(scanner.DEVICETYPE,
                                        parser_device.device)
예제 #4
0
def test_get_io(parser_io):
    """Test get_io"""
    names = parser_io.names
    scanner = parser_io.scanner
    devices = parser_io.devices
    parser_io.symbol = scanner.get_symbol()

    assert parser_io.get_io(parser_io.OUTPUT) == (parser_io.DT, devices.Q_ID)

    [AND] = names.lookup(["and"])
    parser_io.symbol = Symbol(scanner.NAMES, AND, 0, 0)
    assert parser_io.get_io(parser_io.OUTPUT) == (None, None)
예제 #5
0
    def eval_minus(location: Location, c: str):
        if c is None:
            return Symbol('-')

        if c.isdigit():
            return partial(
                eval_integer_literal,
                sign=-1,
                value=ord(c) - ord('0'),
            )

        return partial(eval_symbol, content=[f'-{c}'])
예제 #6
0
    def device_definition(self):
        """Parse a device defintion.

        The EBNF grammar is the following:
        identifier, { "," , identifier }, ":=",
        device_type, [ "(" , number , ")" ], ";" ;
        """
        self.identifier()
        # Throught device definition only enter if statements and while
        # loops if we have recovered from an error. Equivalent to
        # stop parsing device_definition if an error occurs.
        while (self.symbol.type == self.scanner.COMMA and
               self.recovered_from_definition_error):
            self.symbol = self.scanner.get_symbol()
            self.identifier()
        if (self.symbol.type == self.scanner.DEVICE_DEF and
                self.recovered_from_definition_error):
            self.symbol = self.scanner.get_symbol()
            self.device_type()
            if (self.symbol.type == self.scanner.BRACKET_LEFT and
                    self.recovered_from_definition_error):
                self.symbol = self.scanner.get_symbol()
                self.number()
                if(self.symbol.type == self.scanner.BRACKET_RIGHT and
                   self.recovered_from_definition_error):
                    self.symbol = self.scanner.get_symbol()
                else:
                    self.error(self.SYNTAX_ERROR, ")")
            # If the symbol is not a bracket but a number must
            # be missing left bracket from grammar.
            elif (self.symbol.type == self.scanner.NUMBER and
                  self.recovered_from_definition_error):
                self.error(self.SYNTAX_ERROR, "(")
            else:
                # If no number specified in file set variable current_number
                # by default to an empty symbol.
                self.current_number = Symbol()
            if (self.symbol.type == self.scanner.SEMICOLON and
                    self.recovered_from_definition_error):
                # Making devices does not break if errors have occured
                # previously but not during device_definition
                self.make_devices()
                self.symbol = self.scanner.get_symbol()
            else:
                self.error(self.SYNTAX_ERROR, ";")
        # From grammar name followed by name possibly indicates mising coma
        elif (self.symbol.type == self.scanner.NAME):
            self.error(self.SYNTAX_ERROR, ",")
        else:
            self.error(self.SYNTAX_ERROR, ":=")
예제 #7
0
 def __init__(self, names, devices, network, monitors, scanner):
     """Initialise attributes and types of syntax error."""
     self.names = names
     self.devices = devices
     self.network = network
     self.monitors = monitors
     self.scanner = scanner
     self.symbol = Symbol()
     # self.cursor = 0 # this might be needed
     self.error_count = 0
     self.error_output = []
     self.error_to_gui = []  # for error display in GUI
     self.error_cursor = []
     self.errline_num = []
     self.errline_pos = []
     self.error_type_list = [
         self.NO_KEYWORD_DEVICES, self.NO_KEYWORD_CONNECTIONS,
         self.NO_KEYWORD_MONITORS, self.NO_EQUALS, self.NO_SEMICOLON,
         self.DOT_INVALID, self.SLASH_INVALID, self.NO_COMMA, self.NOT_NAME,
         self.NOT_NUMBER, self.NOT_SYMBOL
     ] = self.names.unique_error_codes(11)
예제 #8
0
def new_symbol():
    """Return a new instance of the symbol class."""
    return Symbol()
예제 #9
0
    def eval_symbol(location: Location, c: str, *, content: t.List[str]):
        if c is None:
            return Symbol(''.join(content))

        content.append(c)
        return partial(eval_symbol, content=content)
예제 #10
0
 def clear_vars(self):
     """Clear all symbols used during parsing."""
     self.current_device = Symbol()
     self.current_number = Symbol()
     self.current_name = Symbol()
     self.current_port = Symbol()