Skip to content

Commit 672c469

Browse files
authored
Merge pull request #105 from klauer/repeated-structured-type-declaration-fails-to-parse
Repeated structured type declaration fails to parse
2 parents f694b3d + cbbbf7c commit 672c469

File tree

6 files changed

+43
-42
lines changed

6 files changed

+43
-42
lines changed

blark/iec.lark

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ structure_type_declaration: structure_type_name_declaration [ extends ] ":" [ in
350350

351351
initialized_structure: structure_type_name ":=" structure_initialization
352352

353-
structure_element_declaration: structure_element_name [ incomplete_location ] ":" ( initialized_structure | array_spec_init | simple_spec_init | subrange_spec_init | enumerated_spec_init | function_call )
353+
structure_element_declaration: var1_list ":" ( initialized_structure | array_spec_init | simple_spec_init | subrange_spec_init | enumerated_spec_init | function_call )
354354

355355
union_element_declaration: structure_element_name ":" ( array_specification | simple_specification | indirect_simple_specification | subrange_specification | enumerated_specification )
356356

blark/summary.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -174,18 +174,19 @@ def from_declaration(
174174
result = {}
175175

176176
if isinstance(item, tf.StructureElementDeclaration):
177-
result[item.name] = DeclarationSummary(
178-
name=str(item.name),
179-
item=item,
180-
location=item.location.name if item.location else None,
181-
block=block_header,
182-
type=item.full_type_name, # TODO -> get_type_summary?
183-
base_type=item.base_type_name,
184-
value=str(item.value),
185-
parent=parent.name if parent is not None else "",
186-
filename=filename,
187-
**Summary.get_meta_kwargs(item.meta),
188-
)
177+
for var in item.variables:
178+
result[var.name] = DeclarationSummary(
179+
name=str(var.name),
180+
item=item,
181+
location=str(var.location).replace("AT ", "") if var.location else None,
182+
block=block_header,
183+
type=item.full_type_name, # TODO -> get_type_summary?
184+
base_type=item.base_type_name,
185+
value=str(item.value),
186+
parent=parent.name if parent is not None else "",
187+
filename=filename,
188+
**Summary.get_meta_kwargs(item.meta),
189+
)
189190
elif isinstance(item, tf.UnionElementDeclaration):
190191
result[item.name] = DeclarationSummary(
191192
name=str(item.name),
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
TYPE someStruct :
2+
STRUCT
3+
AlertTimer, SignalBadTimer, QualityBadTimer : library.TPUDO;
4+
END_STRUCT
5+
END_TYPE

blark/tests/test_summary.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def test_twincat_general(twincat_general_281: PlcProjectMetadata):
237237
DeclarationCheck(
238238
name="I_EcatMaster1",
239239
base_type="AMSNETID",
240-
location="input",
240+
location="%I*",
241241
comments=[
242242
"{attribute 'naming' := 'omit'}",
243243
"(* AMS Net ID used for FB_EcatDiag, among others *)"

blark/tests/test_transformer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ def test_bool_literal_roundtrip(name, value, expected):
392392
param("var1_init_decl", "stVar1, stVar2 : TypeName := Value"),
393393
param("var1_init_decl", "stVar1, stVar2 : (Value1 := 1, Value2 := 2)"),
394394
param("var1_init_decl", "stVar1, stVar2 : (Value1 := 1, Value2 := 2) INT := Value1"),
395+
param("structure_element_declaration", "Name1, Name2 : INT"),
395396
param("structure_type_declaration", "TypeName :\nSTRUCT\nEND_STRUCT"),
396397
param("structure_type_declaration", "TypeName EXTENDS Other.Type :\nSTRUCT\nEND_STRUCT"),
397398
param("structure_type_declaration", "TypeName : POINTER TO\nSTRUCT\nEND_STRUCT"),

blark/transform.py

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ def __str__(self) -> str:
19241924
body = "\n".join(
19251925
(
19261926
"STRUCT",
1927-
indent("\n".join(str(decl) for decl in self.declarations)),
1927+
indent("\n".join(f"{decl};" for decl in self.declarations)),
19281928
"END_STRUCT",
19291929
)
19301930
)
@@ -1940,24 +1940,25 @@ def __str__(self) -> str:
19401940
@_rule_handler("structure_element_declaration", comments=True)
19411941
class StructureElementDeclaration:
19421942
"""
1943-
Declaration of a single element of a structure.
1943+
Declaration line of a structure, typically with a single variable name.
1944+
1945+
Excludes the trailing semicolon.
19441946
19451947
Examples::
19461948
1947-
iValue : INT := 3 + 4;
1948-
stTest : ST_Testing := (1, 2);
1949-
eValue : E_Test := E_Test.ABC;
1950-
arrValue : ARRAY [1..2] OF INT := [1, 2];
1951-
arrValue1 : INT (1..2);
1952-
arrValue1 : (Value1 := 1) INT;
1953-
sValue : STRING := 'abc';
1954-
iValue1 AT %I* : INT := 5;
1955-
sValue1 : STRING[10] := 'test';
1949+
iValue : INT := 3 + 4
1950+
stTest : ST_Testing := (1, 2)
1951+
eValue : E_Test := E_Test.ABC
1952+
arrValue : ARRAY [1..2] OF INT := [1, 2]
1953+
arrValue1 : INT (1..2)
1954+
arrValue1 : (Value1 := 1) INT
1955+
sValue : STRING := 'abc'
1956+
iValue1 AT %I* : INT := 5
1957+
sValue1 : STRING[10] := 'test'
1958+
Timer1, Timer2, Timer3 : library.TPUDO
19561959
"""
1957-
name: lark.Token
1958-
location: Optional[IncompleteLocation]
1960+
variables: List[DeclaredVariable]
19591961
init: Union[
1960-
StructureInitialization,
19611962
ArrayTypeInitialization,
19621963
StringTypeInitialization,
19631964
TypeInitialization,
@@ -1968,35 +1969,24 @@ class StructureElementDeclaration:
19681969
]
19691970
meta: Optional[Meta] = meta_field()
19701971

1971-
@property
1972-
def variables(self) -> List[str]:
1973-
"""API compat: list of variable names."""
1974-
return [self.name]
1975-
19761972
@property
19771973
def value(self) -> str:
19781974
"""The initialization value, if applicable."""
1979-
if isinstance(self.init, StructureInitialization):
1980-
return str(self.init)
19811975
return str(self.init.value)
19821976

19831977
@property
19841978
def base_type_name(self) -> Union[lark.Token, str]:
19851979
"""The base type name."""
1986-
if isinstance(self.init, StructureInitialization):
1987-
return self.name
19881980
return self.init.base_type_name
19891981

19901982
@property
1991-
def full_type_name(self) -> lark.Token:
1983+
def full_type_name(self) -> Union[lark.Token, str]:
19921984
"""The full type name."""
1993-
if isinstance(self.init, StructureInitialization):
1994-
return self.name
19951985
return self.init.full_type_name
19961986

19971987
def __str__(self) -> str:
1998-
name_and_location = join_if(self.name, " ", self.location)
1999-
return f"{name_and_location} : {self.init};"
1988+
variables = ", ".join(str(var) for var in self.variables)
1989+
return f"{variables} : {self.init}"
20001990

20011991

20021992
UnionElementSpecification = Union[
@@ -4585,6 +4575,10 @@ def full_subrange(self):
45854575
def var1_list(self, *items: DeclaredVariable) -> List[DeclaredVariable]:
45864576
return list(items)
45874577

4578+
@_annotator_method_wrapper
4579+
def struct_var1_list(self, *items: DeclaredVariable) -> List[DeclaredVariable]:
4580+
return list(items)
4581+
45884582
@_annotator_method_wrapper
45894583
def fb_decl_name_list(self, *items: lark.Token) -> List[lark.Token]:
45904584
return list(items)

0 commit comments

Comments
 (0)