%{ #include #include #include "reclass.h" #include "epp.h" #define YYSTYPE int int yylex(); int yyerror(); RECLASS table; int curval,startval,endval,loop_var; int maxclass; int interactive_parser=0; %} %token NUMBER %% list: statement | list eol statement ; statement: /* empty */ | dest range | map_statement | error { if (interactive_parser) yyerrok; else YYABORT; } dest: value '=' { curval=$1; } | '(' value ':' value ')' '=' { curval=-1; startval=$2 ; endval = $4; loop_var=startval;} eol: '\n' | '\r' '\n' range:subrange |range subrange subrange:value { if (curval>=0) table[$1]=curval; else {table[$1]=loop_var++; if (loop_var>endval) loop_var=startval; } } | value ':' value { int i; for(i=$1;i<=$3;i++) if (curval>=0) table[i]=curval; else {table[i]=loop_var++; if (loop_var>endval) loop_var=startval; } } ; value: NUMBER {if ($1>65535) { yyerror("Class value out of range\n"); return 1;YYERROR; } } map_statement: value ':' value '=' value ':' value { int i,start,stop,startv,stopv; if ($5>$7) {start=$7;startv=$3;stop=$5;stopv=$1;} else {start=$5;startv=$1;stop=$7;stopv=$3;} for (i=start;i<=stop;i++) table[i]=(i-start)*(stopv-startv)/(start-stop)+startv; } ; %% int (*my_getc)(); int yylex() { int c,numb=0,isnumb=0; static char unget_buf=0; while ((c=unget_buf?unget_buf:(*my_getc)())!=EOF) { unget_buf=0; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {isnumb=1; numb=numb*10+c-'0'; break;} case ' ': case '\t': {if (isnumb) { yylval=numb; return NUMBER; } break;} default: if (isnumb) { yylval=numb; unget_buf=c; return NUMBER;} else return c; } } return 0; } int yyerror(char *s) { fprintf(stderr,"%s\n",s); return 0; } RECLASS make_reclass_table(EPP *infile,int (*recl_getc)()) { int size=epp_table_size(infile); return parse_statements(size,create_reclass_table(size),recl_getc); } RECLASS parse_statements(int size,RECLASS src,int (*recl_getc)()) { my_getc=recl_getc; table=src; if (size>65535)size=65535; maxclass=size; if (yyparse()) { free(table);return NULL;} else return table; } RECLASS create_reclass_table(size) { RECLASS table; int i; if (size<=0) return NULL; else if (size>65535) size=65535; table=malloc((size+1)*sizeof(short int)); for(i=0;i<=size;i++) table[i]=i; return table; } RECLASS wrapped_reclass(EPP *infile,int white) { int i,maxclass; RECLASS table; maxclass=epp_table_size(infile); table=malloc(maxclass*sizeof(short int)); table[0]=0; for(i=1;i<=maxclass;i++) table[i]=(i-1)%(white-1)+1; table[infile->offsite]=white; return table; }