diff --git a/src/testcrush/grammars/transformers.py b/src/testcrush/grammars/transformers.py index 40716cc..dc0cce8 100755 --- a/src/testcrush/grammars/transformers.py +++ b/src/testcrush/grammars/transformers.py @@ -4,7 +4,7 @@ import lark import pathlib -from typing import Literal, Any, Iterable, Union +from typing import Literal, Any, Iterable from testcrush.zoix import Fault from testcrush.utils import get_logger @@ -17,11 +17,11 @@ class FaultReportFaultListTransformer(lark.Transformer): After parsing the segment is returning a list of ``zoix.Fault`` objects with the following attributes: - - Fault_Status (str): 2-uppercase-letter status - - Fault_Type (str): 0|1|R|F|~ - - Timing_Info (list[str]): A list with all timing info (if present) e.g., ['6.532ns'] - - Fault_Sites (list[str]): A list of fault sites represented as strings - - Fault_Attributes (dict[str, str]): A dictionary with all fault attributes (if present) + - fault_status (str): 2-uppercase-letter status + - fault_type (str): 0|1|R|F|~ + - timing_info (list[str]): A list with all timing info (if present) e.g., ['6.532ns'] + - fault_sites (list[str]): A list of fault sites represented as strings + - fault_attributes (dict[str, str]): A dictionary with all fault attributes (if present) Lastly, it resolves on-the-fly any fault equivalences on the generated fault list. """ @@ -151,7 +151,7 @@ def fault_status(self, fault_status: str) -> tuple[Literal["Fault Status"], str] log.debug(f"Returning Fault Status: {fault_status}") - return ("Fault Status", fault_status) + return ("fault_status", fault_status) @lark.v_args(inline=True) def fault_type(self, fault_type: str) -> str: @@ -166,7 +166,7 @@ def fault_type(self, fault_type: str) -> str: consumed """ log.debug(f"Returning Fault Type: {fault_type}") - return ("Fault Type", str(fault_type)) + return ("fault_type", str(fault_type)) def timing_info(self, timings: list[str]) -> tuple[Literal["Timing Info"], list[str]]: """ @@ -180,7 +180,7 @@ def timing_info(self, timings: list[str]) -> tuple[Literal["Timing Info"], list[ consumed """ log.debug(f"Passing Received Timing Info {timings}") - return ("Timing Info", [str(x) for x in timings]) + return ("timing_info", [str(x) for x in timings]) def location_info(self, sites: list[str]) -> tuple[Literal['Fault Sites'], list[str]]: """ @@ -195,7 +195,7 @@ def location_info(self, sites: list[str]) -> tuple[Literal['Fault Sites'], list[ """ log.debug(f"Passing Received Fault Sites in a List {sites}") - return ("Fault Sites", sites) + return ("fault_sites", sites) @lark.v_args(inline=True) def loc_and_site(self, fault_site: str) -> str: @@ -227,7 +227,7 @@ def attributes(self, attributes: list[tuple[str, str]]) -> tuple[Literal["Fault """ log.debug(f"Passing Received Fault Attributes in a List {attributes}") - return ("Fault Attributes", dict(attributes)) + return ("fault_attributes", dict(attributes)) @lark.v_args(inline=True) def attribute_and_value(self, attribute_name: str, attribute_value: str) -> tuple[str, str]: @@ -344,7 +344,7 @@ def rhs(self, formula: str) -> str: ^^^^^^^^^^^^^^^^^^^^^^^^ consumed """ - return str(formula) + return str(formula).replace("^", "**") # Pow in py is ** class TraceTransformerCV32E40P(lark.Transformer): @@ -429,7 +429,7 @@ class TraceTransformerFactory: .. code-block:: python factory = TraceTransformerFactory() - transformer, grammar = factory("ProcessorString") + parser = factory("ProcessorString") """ _current_directory = pathlib.Path(__file__).parent @@ -437,7 +437,7 @@ class TraceTransformerFactory: "CV32E40P": (TraceTransformerCV32E40P, _current_directory / "trace_cv32e40p.lark") } - def __call__(self, processor_type: str) -> Union[tuple[TraceTransformerCV32E40P, str]]: + def __call__(self, processor_type: str) -> lark.Lark: transformer, grammar = self._transformers.get(processor_type, (None, None)) @@ -447,7 +447,7 @@ def __call__(self, processor_type: str) -> Union[tuple[TraceTransformerCV32E40P, with open(grammar) as src: lark_grammar = src.read() - return transformer(), lark_grammar + return lark.Lark(grammar=lark_grammar, start="start", parser="lalr", transformer=transformer()) class FaultReportTransformerFactory: @@ -459,7 +459,7 @@ class FaultReportTransformerFactory: .. code-block:: python factory = FaultReportTransformerFactory() - transformer, grammar = factory("FaultReportSectionString") + parser = factory("FaultReportSectionString") """ _current_directory = pathlib.Path(__file__).parent @@ -469,9 +469,7 @@ class FaultReportTransformerFactory: "Coverage": (FaultReportCoverageTransformer, _current_directory / "frpt_coverage.lark") } - def __call__(self, section_string: str) -> Union[tuple[FaultReportFaultListTransformer, str], - tuple[FaultReportStatusGroupsTransformer, str], - tuple[FaultReportCoverageTransformer, str]]: + def __call__(self, section_string: str) -> lark.Lark: transformer, grammar = self._transformers.get(section_string, (None, None)) @@ -481,4 +479,4 @@ def __call__(self, section_string: str) -> Union[tuple[FaultReportFaultListTrans with open(grammar) as src: lark_grammar = src.read() - return transformer(), lark_grammar + return lark.Lark(grammar=lark_grammar, start="start", parser="lalr", transformer=transformer()) diff --git a/src/unit_tests/test_transformers.py b/src/unit_tests/test_transformers.py index 78c6bf9..c3c7ee4 100644 --- a/src/unit_tests/test_transformers.py +++ b/src/unit_tests/test_transformers.py @@ -22,9 +22,7 @@ class FaultReportFaultListTransformerTest(unittest.TestCase): def get_parser(self): factory = transformers.FaultReportTransformerFactory() - transformer, grammar = factory("FaultList") - return lark.Lark(grammar=grammar, start="start", parser="lalr", transformer=transformer) - + return factory("FaultList") def test_stuck_at_fault_list(self): @@ -40,10 +38,10 @@ def test_stuck_at_fault_list(self): } """ expected_faults = [ - zoix.Fault(Fault_Status='ON', Fault_Type='0', Fault_Sites=['tb.dut.subunit_a.subunit_b.cellA.ZN'], Fault_Attributes={'PC': '30551073', 'time': '45ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='1', Fault_Sites=['tb.dut.subunit_a.subunit_b.cellA.A1']), - zoix.Fault(Fault_Status='ON', Fault_Type='1', Fault_Sites=['tb.dut.subunit_a.subunit_b.cellA.A2']), - zoix.Fault(Fault_Status='ON', Fault_Type='0', Fault_Sites=['tb.dut.subunit_a.subunit_b.operand_b[27:3]']) + zoix.Fault(fault_status='ON', fault_type='0', fault_sites=['tb.dut.subunit_a.subunit_b.cellA.ZN'], fault_attributes={'PC': '30551073', 'time': '45ns'}), + zoix.Fault(fault_status='ON', fault_type='1', fault_sites=['tb.dut.subunit_a.subunit_b.cellA.A1']), + zoix.Fault(fault_status='ON', fault_type='1', fault_sites=['tb.dut.subunit_a.subunit_b.cellA.A2']), + zoix.Fault(fault_status='ON', fault_type='0', fault_sites=['tb.dut.subunit_a.subunit_b.operand_b[27:3]']) ] fault_list = parser.parse(fault_list_sample) @@ -74,15 +72,15 @@ def test_transition_delay_fault_list(self): } """ expected_faults = [ - zoix.Fault(Fault_Status='NN', Fault_Type='F', Fault_Sites=['tb.dut.subunit_c.U1528.CI']), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Fault_Sites=['tb.dut.subunit_c.U1528.CO'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Fault_Sites=['tb.dut.subunit_c.U28.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Fault_Sites=['tb.dut.subunit_c.U1528.CO'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Fault_Sites=['tb.dut.subunit_c.U28.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Fault_Sites=['tb.dut.subunit_c.U1528.S'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Fault_Sites=['tb.dut.subunit_c.U27.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Fault_Sites=['tb.dut.subunit_c.U1528.S'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Fault_Sites=['tb.dut.subunit_c.U27.A']) + zoix.Fault(fault_status='NN', fault_type='F', fault_sites=['tb.dut.subunit_c.U1528.CI']), + zoix.Fault(fault_status='ON', fault_type='R', fault_sites=['tb.dut.subunit_c.U1528.CO'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='R', fault_sites=['tb.dut.subunit_c.U28.A']), + zoix.Fault(fault_status='ON', fault_type='F', fault_sites=['tb.dut.subunit_c.U1528.CO'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='F', fault_sites=['tb.dut.subunit_c.U28.A']), + zoix.Fault(fault_status='ON', fault_type='R', fault_sites=['tb.dut.subunit_c.U1528.S'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='R', fault_sites=['tb.dut.subunit_c.U27.A']), + zoix.Fault(fault_status='ON', fault_type='F', fault_sites=['tb.dut.subunit_c.U1528.S'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='F', fault_sites=['tb.dut.subunit_c.U27.A']) ] # Manually resolve the fault equivalences @@ -121,16 +119,16 @@ def test_small_delay_defects_fault_list(self): fault_list = parser.parse(fault_list_sample) expected_faults = [ - zoix.Fault(Fault_Status='NN', Fault_Type='F', Timing_Info=['6.532ns'], Fault_Sites=['tb.dut.subunit_c.U1528.CI']), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Timing_Info=['6.423ns'], Fault_Sites=['tb.dut.subunit_c.U1528.CO'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Timing_Info=['6.6123ns'], Fault_Sites=['tb.dut.subunit_c.U28.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Timing_Info=['5.532ns'], Fault_Sites=['tb.dut.subunit_c.U1528.CO'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Timing_Info=['6.532ns'], Fault_Sites=['tb.dut.subunit_c.U28.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Timing_Info=['2.232ns'], Fault_Sites=['tb.dut.subunit_c.U1528.S'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='R', Timing_Info=['9.722ns'], Fault_Sites=['tb.dut.subunit_c.U27.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Timing_Info=['9.432ns'], Fault_Sites=['tb.dut.subunit_c.U1528.S'], Fault_Attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), - zoix.Fault(Fault_Status='ON', Fault_Type='F', Timing_Info=['1.532ns'], Fault_Sites=['tb.dut.subunit_c.U27.A']), - zoix.Fault(Fault_Status='ON', Fault_Type='~', Timing_Info=['6', '4', '26'], Fault_Sites=['tb.dut.subunit_d.reg_q[0]']) + zoix.Fault(fault_status='NN', fault_type='F', timing_info=['6.532ns'], fault_sites=['tb.dut.subunit_c.U1528.CI']), + zoix.Fault(fault_status='ON', fault_type='R', timing_info=['6.423ns'], fault_sites=['tb.dut.subunit_c.U1528.CO'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='R', timing_info=['6.6123ns'], fault_sites=['tb.dut.subunit_c.U28.A']), + zoix.Fault(fault_status='ON', fault_type='F', timing_info=['5.532ns'], fault_sites=['tb.dut.subunit_c.U1528.CO'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='F', timing_info=['6.532ns'], fault_sites=['tb.dut.subunit_c.U28.A']), + zoix.Fault(fault_status='ON', fault_type='R', timing_info=['2.232ns'], fault_sites=['tb.dut.subunit_c.U1528.S'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='R', timing_info=['9.722ns'], fault_sites=['tb.dut.subunit_c.U27.A']), + zoix.Fault(fault_status='ON', fault_type='F', timing_info=['9.432ns'], fault_sites=['tb.dut.subunit_c.U1528.S'], fault_attributes={'PC_IF': '00000d1c', 'sim_time': '8905ns'}), + zoix.Fault(fault_status='ON', fault_type='F', timing_info=['1.532ns'], fault_sites=['tb.dut.subunit_c.U27.A']), + zoix.Fault(fault_status='ON', fault_type='~', timing_info=['6', '4', '26'], fault_sites=['tb.dut.subunit_d.reg_q[0]']) ] @@ -153,8 +151,7 @@ class FaultReportStatusGroupsTransformerTest(unittest.TestCase): def get_parser(self): factory = transformers.FaultReportTransformerFactory() - transformer, grammar = factory("StatusGroups") - return lark.Lark(grammar=grammar, start="start", parser="lalr", transformer=transformer) + return factory("StatusGroups") def test_no_leq_group_section(self): @@ -207,9 +204,8 @@ class FaultReportCoverageTransformerTest(unittest.TestCase): def get_parser(self): factory = transformers.FaultReportTransformerFactory() - transformer, grammar = factory("Coverage") - return lark.Lark(grammar=grammar, start="start", parser="lalr", transformer=transformer) - + return factory("Coverage") + def test_coverage_str_no_quotes_lhs(self): parser = self.get_parser() @@ -263,8 +259,7 @@ class TraceTransformerCV32E40PTest(unittest.TestCase): def get_parser(self): factory = transformers.TraceTransformerFactory() - transformer, grammar = factory("CV32E40P") - return lark.Lark(grammar=grammar, start="start", parser="lalr", transformer=transformer) + return factory("CV32E40P") def test_doc_example(self):