Writing a ST compiler

It appears that no one uses the TYPE and END_TYPE to define user defined data types or do enumerations.

I am probably 1/3 done. I can't work on it all the time. Sometimes I must into the field and do training or get distract by business stuff.

It kind of cool how a compiler works. It is very recursive as there rules that invoke other rules or rules that invoke themselves. I can see how or why languages were developed early on.

I have the the ST specification. It cost about $250-$300 I think. I have found errors and it isn't complete. Still the person that wrote the specification seemed to know what he was doing as far a defining a compiler.
 
It appears that no one uses the TYPE and END_TYPE to define user defined data types or do enumerations.
Example of TYPE and END_TYPE in Siemens SCL:
Code:
TYPE "UDT_myDATA"
// sample UDT
    STRUCT
    test_REAL : REAL ;
    test_INT : INT ;
    END_STRUCT
END_TYPE
 
DATA_BLOCK "myDATA"
// sample DB
    STRUCT
    set : ARRAY[1..10] OF "UDT_myDATA" ;
    END_STRUCT
BEGIN
END_DATA_BLOCK
 
FUNCTION "FC_test" : VOID
// access previously defined data
IF "myDATA".set[1].test_real > "myDATA".set[2].test_real THEN
    "myDATA".set[1].test_INT := 2 ;
ELSE
    "myDATA".set[1].test_INT := 3 ;
END_IF ; 
END_FUNCTION
I have not seen enumerations in Siemens SCL.
 
I know how to declare TYPE... END_TYPE

My question is where?
According the the specification it is not done within a program, FB, or FN.
If the compiler parser is scanning a program and it comes across the token TYPE it will flag an error. I can change this but I would rather stick to what has been done before or some standard instead of making up yet another way or place to declare TYPE.. END_TYPE.

So far I am left with no choice but to declare user types outside of PROGRAMs, FNs and FBs.
 
My question is where?
According the the specification it is not done within a program, FB, or FN.
If the compiler parser is scanning a program and it comes across the token TYPE it will flag an error. I can change this but I would rather stick to what has been done before or some standard instead of making up yet another way or place to declare TYPE.. END_TYPE.

So far I am left with no choice but to declare user types outside of PROGRAMs, FNs and FBs.

All UDT declarations I have seen are outside of programs, functions and function blocks.

In siemens step 7 v5 you can declare them on same scl source file (that does show TYPE, END_TYPE), but they are compiled as separate blocks (in blocks folder, that does not show TYPE, END_TYPE, one could also make UDT straight to blocks folder). In TIA V11 there is separate folder in tree structure called "PLC data types" that does not show TYPE, END_TYPE.

In GX IEC developer there is separate folder in project tree structure called DUT pool where UDT's are declared, that does not show TYPE, END_TYPE.

In RsLogix5000 there is separate folder in project tree structure called Data Types, where there is folder called User-Defined where UDT's are declared, that does not show TYPE, END_TYPE.

Twincat (also CoDeSys) as seen from LD's post has separate place for UDT's.

When TYPE, END_TYPE are not shown, there is usually "aided" configurator. See example from TIA portal.

So you need to decide what is best way to do it in your sw. In any case, central location for UDT's could be best and easiest for you (that being also as far as i know the usual way to do it).

ps. I try to remember to look at how it is done in twincat3 tomorrow.

UDT.jpg
 
Last edited:
Peter, I think you have a tendency to ask questions and then either ignore the answers or only skim them superficially.
I answered your question in post #25 (in text) and in post #33 (with sample code).

TurpoUrpo said:
In TIA V11 there is separate folder in tree structure called "PLC data types" that does not show TYPE, END_TYPE
Thats because in STEP7 v11 all declarations are no longer written in text, but in an integrated declaration-editor. That includes the main declarations in SCL what kind of block you are editing.
If you export the SCL code form the native editor to the "SCL source" files, then you get the same format as in STEP7 v5 incl FUNCTION, END_FUNCTION, TYPE and END_TYPE etc.
 
You really can't compare Siemens SCL to ST as described in IEC standard.
I would say SCL is a subset of IEC-ST (e.g lack of enumerations regarding to this thread). Codesys-ST implements most of the IEC stuff and adds some really useful things like pointers.

Datatypes defined in TYPE are always global types. There is no way for declaration of local types, but I think sometimes it would be useful to have this.

Peter, I would like to know if you are using a handcrafted scanner/parser, or do you use some kind of generator for this?

I'm currently (in my freetime) working on a program to generate HTML documentation from ST sources (like doxygen for C). I'm using Coco/R for compiler generation.
 
