klauer / blark

Beckhoff TwinCAT ST (IEC 61131-3) code parsing in Python using Lark (Earley)
https://klauer.github.io/blark/
GNU General Public License v2.0
42 stars 5 forks source link

Need Support for `JMP` Statements #78

Closed engineerjoe440 closed 1 year ago

engineerjoe440 commented 1 year ago

Found this in the wild, today:

Apparently, it's possible to use jump (JMP) statements in 61131. I'm not happy about it, you're not happy about it, who is happy about it? Anyway... It can be done...

Here's TwinCAT's docs on it: https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/2528307851.html&id=

I'm not sure how the labels are getting parsed in blark right now, but they may also need to be addressed.

Here's some example logic:

IF
    logMessage := concat(logMessage, ', ...<truncated>');
    JMP JumpToMessageLogging;
END_IF

Which resulted in the following traceback:

λ selint
Traceback (most recent call last):
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 177, in _parse
    self._parse_source_code(self.source)
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 280, in _parse_source_code
    self.source_tree = self.__parser.parse(
                       ^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\lark.py", line 652, in parse
    return self.parser.parse(text, start=start, on_error=on_error)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\parser_frontends.py", line 101, in parse
    return self.parser.parse(stream, chosen_start, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\parsers\earley.py", line 276, in parse
    to_scan = self._parse(lexer, columns, to_scan, start_symbol)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\parsers\xearley.py", line 146, in _parse
    to_scan = scan(i, to_scan)
              ^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\parsers\xearley.py", line 119, in scan
    raise UnexpectedCharacters(stream, i, text_line, text_column, {item.expect.name for item in to_scan},
lark.exceptions.UnexpectedCharacters: No terminal matches 'J' in the current parser context, at line 100 col 7

                JMP JumpToMessageLogging;
                    ^
Expected one of:
        * DOT
        * ASSIGNMENT
        * __ANON_10
        * SEMICOLON
        * LSQB
        * LPAR
        * DEREFERENCED
        * __ANON_12
        * __ANON_11