Request help defining classes for a User Defined Language.
-
Background
The language is for a text encoding of GE’s Proficy HMI Cimplicity screens. Cimplicity is a SCADA / HMI system.
I got the function list working to display all subroutines and functions, but now I would like to add classes.
One complexity, is that the file I am parsing is not entirely user written code. The file represents a graphical screen. The file is created by a graphical editor called CimEdit.exe, and is run by another program called CimView.exe. As a user of CimEdit, I can draw on the screen in a manner similar to Powerpoint. I can name the objects I draw on the screen and add CimBasic ( VBA like ) code to them. The code is saved under each object, so I want to treat the object as a class.
CimEdit allows for saving the screen to a text file. I have a document from GE defining the syntax of this file in BNF (Backus–Naur form ) syntax.
I have created both a UDL called CimScreen and added the language to the functionList.xml
Extracts of each below.Example of text file
<pre><code>
(GmmiTextButtonObject (GmmiObject "btnFootPrintBack" 0 (Help "" "" "") (GmmiOptionTable (GmmiScript "{&h0D}{&h0A}" & "Sub OnMouseUp(x As Long, y As Long, flags As Long){&h0D}{&h0A}" & "{&h0D}{&h0A}" & "{&h09}On Error GoTo err_OnMouseUp{&h0D}{&h0A}" & "{&h0D}{&h0A}"
</code></pre>
The line: (GmmiTextButtonObject defines the object type Gmmi(\w+)Object. For me this is only a nice to have.
The next line: (GmmiObject “btnFootPrintBack” 0 defines the user name for the object, in this case btnFootPrintBack. This is what I want to capture as the class name.There can be several (Gmmixxxxxxx type lines nested within the (GmmiObject – most of which I am not interested in at this time.
Every (Gmmixxxxxx line is closed with a matching close parenthesis ), with possible multiple opening and closing parenthesis nested inside.The script, or user written CimBasic code starts on the (GmmiScript line. The editor encodes special characters as Hex codes: {&h0D} is carriage return for example, etc…
All lines of the CimBasic code start with & in the file and are surrounded by quote characters. If a quote is actually in the CimBasic code, it is encoded as {&h22}. I don’t need to interpret or convert any of the hex codes, I am de-emphasizing them by making them appear light grey on white background.As I said, I have achieved getting all the Sub and Function statements captured in the function list.
GOAL
I would like the sub and funtion names in the funtion list to be grouped under the user defined object name from the line: (GmmiObject “btnFootPrintBack” 0
I think the delimeter are a challenge as well as what I want captured for the class name comes after the opening: (GmmiObject “className” of the class.
From my functionList.xml
<pre><code>
<association ext=".ctx" id="cimplicity_ctx" userDefinedLangName="CimScreen" /> <parser id="cimplicity_ctx" displayName="CimScreen"> <classRange mainExpr="^[\h\s \t]+.GmmiObject\s.*\d+.*[^\28]" openSymbole = "\(GmmiScript" closeSymbole = "\x22\)" displayMode="node"> <className> <nameExpr expr="[A-Za-z_0-9\-]+" /> </className> <function mainExpr="& .[\h]*(Function|Sub)\h+[A-Za-z_0-9]+(?=[\h\{].*$)"> <functionName> <nameExpr expr="(Function|Sub)\h+[A-Za-z_0-9]+" /> </functionName> </function> </classRange> <function mainExpr="& .[\h]*(Function|Sub)\h+[A-Za-z_0-9]+(?=[\h\{\(].*$)"> <functionName> <nameExpr expr="(Function|Sub)\h+[A-Za-z_0-9]+" /> </functionName> </function> </parser>
</code></pre>
portion of exported UDL
<pre><code>
... <Keywords name="Operators1">< = > " ( )</Keywords> <Keywords name="Operators2">and or not</Keywords> <Keywords name="Folders in code1, open">\(GmmiScript</Keywords> <Keywords name="Folders in code1, middle"></Keywords> <Keywords name="Folders in code1, close">\"\)</Keywords> ... <Keywords name="Delimiters">00&{h0 01 02}" 03 04 05 06{&h 07 08} 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23</Keywords>
</code></pre>
Any help greatly appreciated.
-
Could you please provide (a link to):
- a complete example text file;
- the complete UDL;
- the GE BNF syntax file.
-
Guess I found the BNF syntax in the CimEdit Operation Manual.
-
Thanks @MapJe71
CimEdit Operation Manual ( but you already beat me to it. )
https://digitalsupport.ge.com/communities/en_US/Documentation/CimEdit-Operation-Manual
( See Appendix A for BNF syntax )Sample Cimplicity screen:
https://drive.google.com/file/d/0Bz5RjazMRdOKYktXZzRVekxjTkk/view?usp=sharingMy exported UDL:
https://drive.google.com/open?id=0Bz5RjazMRdOKTURZNFV5bUhjbWM -
Could you try the following parser:
<association id="cimplicity_ctx" userDefinedLangName="CimScreen" /> <association id="cimplicity_ctx" ext=".ctx" /> <parser displayName="CimEdit Text File Format" id ="cimplicity_ctx" > <classRange mainExpr ="(?x) (?(DEFINE) (?'NAMED_CHAR'\b(?i: B(?:ackspace|ell) | C(?:arriageReturn|haracterTabulation) | Delete | Escape | FormFeed | L(?:eft(?:Brace|CurlyBracket)|ine(?:Feed|Tabulation)) | N(?:ewLine|ull) | QuotationMark | R(?:eturn|ight(?:Brace|CurlyBracket)) | Tab )\b) (?'STRING_CHAR' [^\r\n\x22\x7B] | \{ (?: \d+ | \x26 (?: [Hh][A-Fa-f0-9]+ | [Oo][0-7]+ ) | (?&NAMED_CHAR) ) \} ) (?'STRING' \x22 (?:(?&STRING_CHAR))* \x22 (?: \s+\x26 \s+(?&STRING) )* ) ) \(GmmiObject \s+(?&STRING) (?: [^(] | \((?!Gmmi(?:Object|Script)\b) )* \(GmmiScript\s+(?&STRING)\s*\) " > <className> <nameExpr expr="\(GmmiObject\s+\x22\K[^\r\n\x22]+" /> </className> <function mainExpr="(?x) \x22 (?:Function|Sub)\h+ \K \w+ [^\r\n\x22]* \x22 " > <functionName> <funcNameExpr expr="[^\x22{]+" /> </functionName> </function> </classRange> </parser>