From 460826b70de5faa40ca1305550bcff94e37f3b0e Mon Sep 17 00:00:00 2001 From: Weixuan Zhang Date: Thu, 2 Jun 2022 19:43:00 +0100 Subject: [PATCH] Fix tests; use previous symbol for missing ; --- src/parse.py | 12 +++++++++--- src/scanner.py | 14 ++++++++------ tests/test_integration.py | 13 +++++-------- tests/test_parse.py | 5 +++-- tests/test_scanner.py | 16 ++++++++++++++-- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/parse.py b/src/parse.py index 41e308b..9d32ef5 100644 --- a/src/parse.py +++ b/src/parse.py @@ -268,7 +268,9 @@ def parse_devices_statement(self): return None if not self.current_symbol.type == OperatorType.SEMICOLON: - self.throw_error(SyntaxErrors.UnexpectedToken, "Expected ';'") + self.throw_error( + SyntaxErrors.UnexpectedToken, "Expected ';'", prev_word=True + ) return False if self.syntax_valid: @@ -316,7 +318,9 @@ def parse_device_type(self): if not self.current_symbol.type == OperatorType.LEFT_ANGLE: self.throw_error( - SyntaxErrors.UnexpectedToken, "Expected '<' or ';'" + SyntaxErrors.UnexpectedToken, + "Expected '<' or ';'", + prev_word=True, ) return False, None @@ -455,7 +459,9 @@ def parse_connection_statement(self): return None if not self.current_symbol.type == OperatorType.SEMICOLON: - self.throw_error(SyntaxErrors.UnexpectedToken, "Expected ';'") + self.throw_error( + SyntaxErrors.UnexpectedToken, "Expected ';'", prev_word=True + ) return False if self.syntax_valid: diff --git a/src/scanner.py b/src/scanner.py index 6355bf7..ede192b 100644 --- a/src/scanner.py +++ b/src/scanner.py @@ -106,9 +106,12 @@ class Scanner: pointer_colno: Column number of the pointer. LINE_COMMENT_IDENTIFIER: - Identifier specifying start of line comments. + Identifier specifying start of line comments, default '//'. BLOCK_COMMENT_IDENTIFIERS: - Identifiers specifying start and end of block comments. + Identifiers specifying start and end of block comments, + default ('/*', '*/'). + TREAT_INVALID_CHAR_AS_ERROR: + Whether to throw errors for invalid characters, default True. EOF: Symbol indicating the end of file. @@ -578,18 +581,17 @@ def get_symbol(self) -> Union[Symbol, None]: if Scanner.TREAT_INVALID_CHAR_AS_ERROR: error = SyntaxErrors.UnexpectedToken("Invalid character") symbol_lineno, symbol_colno = self.get_lineno_colno( - self._pointer_pos - 1 + self._pointer_pos ) - [symbol_id] = self.names.lookup([current_character]) error.symbol = Symbol( symbol_type=ExternalSymbolType.IDENTIFIER, - symbol_id=symbol_id, + symbol_id=-1, lineno=symbol_lineno, colno=symbol_colno, ) self.errors.add_error( error=error, - show_end_of_word=True, + show_end_of_word=False, parse_entry_func_name="get_symbol", base_depth=0, ) diff --git a/tests/test_integration.py b/tests/test_integration.py index 7d6670d..3009222 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -6,6 +6,7 @@ from network import Network from names import Names from monitors import Monitors +from exceptions import Errors @pytest.fixture() @@ -40,18 +41,14 @@ def names(): @pytest.fixture() -def scanner(input_file, names): - """Create a scanner instance with the test file.""" - return Scanner(input_file, names) - - -@pytest.fixture() -def parser(names, scanner): +def parser(names, input_file): """Create a parser instance.""" devices = Devices(names) network = Network(names, devices) monitors = Monitors(names, devices, network) - return Parser(names, devices, network, monitors, scanner) + errors = Errors() + scanner = Scanner(input_file, names, errors) + return Parser(names, devices, network, monitors, scanner, errors) def test_parse_definition_file(parser): diff --git a/tests/test_parse.py b/tests/test_parse.py index 751a767..d62fb7e 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -6,7 +6,7 @@ from scanner import Symbol from names import Names from symbol_types import OperatorType, DeviceType -from exceptions import SyntaxErrors, SemanticErrors +from exceptions import SyntaxErrors, SemanticErrors, Errors class MockScanner: @@ -37,8 +37,9 @@ def make_parser(statement): names.lookup(statement) devices = Devices(names) scanner = MockScanner(names, statement) + errors = Errors() - return Parser(names, devices, None, None, scanner) + return Parser(names, devices, None, None, scanner, errors) @pytest.mark.parametrize( diff --git a/tests/test_scanner.py b/tests/test_scanner.py index 3a82090..bdac5cd 100644 --- a/tests/test_scanner.py +++ b/tests/test_scanner.py @@ -11,6 +11,18 @@ ) +class StubErrors: + def add_error( + self, + error, + show_end_of_word, + show_cursor=True, + parse_entry_func_name="parse_network", + base_depth=2, + ): + return + + def test_symbol_equal(): symbol1 = Symbol( symbol_type=ExternalSymbolType.IDENTIFIER, @@ -62,7 +74,7 @@ def input_file(tmp_path, file_content): @pytest.fixture() def scanner(input_file): """Create a scanner instance with the test file.""" - return Scanner(input_file, Names()) + return Scanner(input_file, Names(), StubErrors()) # noqa # ----------------------------------------------------------------------------- @@ -582,7 +594,7 @@ def test_get_symbol(tmp_path, monkeypatch, content, expected_symbols): monkeypatch.setattr("names.ReservedSymbolType", ReservedSymbolType) monkeypatch.setattr("scanner.ReservedSymbolType", ReservedSymbolType) - scanner = Scanner(p, Names()) + scanner = Scanner(p, Names(), StubErrors()) # noqa expected_symbols = iter(expected_symbols) while (symbol := scanner.get_symbol()) is not None: