From d55eb503e3be1f165fe86d34e623c2a79f1323d3 Mon Sep 17 00:00:00 2001 From: Andrej Lajovic Date: Fri, 11 Jul 2025 16:43:40 +0200 Subject: [PATCH 1/2] Increase priority of constant rule in grammar (#108) --- blark/iec.lark | 10 +++++----- blark/tests/test_parsing.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/blark/iec.lark b/blark/iec.lark index 90808d5..e942aae 100644 --- a/blark/iec.lark +++ b/blark/iec.lark @@ -36,11 +36,11 @@ _library_element_declaration: data_type_declaration IDENTIFIER: /[A-Za-z_][A-Za-z0-9_]*/i // B.1.2 -constant: time_literal - | numeric_literal - | string_literal - | bit_string_literal - | boolean_literal +constant.1: time_literal + | numeric_literal + | string_literal + | bit_string_literal + | boolean_literal // B.1.2.1 BIT_STRING: /(1|0)(_?(1|0))*/ diff --git a/blark/tests/test_parsing.py b/blark/tests/test_parsing.py index ef93009..0dc7b4a 100644 --- a/blark/tests/test_parsing.py +++ b/blark/tests/test_parsing.py @@ -1,5 +1,6 @@ import pathlib +import lark import pytest from ..parse import parse, parse_source_code, summarize @@ -130,3 +131,31 @@ def test_comment_parsing(code: str, expected_snippets: list[str]): result.source_code[token.start_pos: token.end_pos] for token in result.comments ] assert snippets == expected_snippets + + +def tree_contains_token(tree, token): + """ + Checks whether the given lark tree contains the given token, either as a node + or as a leaf. + """ + return any(( + tree.data == token, + token in tree.children, + any(tree_contains_token(child, token) + for child in tree.children + if isinstance(child, lark.Tree)))) + + +@pytest.mark.parametrize( + "start_rule, code, token_type, token_value", + [ + pytest.param("unary_expression", "TRUE", "RULE", "constant"), + pytest.param("unary_expression", "TRUE", "TRUE_VALUE", "TRUE"), + pytest.param("unary_expression", "FALSE", "RULE", "constant"), + pytest.param("unary_expression", "FALSE", "FALSE_VALUE", "FALSE"), + ], +) +def test_key_token(start_rule: str, code: str, token_type: str, token_value: str): + """Test whether the parse tree contains the key token.""" + result = conftest.get_grammar(start=start_rule).parse(code) + assert tree_contains_token(result, lark.Token(token_type, token_value)) From c1193b97ebdfce0f34fbcfb6264efe2dada8f726 Mon Sep 17 00:00:00 2001 From: Andrej Lajovic Date: Sun, 13 Jul 2025 19:33:59 +0200 Subject: [PATCH 2/2] Remove string_var_declaration from grammar (#108) --- blark/iec.lark | 8 -------- blark/transform.py | 41 +---------------------------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/blark/iec.lark b/blark/iec.lark index e942aae..a6a771b 100644 --- a/blark/iec.lark +++ b/blark/iec.lark @@ -430,7 +430,6 @@ edge_declaration: var1_list ":" _BOOL ( R_EDGE | F_EDGE ) ?var_init_decl: array_var_init_decl | structured_var_init_decl - | string_var_declaration | var1_init_decl | fb_decl @@ -499,11 +498,6 @@ location: _AT direct_variable global_var_list: global_var_name ( "," global_var_name )* -?string_var_declaration: single_byte_string_var_declaration - | double_byte_string_var_declaration - -single_byte_string_var_declaration: var1_list ":" single_byte_string_spec - bracketed_expression: "[" expression "]" string_spec_length: parenthesized_expression @@ -511,8 +505,6 @@ string_spec_length: parenthesized_expression single_byte_string_spec: STRING [ string_spec_length ] [ ":=" SINGLE_BYTE_CHARACTER_STRING ] -double_byte_string_var_declaration: var1_list ":" double_byte_string_spec - double_byte_string_spec: WSTRING [ string_spec_length ] [ ":=" DOUBLE_BYTE_CHARACTER_STRING ] incomplete_located_var_declarations: _VAR [ variable_attributes ] incomplete_located_var_decl* _END_VAR ";"* diff --git a/blark/transform.py b/blark/transform.py index df7b5c5..8747af5 100644 --- a/blark/transform.py +++ b/blark/transform.py @@ -2494,7 +2494,7 @@ def __str__(self) -> str: EnumeratedTypeInitialization, ArrayTypeInitialization, InitializedStructure, - _GenericInit, # StringVariableInitDeclaration, EdgeDeclaration + _GenericInit, # EdgeDeclaration ] @@ -2568,44 +2568,6 @@ class StructuredVariableInitDeclaration(InitDeclaration): meta: Optional[Meta] = meta_field() -@dataclass -@_rule_handler( - "single_byte_string_var_declaration", - "double_byte_string_var_declaration", - comments=True -) -class StringVariableInitDeclaration(InitDeclaration): - """ - A declaration of one or more variables using single/double byte strings, - with an optinoal initialization value. - - Examples:: - - sVar1 : STRING(2_500_000) := 'test1' - sVar2, sVar3 : STRING(Param.iLower) := 'test2' - sVar4, sVar5 : WSTRING(Param.iLower) := "test3" - """ - variables: List[DeclaredVariable] - spec: StringTypeSpecification - value: Optional[lark.Token] - init: _GenericInit - meta: Optional[Meta] = meta_field() - - @staticmethod - def from_lark(variables: List[DeclaredVariable], string_info: StringTypeInitialization): - return StringVariableInitDeclaration( - variables=variables, - spec=string_info.spec, - value=string_info.value, - init=_GenericInit( - base_type_name=str(string_info.spec.base_type_name), - full_type_name=str(string_info.spec.full_type_name), - value=str(string_info.value), - repr=join_if(string_info.spec, " := ", string_info.value), - ) - ) - - @dataclass @_rule_handler("edge_declaration", comments=True) class EdgeDeclaration(InitDeclaration): @@ -3294,7 +3256,6 @@ def __str__(self) -> str: VariableInitDeclaration = Union[ ArrayVariableInitDeclaration, - StringVariableInitDeclaration, VariableOneInitDeclaration, FunctionBlockDeclaration, EdgeDeclaration,