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

Variable with underscore #83

Closed drehstromer closed 11 months ago

drehstromer commented 11 months ago

I get an error if i want to parse a TcPou with vars inside which start with an underscore. for example: _eLocalSeverity : E_Severity;

I get the following error message: Failed to parse D:\GIT\Logging\POU\LogFB\FB_LogBase.TcPOU FBLogBase/declaration: Exception: UnexpectedCharacters: No terminal matches '' in the current parser context, at line 9 col 2

    _eLocalSeverity                                 : E_Severity;
    ^

Expected one of:

Failed to parse some source code files: D:\GIT\Logging\POU\LogFB\FB_LogBase.TcPOU: FB_LogBase/declaration

I'm sorry but i dont understand python and lark well enough to find the error and the solution to that error myself. I hope you can help me. Thanks

klauer commented 11 months ago

Hi @drehstromer, thanks for giving blark a try and reaching out.

Identifiers in blark are allowed to start with underscores, so I think there may be something else that it's failing to recognize in your code. Would you be able to provide the full code file (or a minimal version of it) that exhibits the error you pasted? I'd be happy to look into it and fix up the core of the issue.

drehstromer commented 11 months ago

Hi @klauer Here is the file: FB_Log.zip Thanks for your help!

klauer commented 11 months ago

Interestingly I'm unable to reproduce the issue. On blark v0.7.0, I see the following with your file:

$ blark parse --print-filename Logging/POU/LogFB/FB_Log.TcPOU
[1] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log/declaration (function_block)
[2] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log._GetLogConditionFullfilled/declaration (method)
[3] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log._GetLogConditionFullfilled/implementation (method)
[4] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log._Init/declaration (method)
[5] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log._Init/implementation (method)
[6] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.AddString/declaration (method)
[7] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.AddString/implementation (method)
[8] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.AddVar/declaration (method)
[9] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.AddVar/implementation (method)
[10] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Debug/declaration (method)
[11] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Debug/implementation (method)
[12] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Error/declaration (method)
[13] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Error/implementation (method)
[14] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Fatal/declaration (method)
[15] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Fatal/implementation (method)
[16] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Info/declaration (method)
[17] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Info/implementation (method)
[18] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.LogCollector.set/declaration (property)
[19] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.LogCollector.set/implementation (property)
[20] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.MinSeverity.set/declaration (property)
[21] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.MinSeverity.set/implementation (property)
[22] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Name.set/declaration (property)
[23] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Name.set/implementation (property)
[24] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Send/declaration (method)
[25] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Send/implementation (method)
[26] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Trace/declaration (method)
[27] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Trace/implementation (method)
[28] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Warn/declaration (method)
[29] Parsing /Users/klauer/Repos/blark/Logging/POU/LogFB/FB_Log.TcPOU: FB_Log.Warn/implementation (method)

Would you mind checking blark --version and show me the output? If it's less than v0.7.0, please try upgrading and giving it another shot.

drehstromer commented 11 months ago

blark --version gives the output: 0.7.0

I tried yesterday the command: blark format D:\GIT\Logging\POU\LogFB\FB_LogBase.TcPOU This command threwed the error The parse command works on my computer. Maybe I'm using the library wrong? I want a formated file, so that i can use it for my documentation. Additionaly it would be nice if i could use this output and format it in a standard way, to describe for e.g. all methods, each with the comments to describe it. Is something like this already possible?

Thanks for your help!

klauer commented 11 months ago

I tried yesterday the command: blark format D:\GIT\Logging\POU\LogFB\FB_LogBase.TcPOU This command threwed the error

Ah, OK - blark format does indeed have a problem with your file. Thanks again for reporting this! I'm going to resolve it in #84.

Would you be OK if I included it as a test case in blark? (Or a modified version of it, if that's preferable?)

blark format --overwrite FB_Log.TcPOU should work after that fix gets merged. Keep in mind this project is a big work-in-progress, so be sure your stuff is version-controlled before you go overwriting it :)

Maybe I'm using the library wrong? I want a formated file, so that i can use it for my documentation.

You've got the right idea. But you might be unhappy with blark's idea of "formatted" output - it's not exactly pretty just yet! There are alternative projects you might consider, like https://github.com/Roald87/TcBlack

