Skip to content

Commit 0bd8c74

Browse files
committed
Clarified error handling slightly, made sure to include a syntax error on purpose
1 parent c7d3749 commit 0bd8c74

File tree

10 files changed

+75
-6
lines changed

10 files changed

+75
-6
lines changed

src/plcdoc/interpreter.py

+2
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,15 @@ def _parse_file(self, filepath) -> bool:
132132
plc_item = item.tag # I.e. "POU"
133133

134134
if plc_item not in self.XML_TYPES:
135+
logger.warning(f"Skipping file with XML tag {plc_item}")
135136
continue
136137

137138
# Name is repeated inside the declaration, use it from there instead
138139
# name = item.attrib["Name"]
139140

140141
object_model = self._parse_declaration(item)
141142
if object_model is None:
143+
# Log entry is made inside _parse_declaration() already
142144
continue
143145

144146
obj = PlcDeclaration(object_model, filepath)

src/plcdoc/st_declaration.tx

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ Note: `FUNCTION*` does not have a closing call for some reason!
88

99
There are a lot of `comments*=CommentAny`. This will offer a list of comments, the relevant docblocks need to be
1010
extracted later. There seems no better way to do this in TextX.
11-
Comment captures should be move down (= more basic elements) as much as possible to limit their usage.
11+
Comment captures should be moved down (= more basic elements) as much as possible to limit their usage.
1212

1313
There can be dynamic expressions in variable declarations, which are very tricky to parse. Therefore expected
14-
expressions are parsed greedily as whole string. As a consequence, blocks like argument lists will result in a long
14+
expressions are parsed greedily as whole strings. As a consequence, blocks like argument lists will result in a long
1515
string including the parentheses and commas.
1616
*/
17+
1718
Declaration:
1819
types*=TypeDef
1920
properties*=Property

tests/plc_code/T_ALIAS.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
TYPE T_INTERLOCK : WORD;
2+
END_TYPE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
3+
<DUT Name="E_Error" Id="{c568c63f-be9a-4c9b-92a0-4c4517e2c530}">
4+
<Declaration><![CDATA[{attribute 'qualified_only'}
5+
{attribute 'strict'}
6+
TYPE E_Error :
7+
(
8+
OK := 0,
9+
SomeError := 5,
10+
OtherError
11+
) USINT;
12+
END_TYPE
13+
]]></Declaration>
14+
</DUT>
15+
</TcPlcObject>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
3+
<DUT Name="ST_MyStruct" Id="{111e5770-8d5b-4d8e-bf7d-bb6f31cde823}">
4+
<Declaration><![CDATA[TYPE ST_MyStruct :
5+
STRUCT
6+
number : LREAL;
7+
text : STRING(10);
8+
END_STRUCT
9+
END_TYPE
10+
]]></Declaration>
11+
</DUT>
12+
</TcPlcObject>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
3+
<DUT Name="T_ALIAS" Id="{211c8563-7ef4-49a4-abc1-63eb79b1eac8}">
4+
<Declaration><![CDATA[TYPE T_ALIAS : WORD;
5+
END_TYPE
6+
]]></Declaration>
7+
</DUT>
8+
</TcPlcObject>

tests/roots/test-plc-project/src_plc/MyPLC.plcproj

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
22
<ItemGroup>
3+
<Compile Include="DUTs\E_Error.TcDUT">
4+
<SubType>Code</SubType>
5+
</Compile>
6+
<Compile Include="DUTs\ST_MyStruct.TcDUT">
7+
<SubType>Code</SubType>
8+
</Compile>
9+
<Compile Include="DUTs\T_ALIAS.TcDUT">
10+
<SubType>Code</SubType>
11+
</Compile>
12+
<Compile Include="POUs\F_SyntaxError.TcPOU">
13+
<SubType>Code</SubType>
14+
</Compile>
315
<Compile Include="POUs\FB_MyBlock.TcPOU">
416
<SubType>Code</SubType>
517
</Compile>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
3+
<POU Name="F_SyntaxError" Id="{245635d7-7d54-4aa8-92df-775383b63265}" SpecialFunc="None">
4+
<Declaration><![CDATA[FUNCTION F_SyntaxError RETURNS BOOL
5+
VAR_INPUT
6+
END_VAR
7+
]]></Declaration>
8+
<Implementation>
9+
<ST><![CDATA[]]></ST>
10+
</Implementation>
11+
</POU>
12+
</TcPlcObject>

tests/test_plc_project.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def test_project_interpret(app, status, warning):
1717
"functionblock": ["FB_MyBlock", "FB_SecondBlock", "PlainFunctionBlock"],
1818
"function": ["PlainFunction", "RegularFunction"],
1919
"program": ["MAIN"],
20+
"enum": ["E_Error"],
21+
"struct": ["ST_MyStruct"],
2022
}
2123

2224
for objtype, objects in expected.items():
@@ -29,6 +31,8 @@ def test_project_interpret(app, status, warning):
2931

3032

3133
@pytest.mark.sphinx("dummy", testroot="plc-project")
32-
def test_project_build(app, status, warning):
34+
def test_project_build(app, status, warning, caplog):
3335
"""Test building a document loading a project."""
3436
app.builder.build_all()
37+
# Project contains a function with an outright syntax error, but the project
38+
# completes nonetheless.

tests/test_st_grammar.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytest
66

77
import os
8-
from textx import metamodel_from_file
8+
from textx import metamodel_from_file, TextXSyntaxError
99
import re
1010

1111

@@ -30,6 +30,7 @@ def meta_model():
3030
"E_Filter.txt",
3131
"Properties.txt",
3232
"Unions.txt",
33+
"T_ALIAS.txt",
3334
"GlobalVariableList.txt",
3435
"Main.txt",
3536
]
@@ -41,8 +42,8 @@ def test_grammar_on_files(meta_model, file):
4142
filepath = os.path.realpath(tests_dir + "/plc_code/" + file)
4243
try:
4344
model = meta_model.model_from_file(filepath)
44-
except:
45-
pytest.fail(f"Error when analyzing the file `{file}`")
45+
except TextXSyntaxError as err: # noqa
46+
pytest.fail(f"Error when analyzing the file `{file}`: {err}")
4647
else:
4748
assert model is not None
4849
assert (

0 commit comments

Comments
 (0)