%{
#include <stdio.h>
#include <string.h>
#define YYDEBUG 1
#define YYERROR_VERBOSE

void yyerror(char *s){
   printf("ERROR: yyerror: %s\n",s);
}

void header(FILE *fp){
      fprintf(fp,"/* AUTOGENERATED structure input routine */\n");
      fprintf(fp,"#include <stdio.h>\n");
      fprintf(fp,"#include <stdlib.h>\n");
      fprintf(fp,"#include <time.h>\n");
      fprintf(fp,"#include \"machine.h\"\n");
      fprintf(fp,"#include \"blocks.h\"\n");
      fprintf(fp,"/* ADD the header for the structure */\n");
}
void h_header(FILE *fp){
      fprintf(fp,"/* AUTOGENERATED header file for structure input routines */\n");
}

void prog(char * s,const char * strname){
      sprintf(s,"void input_%s_values(char * filename,struct %s *sp){\n",strname,strname);
}
void inp_intro(FILE *fp){
fprintf(fp,"   char *line;\n");
fprintf(fp,"   char *token;\n");
fprintf(fp,"   FILE *fp;\n");
fprintf(fp,"   char *sep;\n");
fprintf(fp,"   int error;\n");
fprintf(fp,"   int rflag = 0;\n");
fprintf(fp,"   line = (char *)calloc(MAX_STRING_LEN,sizeof(char));\n");
fprintf(fp,"   sep = strdup(\" ,;\\t\\n\\r\") ;\n");
fprintf(fp,"   \n");
fprintf(fp,"   /*********************************************************/\n");
fprintf(fp,"   /* Open the control file                                 */\n");
fprintf(fp,"   /*********************************************************/\n");
fprintf(fp,"   if((fp = fopen(filename,\"r\")) == NULL) {\n");
fprintf(fp,"      fprintf(stderr,\"Error: read_ctrl: can't open input file [%%s]\",filename);\n");
fprintf(fp,"      return;\n");
fprintf(fp,"    }\n");
fprintf(fp,"\n");
fprintf(fp,"   while (fgets(line, MAX_STRING_LEN, fp) != NULL) {\n");
fprintf(fp,"      /* ignore comment and blank lines */\n");
fprintf(fp,"      if(line[0]=='%%' || line[0]=='#'||(token = strtok(line,sep))==NULL) {\n");
fprintf(fp,"	      continue;\n");

}

FILE * fp,*hfp,*cfp;
char * line;
char  outstring[1000];
int cmtflag = 0;
int newflag = 0;
int nflag = 0;
int endflag = 0;
%}
%union{
int index;
double val;
char * name;
}
%token <val> NUMBER
%token <name> NAME KEY STRNAME OTHER STRSTART
%token <index> INDEX
%type <name> Name Key
%type <index> index Index
%%
input:  | input line ;

member: Key Name Other {fprintf(stderr,"/* %s Member name: %s */\n",$1,$2);
                  if (strcasecmp ($1,"int") == 0){
                     fprintf(cfp,"%-20s   /* %s %s */\n",$2,$1,$2);
                     fprintf(fp,"      }else if (strcasecmp(token,\"%s\")==0){\n",$2);
                     fprintf(fp,"         if ((token = strtok(NULL, sep)) != NULL){\n");
                     fprintf(fp,"            sp->%s = atoi(token);\n",$2);
                     fprintf(fp,"         }\n");
                  }else if (strcasecmp ($1,"float") == 0 || strcasecmp($1,"ca_float") ==0){
                     fprintf(cfp,"%-20s   /* %s %s */\n",$2,$1,$2);
                     fprintf(fp,"      }else if (strcasecmp(token,\"%s\")==0){\n",$2);
                     fprintf(fp,"         if ((token = strtok(NULL, sep)) != NULL){\n");
                     fprintf(fp,"            sp->%s = (%s)atof(token);\n",$2,$1);
                     fprintf(fp,"         }\n");
                  }
                /*  fprintf(fp,"}");*/

                 }
