Valhalla Legends Forums Archive | C/C++ Programming | Yacc/Bison Question -- Parsing Trick?

AuthorMessageTime
Rule
I've changed the yacc grammar so that assignments of the form
[code]
name := value
name2 := value2
otherName := $[name]*$[name2]+9*4/2-3+18 
[/code]
etc, can be made.

I have two questions:

1) As I have written my grammar presently, is there an easy way to add this sort of feature:     
[code]
otherName := 9*4/2-3+18 + $[name]     
[/code]
....etc
2) I really want to add this feature.
[code]
name := value
otherName := "some string text $[name]"
[/code]

Any suggestions?  Should major changes be made to my grammar?

As always, thanks in advance!

Also, any stylistic suggestions are appreciated.  For example, is it really bad that I've reduced $[name] assignments into a number? :P
There are currently 5 shift/reduce conflicts, although I believe they are in the "expr" rule (not positive), and can be fixed by adding associative rules and precedence

Below I've pasted my grammar, with the additions I've made put in bold.  The routine sget_param can be ignored.  I've also pasted my lex file.
[quote]
[font=Courier New]
[size=2]
/* gpar.y */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gpar.h"

assignment myasgn;


ivel_list * new_ivel_list();
fvel_list * new_fvel_list();
value_list * new_value_list();
int gotit;

%}

%union {
  int inum;
  double num;
  char *str;
  value val;
  ivel_list *ivl;
  fvel_list *fvl;
  value_list *vl;
  assignment asgn;
}

%token <str> STR IDEN FNAME
%token <num> NUM
%token <inum> INUM ASSIGNOP EQUALS PLUS MINUS TIMES DIVIDE COMMA OBRACK CBRACK EXTRACT
%token LONG DOUBLE STRING IVEC FVEC VECTOR SCALAR

%type <asgn> assignment
%type <val> number inumber string ivec fvec file
%type <inum> ival becomes option
%type <vl> inumber_list number_list string_list
%type <num> fval expr


%%