Thats because in STEP7 v11 all declarations are no longer written in text, but in an integrated declaration-editor. That includes the main declarations in SCL what kind of block you are editing.
If you export the SCL code form the native editor to the "SCL source" files, then you get the same format as in STEP7 v5 incl FUNCTION, END_FUNCTION, TYPE and END_TYPE etc.

Yes, but that is not main way to do it in TIA.

Here is screen from twincat3 implementation. I just copied type & union to same file as enum to get them nicely on same screen. Those have own files as seen from tree structure.

DUT.jpg
 
Last edited:
Jesper, I saw your example but SCL is not ST. ST doesn't have DB. Also, it wasn't clear if the TYPE and END_TYPE were declared inside or outside the program block. If there was a PROGRAM ... END_PROGRAM block in your example it would have been clear. I did notice that the TYPE...END_TYPE was declared first but it wasn't make clear if this is just a cut and paste of part of a program. I needed to know if the TYPE..END_TYPE was declared outside of all other blocks like it appears to be in the specification. This is would be much different from Java or Pascal.

I was hoping that one of the codesys users would tell me where they declare their TYPE..END_TYPE.

So far it looks like the TYPE... END_TYPE must be declared before use and before a PROGRAM..END_PROGRAM.

Thomas_v2, I am using Flex and Bison. Flex is the token scanner and Bison is the parser with all the rules. Tokens are all the reserved words and symbols of ST. What I am doing is pretty straight forward so far. I had to translate the ST specification in EBNF to Bison rules but I did it step by step preserving names so one can look at my code and see exactly what EBNF rule was used to generate the Bison rule.

The reason I asked my original question about TYPE and END_TYPE is because now my Flex scanner expects PROGRAM to be the first thing it sees. FN and FBs are declared within the program block. It appears I must modify the scanner so it can see either PROGRAM or TYPE as the first thing it sees. I can modify this. I may as well allow FNs and FBs to be defined outside of program blocks too.

I am NOT going to add pointers, at least not as a variable type. There are way too many threads/questions about pointers on this forum. Java doesn't have pointers. Pointers aren't necessary. I would rather implement simple class objects. In a way a FB is like an object that but there is no way to define methods. One thing that really irked me about Siemens is the inability to have an array of FBs. An array of FBs may be an extension but I think it would be a good one.

I have ruled out using IL as an intermediate code to compile down to. IL is not as complete as Siemens STL. I could 'extend' IL but then there would be little need for the IL. For instance IL has no way of doing indirect addressing. I could give IL the ability to use ST expressions but then it is simply easier to use ST.

The IEC spec does mention a library but doesn't say how to implement it. The obvious way would be to make a library block like a program block. That is much more work than I want to do right now but it would be good. Most of our customers have very simple user programs that are 10 steps or less and the whole project is really very small.
 
Siemens SCL is a subset of ST. True. But as far as the question about where TYPE END_TYPE is declared, it follows IEC ST. No enumerations though.

Siemens SCL do not have PROGRAM, END_PROGRAM.

The code I posted was directly from Siemens SCL editor.
In the Siemens SCL editor you can freely write code for several blocks in one SCL source file. That is a way to make sure the compile order gets right. You can also split into several source files, but then you have to manually specify the compile order.
It shows how the UDT is defined first, and then some blocks that use the UDT. edit: If you move the UDT code to the bottom, the compiler will complain when trying to generate the code.
 
Last edited:
JesperMP said:
Thats because in STEP7 v11 all declarations are no longer written in text, but in an integrated declaration-editor. That includes the main declarations in SCL what kind of block you are editing. If you export the SCL code form the native editor to the "SCL source" files, then you get the same format as in STEP7 v5 incl FUNCTION, END_FUNCTION, TYPE and END_TYPE etc.
TurpoUrpo said:
Yes, but that is not main way to do it in TIA.
Siemens and Rockwell has moved away from a pure text-document based SCL/ST programming environment, to a more "integrated" programming environment. And when doing so, the declaration part is no longer text-based, but similar to declaring tags.
edit: There is something about the pure text based coding that appeals to me when writing code. It feels uninhibited somehow. I can quickly put down some code, and then tidy it up later. The integrated editors force me to write "properly" the first time.

Apart from the differences between Siemens SCL and IEC ST, I think that Peter is going to have a compiler that works like the STEP7 v5 SCL compiler works.
When you write code, you just write text, and there is no type-checking, variable checking, auto complete, auto suggest or any such goodies.
You invoke the compiler at some time, and the compiler loads the text code and interprets it one line at a time, and only then it does the necessary check of the code, of the types, of the variables etc. If everything goes OK, the compiled code is created.
 
