%{
/* $Id: gisel.y 2.7 1997/03/27 08:30:16 leon Exp leon $
 *
 *      GISEL - G-CODE ISEL CNC driver
 *
 *      Copyright (c) 1994 LECAD
 *      All Rights Reserved.
        | NL { $$ = NULL; }
%nonassoc NL0
%nonassoc NL

 *
 */

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <math.h>



#include "parse.h"



#define INODE(node, nodeType, val) node = (Node *)malloc(sizeof(Node)); \

            node->type = nodeType; node->arg.ival = val; node->next = NULL

#define DNODE(node, nodeType, val) node = (Node *)malloc(sizeof(Node)); \

            node->type = nodeType; node->arg.dval = val; node->next = NULL 

#define ADD_NODE(head, node) if (head) { Node *n = head; while(n->next) \

        {n = n->next;} n->next = node;} else head = node


extern int yylex(void);
extern char *yytext;

#pragma warn -pia


%}

%union {
	int ival;
        long int lval;
	double dval;
        Node *node;
}

%token LINENUMBER
%token NL NAME NUMBER
%token GCODE MCODE ORIENTATION
%token X Y Z I J K U V W Q F S R A B C L
%token T P

%type <dval> number 
%type <ival> gcode mcode
%type <lval> linenumber
%type <node> command arguments geometry technology
%type <node> coordinate parameter

%type <dval> coordX coordY coordZ coordI coordJ coordK 
%type <dval> coordR coordA coordB
%type <dval> parF parS
%type <ival> parT parL


%%


input :  /* empty */
	| input NL
	| input linenumber command NL
                {
                  if ($3)
                    {
                        Node *p;

                        ExecCommandCb($3); /* Callback function */

                        p = $3; 
                        while(p)        /* free command list */
                        {
                        Node *n;
                        n = p->next;
                        free(p);
                        p = n;
                        }
                        $3 = NULL;
                    }
                }
        | error {yyclearin; yyerrok; } 
	;




command:
          gcode arguments
                {
                  INODE($$, Node_GCODE, $1);
                  $$->next = $2;
                }
	| arguments
                {
                  INODE($$, Node_GCODE, 1); /* slow linear move only */
                  $$->next = $1;
                }
/*		
        | mcode
                {
                  INODE($$, Node_MCODE, $1);
                }
*/
        | mcode number 
                {
                  INODE($$, Node_MCODE, $1); 
                  DNODE($$->next, Node_Number, $2); 
                }
        | gcode NAME 
                {
                  INODE($$, Node_GCODE, $1); /* TODO */
                }
	;


linenumber: 
         /* empty */  {} /* TODO */
        | LINENUMBER  {}
        ;

arguments: 
	/* empty */     { $$ = NULL;} 
        | geometry      { $$ = $1; } 
        | technology    { $$ = $1; }
        | geometry technology { $$ = $1; ADD_NODE($1, $2); }
        | NUMBER        { $$ = NULL; } /** TODO **/
        | ORIENTATION   { $$ = NULL; }
        ;

geometry:
          coordinate { $$ = $1; }
        | geometry coordinate { $$ = $1; ADD_NODE($1, $2); }
        ;
      
coordinate:
          coordX { DNODE($$, Node_X, $1); } 
        | coordY { DNODE($$, Node_Y, $1); }
        | coordZ { DNODE($$, Node_Z, $1); }
        | coordI { DNODE($$, Node_I, $1); }
        | coordJ { DNODE($$, Node_J, $1); }
        | coordK { DNODE($$, Node_K, $1); }
        | coordR { DNODE($$, Node_R, $1); }
        | coordA { DNODE($$, Node_A, $1); }
        | coordB { DNODE($$, Node_B, $1); }
        ;

technology:
        parameter { $$ = $1; }
        | technology parameter { $$ = $1; $1->next = $2; }
        ;

parameter:
          parF  { DNODE($$, Node_F, $1); } 
        | parS  { DNODE($$, Node_S, $1); }
        | parT  { INODE($$, Node_T, $1); }
        | parL  { INODE($$, Node_L, $1); }
	| mcode { INODE($$, Node_MCODE, $1);}
        ;

coordX: X { $$ = atof(yytext + 1); };
coordY: Y { $$ = atof(yytext + 1); };
coordZ: Z { $$ = atof(yytext + 1); };
coordI: I { $$ = atof(yytext + 1); };
coordJ: J { $$ = atof(yytext + 1); };
coordK: K { $$ = atof(yytext + 1); };
coordR: R { $$ = atof(yytext + 1); };
coordA: A { $$ = atof(yytext + 1); };
coordB: B { $$ = atof(yytext + 1); };

parF: F   { $$ = atof(yytext + 1); };
parS: S   { $$ = atof(yytext + 1); };
parT: T   { $$ = atoi(yytext + 1); };
parL: L   { $$ = atoi(yytext + 1); };

number: NUMBER  { $$ = atof(yytext); };
gcode:  GCODE   { $$ = atoi(yytext + 1);};
mcode:  MCODE   { $$ = atoi(yytext + 1);};

%%

#if 0


int yyerror(char *str)
{
  extern long int lineno;
  extern char linebuf[200];
  extern FILE *yyout;

  fprintf(yyout, "Error: '%s' on line %ld\n%s\n", 
        str, lineno, linebuf);
  return 0;
}

#endif



syntax highlighted by Code2HTML, v. 0.9.1