GCode is language used to tell multi-axis (CNC) robots how to move. It looks like this :
M3 S5000 (Start Spindle Clockwise at 5000 RPM)
G21 (All units in mm)
G00 Z1.000000 (lift Z axis up by 1mm)
G00 X94.720505 Y-14.904622 (Go to this XY coordinate)
G01 Z0.000000 F100.0 (Penetrate at 100mm/m)
G01 X97.298434 Y-14.870127 F400 (cut to here)
G03 X98.003848 Y-14.275867 I-0.028107 J0.749174 (cut an arc)
G00 Z1.000000 (lift Z axis)
etc.
I have layed these commands out in sentences, but each token could be on a separate line. And in fact there are no rules about numbers being concatenated to their respective code letters. Yet I already have a LEX parser which can get me the tokens as described below.
Note that certain commands (M or G codes) have parameters. In the case of M3, it can have an S (spindle speed) parameter. G0 and G1 can have X,Y,Z,F etc. G3 can have X,Y,Z,I,J,R... However each G code does not require ALL those parameters, just one, many or all.
One thing to note here is that we are cutting a single path, then lifting the z axis. That is, we move to a location above the work surface, penetrate, cut a path then lift off. I would call this a 'block' or a 'path' and it is this that I'm interested in.
I need to be able to parse GCode in any messy format and then create a structure of 'blocks', where a block is any series of 'commands' between an z axis down and up.
I can tokenise this language using LEX (python PLY specifically). And get :
type M value 3
type S value 5000
type COMMENT value "Start Spindle Clockwise at 5000 RPM"
type G value 31
type COMMENT value "All unites in mm"
type G value 0
type Z value 1.0
etc.
Now using Lexx I need a rule for a thing called a 'command'.
A command is any comment, or : A 'G' or 'M' code followed by ANY of the appropriate parameter codes (X,Y,Z etc.) Command ends when another command (comment, G or M) is encountered.
Then I need a thing called a 'block', where a block is any set of 'commands' that come after a Z down and before a Z up.
There are 100 G codes and 100 M Codes and 25 parameter codes (A-Z minus G and M)
A rule for 'command' might look like :
command : G F H I J K L S T W X Y Z (how to specify ONE OF)
| M S F (How to specify one of)
| COMMENT
And then how would we define block!?
I realise this is a very long post, but if anyone can give me even an idea as to whether YACC can do this? Otherwise I'll just write some code that converts the lex tokens into a tree manually.
Addendum @rici
Thank you for taking the time to understand this question. By way of feedback: My task in full is to get YACC to do the heavy lifting of separating chunks of code into blocks based on different use cases.
For example When 'engraving', often a block will represent a letter or some other shape (in the xy plane). So a block will be defined by the movement of the z axis in and out of the xy plane.
I want to be able to post process blocks:
- hatch fill a 'block'. which will involve some fairly complicated calculation of path boundaries, tangents to those boundaries, tool diameter etc. This is the most pressing use case and I haven't a good solution to this yet but I know it can be done because it can be done in Inkscape (vector graphics application)
- rotate by n degrees. A fairly simply coordinate translation, I have a solution for this already.
- iteratively deepen (extrude). Copy blocks and adjust Z depth on each iteration. Simple.
- etc.