Skip to content

Commit

Permalink
Clarified error handling slightly, made sure to include a syntax erro…
Browse files Browse the repository at this point in the history
…r on purpose
  • Loading branch information
RobertoRoos committed Nov 28, 2024
1 parent c7d3749 commit 0bd8c74
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/plcdoc/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,15 @@ def _parse_file(self, filepath) -> bool:
plc_item = item.tag # I.e. "POU"

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

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

object_model = self._parse_declaration(item)
if object_model is None:
# Log entry is made inside _parse_declaration() already
continue

obj = PlcDeclaration(object_model, filepath)
Expand Down
5 changes: 3 additions & 2 deletions src/plcdoc/st_declaration.tx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ Note: `FUNCTION*` does not have a closing call for some reason!

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

There can be dynamic expressions in variable declarations, which are very tricky to parse. Therefore expected
expressions are parsed greedily as whole string. As a consequence, blocks like argument lists will result in a long
expressions are parsed greedily as whole strings. As a consequence, blocks like argument lists will result in a long
string including the parentheses and commas.
*/

Declaration:
types*=TypeDef
properties*=Property
Expand Down
2 changes: 2 additions & 0 deletions tests/plc_code/T_ALIAS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TYPE T_INTERLOCK : WORD;
END_TYPE
15 changes: 15 additions & 0 deletions tests/roots/test-plc-project/src_plc/DUTs/E_Error.TcDUT
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
<DUT Name="E_Error" Id="{c568c63f-be9a-4c9b-92a0-4c4517e2c530}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
TYPE E_Error :
(
OK := 0,
SomeError := 5,
OtherError
) USINT;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>
12 changes: 12 additions & 0 deletions tests/roots/test-plc-project/src_plc/DUTs/ST_MyStruct.TcDUT
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
<DUT Name="ST_MyStruct" Id="{111e5770-8d5b-4d8e-bf7d-bb6f31cde823}">
<Declaration><![CDATA[TYPE ST_MyStruct :
STRUCT
number : LREAL;
text : STRING(10);
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>
8 changes: 8 additions & 0 deletions tests/roots/test-plc-project/src_plc/DUTs/T_ALIAS.TcDUT
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
<DUT Name="T_ALIAS" Id="{211c8563-7ef4-49a4-abc1-63eb79b1eac8}">
<Declaration><![CDATA[TYPE T_ALIAS : WORD;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>
12 changes: 12 additions & 0 deletions tests/roots/test-plc-project/src_plc/MyPLC.plcproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Include="DUTs\E_Error.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\ST_MyStruct.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\T_ALIAS.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\F_SyntaxError.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\FB_MyBlock.TcPOU">
<SubType>Code</SubType>
</Compile>
Expand Down
12 changes: 12 additions & 0 deletions tests/roots/test-plc-project/src_plc/POUs/F_SyntaxError.TcPOU
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.11">
<POU Name="F_SyntaxError" Id="{245635d7-7d54-4aa8-92df-775383b63265}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION F_SyntaxError RETURNS BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</POU>
</TcPlcObject>
6 changes: 5 additions & 1 deletion tests/test_plc_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ def test_project_interpret(app, status, warning):
"functionblock": ["FB_MyBlock", "FB_SecondBlock", "PlainFunctionBlock"],
"function": ["PlainFunction", "RegularFunction"],
"program": ["MAIN"],
"enum": ["E_Error"],
"struct": ["ST_MyStruct"],
}

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


@pytest.mark.sphinx("dummy", testroot="plc-project")
def test_project_build(app, status, warning):
def test_project_build(app, status, warning, caplog):
"""Test building a document loading a project."""
app.builder.build_all()
# Project contains a function with an outright syntax error, but the project
# completes nonetheless.
7 changes: 4 additions & 3 deletions tests/test_st_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest

import os
from textx import metamodel_from_file
from textx import metamodel_from_file, TextXSyntaxError
import re


Expand All @@ -30,6 +30,7 @@ def meta_model():
"E_Filter.txt",
"Properties.txt",
"Unions.txt",
"T_ALIAS.txt",
"GlobalVariableList.txt",
"Main.txt",
]
Expand All @@ -41,8 +42,8 @@ def test_grammar_on_files(meta_model, file):
filepath = os.path.realpath(tests_dir + "/plc_code/" + file)
try:
model = meta_model.model_from_file(filepath)
except:
pytest.fail(f"Error when analyzing the file `{file}`")
except TextXSyntaxError as err: # noqa
pytest.fail(f"Error when analyzing the file `{file}`: {err}")
else:
assert model is not None
assert (
Expand Down

0 comments on commit 0bd8c74

Please sign in to comment.