assignment:  LONG {
              gotit=0;
            } /* nothing */
  |  DOUBLE {
      gotit=0;
    } /* nothing */ 
  |  STRING {
      gotit=0;
    } /* nothing */ 
  |  IVEC {
      gotit=0;
    } /* nothing */ 
  |  FVEC {
      gotit=0;
    } /* nothing */ 
  |  LONG IDEN becomes inumber {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
  addAssign(myasgn);     /* All addAssign statements were added by me -- rule */
      gotit=1;

    }
  |  DOUBLE IDEN becomes number {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;

    }
  |  STRING IDEN becomes string {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  IVEC IDEN becomes ivec {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  FVEC IDEN becomes fvec {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  LONG IDEN becomes file {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  DOUBLE IDEN becomes file {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  STRING IDEN becomes file {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  IVEC IDEN becomes file {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  FVEC IDEN becomes file {
      myasgn.name=$2;
      myasgn.val=$4;
      myasgn.type=SCALAR;
      addAssign(myasgn);
      gotit=1;
    }
  |  LONG IDEN becomes OBRACK inumber_list CBRACK {
      myasgn.name=$2;
      myasgn.vl=$5;
      myasgn.type=VECTOR;
      addAssign(myasgn);
      gotit=1;
    }
  |  DOUBLE IDEN becomes OBRACK number_list CBRACK {
      myasgn.name=$2;
      myasgn.vl=$5;
      myasgn.type=VECTOR;
      addAssign(myasgn);
      gotit=1;
    }
  |  STRING IDEN becomes OBRACK string_list CBRACK {
      myasgn.name=$2;
      myasgn.vl=$5;
      myasgn.type=VECTOR;
      addAssign(myasgn);
      gotit=1;
    } 

  |  datatype EXTRACT IDEN becomes EXTRACT OBRACK IDEN CBRACK option expr{
      extern int change;
      myasgn = assignLook($7)->assign;

      if (!change)
        fprintf(stderr, "gpar: warning:  can't extrapolate parameter <%s>; it hasn't been manually initialized.\n", $7);
     
     
      /* Some print statements for debugging */
      fprintf(stdout, "expression value: %f\n", $10);
     
      fprintf(stdout, "INUM: %d\t NUM: %d\t\t Type: %d\n", INUM, NUM, myasgn.val.type);
      fprintf(stdout, "Assigned Value: %f\n", myasgn.val.data.num); 

      switch(myasgn.val.type)
      {
        case INUM  :
          switch($9)
  {
    case PLUS  : myasgn.val.data.inum += $10;
                  break;
    case MINUS : myasgn.val.data.inum -= $10;
                  break;
    case TIMES : myasgn.val.data.inum *= $10;
                  break;
    case DIVIDE: if($10!=0.)
                    myasgn.val.data.inum /= $10;
  break;
  }
 
  break;
       
        case NUM  :
        switch($9)
  {
    case PLUS  : myasgn.val.data.num += $10;
                  break;
    case MINUS : myasgn.val.data.num -= $10;
                  break;
    case TIMES : myasgn.val.data.num *= $10;
                  break;
    case DIVIDE: if($10!=0.)
                    myasgn.val.data.num /= $10;
  break;
  }
         
  break;
       
      }
   
      myasgn.name=$3;
      addAssign(myasgn);
      gotit=1;
    }
  ;

becomes: ASSIGNOP | EQUALS
  ;
 
inumber:  INUM {
          $$.type=INUM;
          $$.data.inum=$1;
        }
  |  MINUS INUM {
      $$.type=INUM;
      $$.data.inum=-$2;
    }
  ;

number:  NUM  {
          $$.type=NUM;
          $$.data.num=$1;
        }
  |  MINUS NUM {
      $$.type=NUM;
      $$.data.num=-$2;
    }
  |  INUM {
      $$.type=NUM;
      $$.data.num=(double)$1;
    }
  |  MINUS INUM {
      $$.type=NUM;
      $$.data.num=(double)(-$2);
    }

  |  EXTRACT OBRACK IDEN CBRACK  {
      assignment moreNames = assignLook($3)->assign;
      switch(moreNames.val.type)
      {
        case INUM  : $$.data.num = (double) moreNames.val.data.inum;
              break;
        case NUM    : $$.data.num = moreNames.val.data.num;
              break;
default    : $$.data.num = 1.0; 
              break;
      }
   
    $$.type=NUM;
   
    }
  ;

string:  STR {
          $$.type=STR;
          $$.data.str=$1;
        }
  ;
 
ivec:  ival {
        $$.type=IVEC;
        $$.data.ivec=new_ivel_list();
        $$.data.ivec->ivel[0]=$1;
        $$.data.ivec->ivel[1]=-2;
        $$.data.ivec->ivel[2]=1;
        $$.data.ivec->len=1;
      }
  |  ival MINUS ival {
      $$.type=IVEC;
      $$.data.ivec=new_ivel_list();
      $$.data.ivec->ivel[0]=$1;
      $$.data.ivec->ivel[1]=$3;
      $$.data.ivec->ivel[2]=1;
      $$.data.ivec->len=1;
    }
  |  ival MINUS ival DIVIDE INUM {
      $$.type=IVEC;
      $$.data.ivec=new_ivel_list();
      $$.data.ivec->ivel[0]=$1;
      $$.data.ivec->ivel[1]=$3;
      $$.data.ivec->ivel[2]=$5;
      $$.data.ivec->len=1;
    }
  |  ivec COMMA ival {
      $$.type=IVEC;
      $$.data.ivec=new_ivel_list();
      $$.data.ivec->ivel[0]=$3;
      $$.data.ivec->ivel[1]=-2;
      $$.data.ivec->ivel[2]=1;
      $$.data.ivec->next=$1.data.ivec;
      $$.data.ivec->len=1+$1.data.ivec->len;
    }
  |  ivec COMMA ival MINUS ival {
      $$.type=IVEC;
      $$.data.ivec=new_ivel_list();
      $$.data.ivec->ivel[0]=$3;
      $$.data.ivec->ivel[1]=$5;
      $$.data.ivec->ivel[2]=1;
      $$.data.ivec->next=$1.data.ivec;
      $$.data.ivec->len=1+$1.data.ivec->len;
    }
  |  ivec COMMA ival MINUS ival DIVIDE INUM {
      $$.type=IVEC;
      $$.data.ivec=new_ivel_list();
      $$.data.ivec->ivel[0]=$3;
      $$.data.ivec->ivel[1]=$5;
      $$.data.ivec->ivel[2]=$7;
      $$.data.ivec->next=$1.data.ivec;
      $$.data.ivec->len=1+$1.data.ivec->len;
    }
  ;

fvec:  fval {
        $$.type=FVEC;
        $$.data.fvec=new_fvel_list();
        $$.data.fvec->fvel[0]=$1;
        $$.data.fvec->fvel[1]=$1;
        $$.data.fvec->fvel[2]=1;
        $$.data.fvec->len=1;
      }
  |  fval MINUS fval DIVIDE INUM {
      $$.type=FVEC;
      $$.data.fvec=new_fvel_list();
      $$.data.fvec->fvel[0]=$1;
      $$.data.fvec->fvel[1]=$3;
      $$.data.fvec->fvel[2]=$5;
      $$.data.fvec->len=1;
    }
  | fvec COMMA fval {
      $$.type=FVEC;
      $$.data.fvec=new_fvel_list();
      $$.data.fvec->fvel[0]=$3;
      $$.data.fvec->fvel[1]=$3;
      $$.data.fvec->fvel[2]=1;
      $$.data.fvec->next=$1.data.fvec;
      $$.data.fvec->len=1+$1.data.fvec->len;
    }
  |  fvec COMMA fval MINUS fval DIVIDE INUM {
      $$.type=FVEC;
      $$.data.fvec=new_fvel_list();
      $$.data.fvec->fvel[0]=$3;
      $$.data.fvec->fvel[1]=$5;
      $$.data.fvec->fvel[2]=$7;
      $$.data.fvec->next=$1.data.fvec;
      $$.data.fvec->len=1+$1.data.fvec->len;
    }
  ;

file: FNAME {
        $$.type=FNAME;
        $$.data.str=$1;
      }
  ;

inumber_list:  inumber {
                $$=new_value_list();
                $$->val=$1;
                $$->len=1;
              }
  | inumber_list inumber {
      $$=new_value_list();
      $$->val=$2;
      $$->next=$1;
      $$->len=1+$1->len;
    }
  ;

number_list:  number {
                $$=new_value_list();
                $$->val=$1;
                $$->len=1;
              }
  | number_list number {
      $$=new_value_list();
      $$->val=$2;
      $$->next=$1;
      $$->len=1+$1->len;
    }
  ;

string_list:  string {
                $$=new_value_list();
                $$->val=$1;
                $$->len=1;
              }
  | string_list string {
      $$=new_value_list();
      $$->val=$2;
      $$->next=$1;
      $$->len=1+$1->len;
    }
  ;

ival: INUM {
        $$=$1;
      }
  |  TIMES {
      $$=-1;
    }
  ;
 
fval:  NUM  {
          $$=$1;
        }
  |  MINUS NUM {
      $$=-$2;
    }
  |  INUM {
      $$=(double)$1;
    }
  |  MINUS INUM {
      $$=(double)(-$2);
    }
  ;


expr: 
  |    expr PLUS number    { $$ = $1+$3.data.num; }
  |    expr MINUS number  { $$ = $1-$3.data.num; }
  |    expr TIMES number  { $$ = $1*$3.data.num; }
  |    expr DIVIDE number  {
                            if ($3.data.num == 0.)
    {
      fprintf(stderr, "gpar: error: cannot divide by zero\n");
      exit(0);
    }
   
    else
      $$ = $1/($3.data.num);
  }
  |    number   { $$ = $1.data.num; }
  ;



datatype: LONG | DOUBLE | STRING | IVEC | FVEC | VECTOR | SCALAR
  ;


 
option: 
  |      PLUS  {
            $$=PLUS;
  }
  |      MINUS {
            $$=MINUS;
  }
  |      TIMES {
            $$=TIMES;
  }
  |      DIVIDE {
            $$=DIVIDE;
  }
  ;   
 
 
%%

ivel_list * new_ivel_list()
{
  ivel_list *iv;
 
  iv=(ivel_list *)malloc(sizeof(ivel_list));
  if(iv==NULL){
    fprintf(stderr,"new_ivel_list: can't get memory.\n");
    exit(0);
  }
  iv->next=NULL;
  iv->len=0;
  return iv;
}

fvel_list * new_fvel_list()
{
  fvel_list *iv;
 
  iv=(fvel_list *)malloc(sizeof(fvel_list));
  if(iv==NULL){
    fprintf(stderr,"new_fvel_list: can't get memory.\n");
    exit(0);
  }
  iv->next=NULL;
  iv->len=0;
  return iv;
}

value_list * new_value_list()
{
  value_list *vl;
 
  vl=(value_list *)malloc(sizeof(value_list));
  if(vl==NULL){
    fprintf(stderr,"new_value_list: can't get memory.\n");
    exit(0);
  }
  vl->next=NULL;
  vl->len=0;
  return vl;
}

int addAssign(assignment toAdd)
{
  assignment_list *alistp;
  assignment_list *add = assignLook(toAdd.name);

  /* Overwrites an assignment in the list if it has the same name as toAdd */
  if (change)
  {
  add->assign = toAdd;
  return 1;
  }

  alistp = (assignment_list *) malloc(sizeof(assignment_list));
  if (alistp == NULL)
  {
    fprintf(stderr, "addAssign: no more memory available\n");
    exit(0);
  }

  alistp->next = asgnList;
  alistp->assign = toAdd;
  asgnList = alistp;

  return 2;
}


assignment_list *assignLook(char *toFind)
{
  extern int change;
  change = 0;
  assignment_list *asearchp = asgnList;
 
  for(; asearchp; asearchp = asearchp->next)
  {
    if(!strcmp(asearchp->assign.name, toFind))
    {
      change = 1;
      return asearchp;
    }
  }
}

#define IVEL 4
#define FVEL 4

char *sg_param_buf;
char *sg_param_ptr;
char *sg_param_end;
int sg_param_type,first_tok;
int inputerror;

int sget_param(const char *string, const char *name,
              char *type, int size, void *p, int cs)
{
  int *q;
  double *r;
  value_list *vl;
  ivel_list *il;
  fvel_list *fl;
  int found=0,i;
  int typeerr=0;
  int ltrace=0;
 
  if(ltrace)
    fprintf(stderr,"string=<%s> name=<%s> type=<%s> size=%d\n",
            string,name,type,size);
           
  sg_param_buf=(char *)string;
  sg_param_ptr=sg_param_buf;
  sg_param_end=sg_param_buf+strlen(string);
 
  if(!strcmp(type,"long"))
    sg_param_type=LONG;
  else if(!strcmp(type,"double"))
    sg_param_type=DOUBLE;
  else if(!strcmp(type,"string"))
    sg_param_type=STRING;
  else if(!strcmp(type,"ivec"))
    sg_param_type=IVEC;
  else if(!strcmp(type,"fvec"))
    sg_param_type=FVEC;
  else {
    fprintf(stderr,"sget_param: error: unknown type <%s>\n",type);
    return(0);
  }
 
  first_tok=1;
  inputerror=0;
  gotit=0;
  gparparse();
 
  if(ltrace)
    fprintf(stderr,"sget_param: gotit=%d inputerror=%d\n",gotit,inputerror);
 
  if(!inputerror && gotit){
    if(ltrace)
      fprintf(stderr,"sget_param: myasgn.name=<%s> name=<%s>\n",myasgn.name,name);
    if((cs && !strcmp(myasgn.name,name)) || (!cs && !strcmp_nc(myasgn.name,name))){
      if(ltrace)
        fprintf(stderr,"sget_param: found <%s>\n",name);
      found=1;
      switch(myasgn.type){
        case SCALAR :
          if(myasgn.val.type!=FNAME && size!=1 && (sg_param_type==LONG ||
              sg_param_type==DOUBLE || sg_param_type==STRING)){
            fprintf(stderr,"sget_param: expecting a vector value for <%s>\n",name);
            return(0);
          }
          if(ltrace)
            fprintf(stderr,"sget_param: size=%d\n",size);
          switch(sg_param_type){
            case LONG :
              if(myasgn.val.type==INUM)
                *((int *)p)=myasgn.val.data.inum;
              else if(myasgn.val.type==FNAME)
                return(read_ascii_int(myasgn.val.data.str,(int *)p,size));
              else typeerr=1;
              break;
            case DOUBLE :
              if(myasgn.val.type==INUM)
                *((double *)p)=(double)myasgn.val.data.inum;
              else if(myasgn.val.type==NUM)
                *((double *)p)=myasgn.val.data.num;
              else if(myasgn.val.type==FNAME){
                if(ltrace)
                  fprintf(stderr,"sget_param: FNAME=<%s>\n",myasgn.val.data.str);
                return(read_ascii_double(myasgn.val.data.str,(double *)p,size));
              }else typeerr=1;
              break;
            case STRING :
              if(myasgn.val.type==STR){
                if(*((char **)p))
                  free(*((char **)p));
                *((char **)p)=cvec_alloc(strlen(myasgn.val.data.str)+1);
                strcpy(*((char **)p),myasgn.val.data.str);
                free(myasgn.val.data.str);
              }else if(myasgn.val.type==FNAME){
                return(read_ascii_string(myasgn.val.data.str,(char **)p,size));
              }else typeerr=1;
              break;
            case IVEC :
              if(ltrace)
                fprintf(stderr,"sget_param: looking for IVEC\n");
              if(myasgn.val.type==IVEC){
                if(ltrace)
                  fprintf(stderr,"sget_param: found IVEC\n");
                if(cs){
                  if(ltrace)
                    fprintf(stderr,"sget_param: len=%d\n",myasgn.val.data.ivec->len);
                  if(size<IVEL*myasgn.val.data.ivec->len+1){
                    if(*((int **)p)!=NULL) free(*((int **)p));
                    *((int **)p)=ivec_alloc(IVEL*myasgn.val.data.ivec->len+1);
                  }
                  q=(int *)*((int **)p);
                }else{
                  if(size<IVEL*myasgn.val.data.ivec->len+1){
                    fprintf(stderr,"sget_param: ivec too long for FORTRAN data type.\n");
                    return(0);
                  }
                  q=(int *)p;
                }
                if(ltrace)
                  fprintf(stderr,"sget_param: setting ivec len to %d\n",
                          myasgn.val.data.ivec->len);
                q[0]=myasgn.val.data.ivec->len;
                for(i=myasgn.val.data.ivec->len-1,il=myasgn.val.data.ivec;i>=0;i--,il=il->next){
                  rivcpy(q+i*IVEL+1,il->ivel,3);
                  q[IVEL*i+1+3]=0;
                }
              }else if(myasgn.val.type==FNAME){
                return(read_ascii_ivec(myasgn.val.data.str,(int **)p,size,cs));
              }else typeerr=1;
              break;
            case FVEC :
              if(myasgn.val.type==FVEC){
                if(cs){
                  if(size<FVEL*myasgn.val.data.fvec->len+1){
                    if(*((double **)p)!=NULL) free(*((double **)p));
                    *((double **)p)=vec_alloc(FVEL*myasgn.val.data.fvec->len+1);
                  }
                  r=(double *)*((double **)p);
                }else{
                  if(size<FVEL*myasgn.val.data.fvec->len+1){
                    fprintf(stderr,"sget_param: fvec too long for FORTRAN data type.\n");
                    return(0);
                  }
                  r=(double *)p;
                }
                r[0]=(double)myasgn.val.data.fvec->len;
                for(i=myasgn.val.data.fvec->len-1,fl=myasgn.val.data.fvec;i>=0;i--,fl=fl->next){
                  rdvcpy(r+i*FVEL+1,fl->fvel,3);
                  r[FVEL*i+1+3]=0;
                }
              }else if(myasgn.val.type==FNAME){
                return(read_ascii_fvec(myasgn.val.data.str,(double **)p,size,cs));
              }else typeerr=1;
              break;
          }
          break;
        case VECTOR :
          switch(sg_param_type){
            case LONG :
              if(size!=myasgn.vl->len){
                fprintf(stderr,"sget_param: expecting length %d, but read %d\n",size,myasgn.vl->len);
                return(0);
              }
              for(vl=myasgn.vl,i=size-1;i>=0;i--,vl=vl->next){
                if(vl->val.type==INUM)
                  ((int *)p)[i]=vl->val.data.inum;
                else typeerr=1;
              }
              break;
            case DOUBLE :
              if(size!=myasgn.vl->len){
                fprintf(stderr,"sget_param: expecting length %d, but read %d\n",size,myasgn.vl->len);
                return(0);
              }
              for(vl=myasgn.vl,i=size-1;i>=0;i--,vl=vl->next){
                if(vl->val.type==NUM)
                  ((double *)p)[i]=vl->val.data.num;
                else if(vl->val.type==INUM)
                  ((double *)p)[i]=(double)(vl->val.data.inum);
                else typeerr=1;
              }
              break;
            case STRING :
              if(size!=myasgn.vl->len){
                fprintf(stderr,"sget_param: expecting length %d, but read %d\n",size,myasgn.vl->len);
                return(0);
              }
              for(vl=myasgn.vl,i=size-1;i>=0;i--,vl=vl->next){
                if(vl->val.type==STR){
                  if(*((char **)p+i)!=NULL)
                    free(*((char **)p+i));
                  *((char**)p+i)=cvec_alloc(strlen(vl->val.data.str)+1);
                  strcpy(*((char**)p+i),vl->val.data.str);
                }else typeerr=1;
              }
              break;
          }
          break;
      }
      if(typeerr){
        fprintf(stderr,"sget_param: read bad value for <%s>.  Expected %s\n",name,type);
        return(0);
      }
    }
  }
  if(!found)
    return(-1);
  return(1);
}
[/font]
[/size]
[/quote]

[code]
/* gpar.l */

#include <stdlib.h>
#include <string.h>
#include "gpar.h"
#include "gpar.tab.h"

int my_gparinput(char *buf, int max_size);

#undef YY_INPUT
#define YY_INPUT(b,r,ms) (r=my_gparinput(b,ms))

#undef gparwrap

%}

word ([a-zA-Z_][a-zA-Z_0-9]*)

%%
%{
  extern int sg_param_type;
  extern int first_tok;
 
  if(first_tok){
    first_tok=0;
    if(YY_CURRENT_BUFFER) yy_flush_buffer(YY_CURRENT_BUFFER);
    return sg_param_type;
  }
 
%}


[ \t] ; /* ignore whitespace */

^[^=]+$ ; /* ignore lines without = */

\n ;

^[ \t]*#.*$ ; /* ignore comments */

(:=) {
  gparlval.inum=ASSIGNOP;
  return ASSIGNOP;
}

"=" {
  gparlval.inum=EQUALS;
  return EQUALS;
}

"+" {
  gparlval.inum=PLUS;
  return PLUS;
}

"-" {
  gparlval.inum=MINUS;
  return MINUS;
}

"*" {
  gparlval.inum=TIMES;
  return TIMES;
}

\/ {
  gparlval.inum=DIVIDE;
  return DIVIDE;
}

(\[) {
  gparlval.inum=OBRACK;
  return OBRACK;
}

(\]) {
  gparlval.inum=CBRACK;
  return CBRACK;
}

(\,) {
  gparlval.inum=COMMA;
  return COMMA;
}

([0-9]+) {
  gparlval.inum = atoi((const char *)gpartext);
  return INUM;
}

(([0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?) {
  sscanf((const char *)gpartext,"%lf",&gparlval.num);
  return NUM;
}

(\$) {
  fprintf(stdout, "******** EXTRACT TOKEN MATCHED ********\n");
  gparlval.inum=EXTRACT;
  return EXTRACT;
}

{word}((\.{word})|("->"{word}))* {
  gparlval.str=(char *)malloc(strlen((const char *)gpartext)+1);
  strcpy(gparlval.str,(const char *)gpartext);
  return IDEN;
}

(\"[^\"\n]*\") {
  gparlval.str = (char *)malloc(strlen((const char *)gpartext)-1);
  strncpy(gparlval.str,(const char *)gpartext+1,strlen((const char *)gpartext)-2);
  gparlval.str[strlen((const char *)gpartext)-2]=0;
  return STR;
}

"<<"{word} {
  gparlval.str=(char *)malloc(strlen((const char *)gpartext-1));
  strcpy(gparlval.str,(const char *)gpartext+2);
  return FNAME;
}


%%

extern char *sg_param_ptr, *sg_param_end;

int my_gparinput(char *buf, int max_size)
{
  int n;
 
  n=(max_size < (sg_param_end-sg_param_ptr)) ? max_size : (sg_param_end-sg_param_ptr);
  if(n>0){
    memcpy(buf,sg_param_ptr,n);
    sg_param_ptr+=n;
  }
  return n;
}

extern int inputerror;

void gparerror(const char *msg)
{
  /*fprintf(stderr,"GPARERROR: %s at '%s'\n",msg,gpartext);*/
  inputerror=1;
}

int gparwrap()
{
  return 1;
}
[/code]

[code]
/* gpar.h */
#include <bbhutil.h>

typedef struct iv{
  int len;
  int ivel[3];
  struct iv *next;
} ivel_list;

typedef struct fv{
  int len;
  double fvel[3];
  struct fv *next;
} fvel_list;

typedef struct {
  int type;
  union{
    int inum;
    double num;
    char *str;
    ivel_list *ivec;
    fvel_list *fvec;
  } data;
} value;

typedef struct vl{
  int len;
  value val;
  struct vl *next;
} value_list;

typedef struct {
  char *name;
  int type;
  value val;
  value_list *vl;
} assignment;

typedef struct alist{
  assignment assign;
  struct alist *next;
} assignment_list;

/* Global assignment list for extrapolating the value of somevariable in
* someParam := $[someVariable]
* if someVariable has already been assigned a value in gpar.y
*/
assignment_list *asgnList;

/* Is set to 1 if assignLook finds the value of its string parameter, toFind,
* and 0 otherwise.
*/
int change;


/* Searches asgnList for toAdd: if an assignment with the same name as
* toAdd.name is found in asgnList, the the assignment will be overwritten
* by toAdd and the function returns 1.  Otherwise, toAdd will be added
* to asgnList and the function returns 2.  If toAdd is null, -1 is returned.
*/
int addAssign(assignment toAdd);
assignment_list *assignLook(char *toFind);
[/code]
June 22, 2006, 6:30 PM

Search