Additionaly it would be nice if i could use this output and format it in a standard way, to describe for e.g. all methods, each with the comments to describe it. Is something like this already possible?

That's one of the goals! I have some of the basics done, but it's not quite ready for the general public just yet. It's called the "sphinx domain" - and I've been noting progress in https://github.com/klauer/blark/issues/17 . The idea is that you would use sphinx along with blark to generate API documentation for your entire project.

If you're willing to drop into Python, you can generate any documentation format you prefer. It's pretty easy to iterate over the summary tooling (see my response in https://github.com/klauer/blark/discussions/80 and also the submitter's project - it may be of interest), for example:

import blark.parse
import blark.summary

parsed = list(blark.parse.parse("Logging/POU/LogFB/FB_Log.TcPOU"))
summary = blark.summary.CodeSummary.from_parse_results(parsed)

fb_log = summary.function_blocks["FB_Log"]
for name, decl in fb_log.declarations.items():
    print(f"Declaration {name} is of type: {decl.type} and has comments={decl.comments} pragmas={decl.pragmas}")

which outputs:

``` Declaration _aLogBaseExt is of type: ARRAY [-1..SIZEOF(TwinCAT_SystemInfoVarList._TaskInfo) / SIZEOF(PlcTaskSystemInfo)] OF FB_LogBaseExt and has comments=[] pragmas=[Token('PRAGMA', "{attribute 'hide'}")] Declaration _aInternalMsg is of type: ARRAY [-1..SIZEOF(TwinCAT_SystemInfoVarList._TaskInfo) / SIZEOF(PlcTaskSystemInfo)] OF STRING(100) and has comments=[] pragmas=[Token('PRAGMA', "{attribute 'hide'}")] Declaration _aLogSeverity is of type: ARRAY [-1..SIZEOF(TwinCAT_SystemInfoVarList._TaskInfo) / SIZEOF(PlcTaskSystemInfo)] OF E_Severity and has comments=[] pragmas=[Token('PRAGMA', "{attribute 'hide'}")] Declaration _InstancePath is of type: STRING and has comments=[Token('SINGLE_LINE_COMMENT', '// contains instance path \t')] pragmas=[Token('PRAGMA', "{attribute 'hide'}"), Token('PRAGMA', "{attribute 'instance-path'} "), Token('PRAGMA', "{attribute 'noinit'} ")] Declaration _bUseExternalName is of type: BOOL and has comments=[] pragmas=[Token('PRAGMA', "{attribute 'hide'}")] Declaration _InstanceName is of type: STRING(25) and has comments=[] pragmas=[] ```
drehstromer commented 11 months ago

Thanks for fixing it. It works now.

Would you be OK if I included it as a test case in blark? (Or a modified version of it, if that's preferable?)

Yes no problem. I can provide you in the future with new testmaterial if you could use it. My goal is to provide an easy documentation for all my code. As you mentioned in #80 code documentation isnt the favourite work of plc developers, but in my opinion it is something of the most important things. And if you can write your docs in code, its easier to do it.

If you're willing to drop into Python, you can generate any documentation format you prefer. It's pretty easy to iterate over the summary tooling (see my response in https://github.com/klauer/blark/discussions/80 and >also the submitter's project - it may be of interest), for example:

Thanks for the example. I will try to work with Python and Blark. Would you be willing to help me if I have any questions about blark? I worked a bit with Python at school but haven't used it since.

klauer commented 11 months ago

Thanks for fixing it. It works now.

No problem! 👍

Yes no problem. I can provide you in the future with new testmaterial if you could use it.

Definitely - if you can find things that blark fails at or doesn't do what you'd expect, I'd love to know about it.

My goal is to provide an easy documentation for all my code. As you mentioned in #80 code documentation isnt the favourite work of plc developers, but in my opinion it is something of the most important things. And if you can write your docs in code, its easier to do it.

I strongly agree with your opinion about documentation.

Also, the more general interest there is in blark as a tool gives me an excuse to finish up that documentation-generation tooling. Maybe one day soon...

Thanks for the example. I will try to work with Python and Blark. Would you be willing to help me if I have any questions about blark? I worked a bit with Python at school but haven't used it since.

I'll help where I can! This is a fun side project for me, so having people actually poke around with the library is nice. If you find issues, open up another issue like you did, and if you have general questions, perhaps Discussions would be a better spot for those. I'm not too picky, though.