;
array: Key Name Index Other { if ($3 == 0){
                              fprintf(stderr,"/* %s -- Can't do multi arrays yet */\n",$1);
                           }else if (strcasecmp($1,"char")==0){
                              fprintf(stderr,"/* Member %s string array %s index %i*/\n",$1,$2,$3);
                              fprintf(cfp,"%-20s   /* %s %s */\n",$2,$1,$2);
                              fprintf(fp,"      }else if (strcasecmp(token,\"%s\")==0){\n",$2);
                              fprintf(fp,"         if ((token = strtok(NULL, sep)) != NULL){\n");
                              fprintf(fp,"            sprintf(sp->%s,token);\n",$2);
                              fprintf(fp,"         }\n");
                              /*fprintf(fp,"      }\n");*/

                           }else if (strcasecmp($1,"int")==0 || (strcasecmp($1,"float")==0) || (strcasecmp($1,"ca_float")==0)){
                              fprintf(stderr,"/* Member %s array %s index %i*/\n",$1,$2,$3);
                              fprintf(cfp,"%-20s   /* %s %s[%i] */\n",$2,$1,$2,$3);
                              fprintf(fp,"      }else if (strcasecmp(token,\"%s\")==0){\n",$2);
                              fprintf(fp,"         for(i=0;i<%i;i++){\n",$3);

                              if (strcasecmp ($1,"int") == 0){
                                 fprintf(fp,"         if ((token = strtok(NULL, sep)) != NULL){\n");
                                 fprintf(fp,"            sp->%s[i] = atoi(token);\n",$2);
                                 fprintf(fp,"         }\n");

                              }else if (strcasecmp ($1,"float") == 0 || strcasecmp($1,"ca_float") == 0){
                                 fprintf(fp,"         if ((token = strtok(NULL, sep)) != NULL){\n");
                                 fprintf(fp,"            sp->%s[i] = (%s)atof(token);\n",$2,$1);
                                 fprintf(fp,"         }\n");
                              }


                              fprintf(fp,"         }\n");
                              /*fprintf(fp,"}\n");*/
                              }
                           }
;
Index: index {$$ = $1;}
       | Index index {$$=0;}
;

index: INDEX {printf("Parser: index %i\n",$1);}
;

endstr: STRNAME {fprintf(fp,"\n      }\n   }\n}\n/* End of structure %s */\n",$1);}
;
strstart: STRSTART STRNAME {printf("Parser: strname %s\n",$2);
                            fprintf(fp,"/* start of structure %s */\n",$2);
                            prog(outstring,$2);
                            fprintf(fp,"%s",outstring);
                            fprintf(fp,"   int i;\n\n");
                            inp_intro(fp);
                            outstring[strlen(outstring)-2] = ';';
                            fprintf(hfp,"extern %s",outstring);
                           }
;
info:  Name {;} | Key {;} | Other {;} | Number {;} ;
line: array | strstart | endstr | member | info | info line;

Name: NAME {printf("parser: Name: %s\n",$1)}
;

Number: NUMBER {printf("parser: Number %f\n",$1)}
;

Key: KEY {printf("parser: Key: %s\n",$1)}
;

Other: OTHER {printf("parser: Other: %s\n",$1)}
;

%%


/*
int yylex(void){
   char * token;
   int return_val;

   if (newflag == 0){
      newflag = 1;
      token = strtok(line," ,\t");
   }else{
      token = strtok(NULL," ,\t");
   }

   if (token == NULL){
      return 0;
   }


   if ( token[0] == '/' || token[0] == '#' || token[0] == '%'){
       return_val = CMT;
       yylval.name = strdup(token);
   }else if(isalpha(token[0])){
      yylval.name = strdup(token);
      return_val = NAME;
   }else{
      yylval.val = atof(token);
      return_val= NUMBER;
   }
   return (return_val);
}
*/

void main(int argc, char * argv[]){
    fp = fopen("P_out.c","w");
    hfp = fopen("P_out.h","w");
    cfp = fopen("Struct.in","w");
    header (fp);
    h_header(hfp);
    while (endflag == 0){
       printf("Parsing .. \n");
       yyparse();
       printf("Enflag %i\n",endflag);
    }
    fclose (fp);
    fclose (hfp);
    fclose (cfp);
}





  