There is something about the pure text based coding that appeals to me when writing code. It feels uninhibited somehow. I can quickly put down some code, and then tidy it up later. The integrated editors force me to write "properly" the first time.
Currently we compile on-the-fly. That works pretty well for what we do right now. Currently we don't accept code with errors unless you override.
The Flex and Bison combination does a much better job of locating the errors.

Apart from the differences between Siemens SCL and IEC ST, I think that Peter is going to have a compiler that works like the STEP7 v5 SCL compiler works.
I would like to integrate the compiler into Scintilla.

When you write code, you just write text, and there is no type-checking, variable checking, auto complete, auto suggest or any such goodies.
You invoke the compiler at some time, and the compiler loads the text code and interprets it one line at a time, and only then it does the necessary check of the code, of the types, of the variables etc. If everything goes OK, the compiled code is created.
Right now I want the most standard, and maintainable compiler. I want something where one can look at section B.1.3 in the spec and find section B.1.3 in my code and see the same variables and terms. I am not worried about optimizing now but keep my opinion about inefficient code.

I have come to find there are four more parts to the compiler.
1 Flex the scanner that finds tokens ( reserved words, variables and literals ).
2 Bison the parser than builds the parse tree. It has rules made of rules made of yet more rules until one gets down to the tokens.
3. Actions, these are what is done when a rule is activated and controls what is put in the parse tree.
4. Code generation. This part is the machine dependent back end. This is where the register optimization. The code generator recursively walks the parse tree and uses a switch table to generate code for all the different things that the code generator may need to do like adding two variables, loading and storing variables.
 
I am NOT going to add pointers, at least not as a variable type. There are way too many threads/questions about pointers on this forum. Java doesn't have pointers. Pointers aren't necessary. I would rather implement simple class objects.

But how should anyone write a general function which is sorting an array of values (e.g. real) of an undefined size with the standard ST language?
The addition of pointers to the ST language in codesys is an adjustement to the real programming world.

That was already a point of criticism at the Pascal language by Brian W. Kernighan (co author of the c standard book) over 30 years ago:
http://www.lysator.liu.se/c/bwk-on-pascal.html
 
Arrays aren't passed by value, they are passed by reference. Internally a reference is a pointer but at least it points to the array. What I don't want to do is provide pointers that people can manipulate so they point to places they shouldn't be pointed to. This can cause crashes and that is bad when doing motion control. It is easy to bounds check an index off a reference 'pointer'.
The length can be passed as a separate parameter.
I just need to allow arrays of unspecified length on my functions.
Right now we have an AddressOf function that returns a pointer. It is safe because the AddressOf(variable) will point to a valid variable not some invalid memory.

I agree with the criticism about Pascal. I learned Pascal before I learned C. I found Pascal too restrictive whereas C could do almost anything.
 
Update, I can generate code for arrays and structures but I am not done with the structures yet. I can't handle structures within structures within structures yet.

It is interesting how ST makes one define structures in the TYPE and TYPE_END blocks. Then one can declare a structure of that type in the VAR type of blocks.

I have already hit some optimizing issues. I am not too worried about optimizing yet.

My compiler is about 2/3 printf statements that I use for debugging. The people that wrote the specification for how ST is to be compiled did a pretty good job. I can see where whoever wrote this knew what he was doing but I really wish he would have written a paragraph or two about what he expected the compiler writers, like me, to do. For instance, one can't use Bison in its simplest mode to parse the code. There are places where Bison used in its simple form can't decide what data type you are talking about and quits. I found a more advanced mode will look at serval options before quitting.

The threads above indicate that people have complaints about ST. At this point I am strictly adhering to the specification. I am doing this because I want others to be able to look at what I have done and see that I used exactly the same terms and rules as the specification.

I have always want to write a compiler. I bought books on how to write compilers about 20 years ago. Finally I am writing a compiler. The books I bought are largely obsolete now. Things change but I am still enjoying writing a compiler.
 

Similar Topics

Hi, I'm having an issue in crimson 3.0 when I create a programme using a case statement referencing a fault word that each bit needs to change the...
Replies
5
Views
241
Hello all, I'm currently working on a servo motor linear positioning system (ball screw). I'm all set up regarding communication between my HMI...
Replies
1
Views
92
Hello All: I have a Windows 10 PC running a FTView ME Station 10.00. I have a .mer file version 6.00. It has been running well on it for a long...
Replies
1
Views
171
My R55 Ingersollrand is tripping on motor overload and im falling to see the trip history it is writing Acquarring texts
Replies
0
Views
134
Hi. Not the fist time I'm saying this but just to give a background. 95% of my PLC programming has used Schneider over the last 10 years on...
Replies
66
Views
4,978
Back
Top Bottom