URI: 
       tsub1.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tsub1.c (10164B)
       ---
            1 # include "ldefs.h"
            2 uchar *
            3 getl(uchar *p)        /* return next line of input, throw away trailing '\n' */
            4         /* returns 0 if eof is had immediately */
            5 {
            6         int c;
            7         uchar *s, *t;
            8 
            9         t = s = p;
           10         while(((c = gch()) != 0) && c != '\n')
           11                 *t++ = c;
           12         *t = 0;
           13         if(c == 0 && s == t) return((uchar *)0);
           14         prev = '\n';
           15         pres = '\n';
           16         return(s);
           17 }
           18 
           19 void
           20 printerr(char *type, char *fmt, va_list argl)
           21 {
           22         char buf[1024];
           23 
           24         if(!eof)fprint(errorf,"%d: ",yyline);
           25         fprint(errorf,"(%s) ", type);
           26         vseprint(buf, buf+sizeof(buf), fmt, argl);
           27         fprint(errorf, "%s\n", buf);
           28 }
           29 
           30 
           31 void
           32 error(char *s,...)
           33 {
           34         va_list argl;
           35 
           36         va_start(argl, s);
           37         printerr("Error", s, argl);
           38         va_end(argl);
           39 # ifdef DEBUG
           40         if(debug && sect != ENDSECTION) {
           41                 sect1dump();
           42                 sect2dump();
           43         }
           44 # endif
           45         if(
           46 # ifdef DEBUG
           47                 debug ||
           48 # endif
           49                 report == 1) statistics();
           50         exits("error");        /* error return code */
           51 }
           52 
           53 void
           54 warning(char *s,...)
           55 {
           56         va_list argl;
           57 
           58         va_start(argl, s);
           59         printerr("Warning", s, argl);
           60         va_end(argl);
           61         Bflush(&fout);
           62 }
           63 
           64 void
           65 lgate(void)
           66 {
           67         int fd;
           68 
           69         if (lgatflg) return;
           70         lgatflg=1;
           71         if(foutopen == 0){
           72                 fd = create("lex.yy.c", OWRITE, 0666);
           73                 if(fd < 0)
           74                         error("Can't open lex.yy.c");
           75                 Binit(&fout, fd, OWRITE);
           76                 foutopen = 1;
           77                 }
           78         phead1();
           79 }
           80 
           81 void
           82 cclinter(int sw)
           83 {
           84                 /* sw = 1 ==> ccl */
           85         int i, j, k;
           86         int m;
           87         if(!sw){                /* is NCCL */
           88                 for(i=1;i<NCH;i++)
           89                         symbol[i] ^= 1;                        /* reverse value */
           90         }
           91         for(i=1;i<NCH;i++)
           92                 if(symbol[i]) break;
           93         if(i >= NCH) return;
           94         i = cindex[i];
           95         /* see if ccl is already in our table */
           96         j = 0;
           97         if(i){
           98                 for(j=1;j<NCH;j++){
           99                         if((symbol[j] && cindex[j] != i) ||
          100                            (!symbol[j] && cindex[j] == i)) break;
          101                 }
          102         }
          103         if(j >= NCH) return;                /* already in */
          104         m = 0;
          105         k = 0;
          106         for(i=1;i<NCH;i++)
          107                 if(symbol[i]){
          108                         if(!cindex[i]){
          109                                 cindex[i] = ccount;
          110                                 symbol[i] = 0;
          111                                 m = 1;
          112                         } else k = 1;
          113                 }
          114                         /* m == 1 implies last value of ccount has been used */
          115         if(m)ccount++;
          116         if(k == 0) return;        /* is now in as ccount wholly */
          117         /* intersection must be computed */
          118         for(i=1;i<NCH;i++){
          119                 if(symbol[i]){
          120                         m = 0;
          121                         j = cindex[i];        /* will be non-zero */
          122                         for(k=1;k<NCH;k++){
          123                                 if(cindex[k] == j){
          124                                         if(symbol[k]) symbol[k] = 0;
          125                                         else {
          126                                                 cindex[k] = ccount;
          127                                                 m = 1;
          128                                         }
          129                                 }
          130                         }
          131                         if(m)ccount++;
          132                 }
          133         }
          134 }
          135 
          136 int
          137 usescape(int c)
          138 {
          139         int d;
          140         switch(c){
          141         case 'n': c = '\n'; break;
          142         case 'r': c = '\r'; break;
          143         case 't': c = '\t'; break;
          144         case 'b': c = '\b'; break;
          145         case 'f': c = 014; break;                /* form feed for ascii */
          146         case '0': case '1': case '2': case '3':
          147         case '4': case '5': case '6': case '7':
          148                 c -= '0';
          149                 while('0' <= (d=gch()) && d <= '7'){
          150                         c = c * 8 + (d-'0');
          151                         if(!('0' <= peek && peek <= '7')) break;
          152                         }
          153                 break;
          154         }
          155         return(c);
          156 }
          157 
          158 int
          159 lookup(uchar *s, uchar **t)
          160 {
          161         int i;
          162         i = 0;
          163         while(*t){
          164                 if(strcmp((char *)s, *(char **)t) == 0)
          165                         return(i);
          166                 i++;
          167                 t++;
          168         }
          169         return(-1);
          170 }
          171 
          172 int
          173 cpyact(void)
          174 { /* copy C action to the next ; or closing } */
          175         int brac, c, mth;
          176         int savline, sw;
          177 
          178         brac = 0;
          179         sw = TRUE;
          180         savline = 0;
          181 
          182 while(!eof){
          183         c = gch();
          184 swt:
          185         switch( c ){
          186 
          187 case '|':        if(brac == 0 && sw == TRUE){
          188                         if(peek == '|')gch();                /* eat up an extra '|' */
          189                         return(0);
          190                 }
          191                 break;
          192 
          193 case ';':
          194                 if( brac == 0 ){
          195                         Bputc(&fout, c);
          196                         Bputc(&fout, '\n');
          197                         return(1);
          198                 }
          199                 break;
          200 
          201 case '{':
          202                 brac++;
          203                 savline=yyline;
          204                 break;
          205 
          206 case '}':
          207                 brac--;
          208                 if( brac == 0 ){
          209                         Bputc(&fout, c);
          210                         Bputc(&fout, '\n');
          211                         return(1);
          212                 }
          213                 break;
          214 
          215 case '/':        /* look for comments */
          216                 Bputc(&fout, c);
          217                 c = gch();
          218                 if( c != '*' ) goto swt;
          219 
          220                 /* it really is a comment */
          221 
          222                 Bputc(&fout, c);
          223                 savline=yyline;
          224                 while( c=gch() ){
          225                         if( c=='*' ){
          226                                 Bputc(&fout, c);
          227                                 if( (c=gch()) == '/' ) goto loop;
          228                         }
          229                         Bputc(&fout, c);
          230                 }
          231                 yyline=savline;
          232                 error( "EOF inside comment" );
          233 
          234 case '\'':        /* character constant */
          235                 mth = '\'';
          236                 goto string;
          237 
          238 case '"':        /* character string */
          239                 mth = '"';
          240 
          241         string:
          242 
          243                 Bputc(&fout, c);
          244                 while( c=gch() ){
          245                         if( c=='\\' ){
          246                                 Bputc(&fout, c);
          247                                 c=gch();
          248                         }
          249                         else if( c==mth ) goto loop;
          250                         Bputc(&fout, c);
          251                         if (c == '\n') {
          252                                 yyline--;
          253                                 error( "Non-terminated string or character constant");
          254                         }
          255                 }
          256                 error( "EOF in string or character constant" );
          257 
          258 case '\0':
          259                 yyline = savline;
          260                 error("Action does not terminate");
          261 default:
          262                 break;                /* usual character */
          263                 }
          264 loop:
          265         if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
          266         Bputc(&fout, c);
          267         }
          268         error("Premature EOF");
          269         return(0);
          270 }
          271 
          272 int
          273 gch(void){
          274         int c;
          275         prev = pres;
          276         c = pres = peek;
          277         peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
          278         if(peek == Beof && sargc > 1){
          279                 Bterm(fin);
          280                 fin = Bopen(sargv[fptr++],OREAD);
          281                 if(fin == 0)
          282                         error("Cannot open file %s",sargv[fptr-1]);
          283                 peek = Bgetc(fin);
          284                 sargc--;
          285                 sargv++;
          286         }
          287         if(c == Beof) {
          288                 eof = TRUE;
          289                 Bterm(fin);
          290                 fin = 0;
          291                 return(0);
          292         }
          293         if(c == '\n')yyline++;
          294         return(c);
          295 }
          296 
          297 int
          298 mn2(int a, int d, uintptr c)
          299 {
          300         name[tptr] = a;
          301         left[tptr] = d;
          302         right[tptr] = c;
          303         parent[tptr] = 0;
          304         nullstr[tptr] = 0;
          305         switch(a){
          306         case RSTR:
          307                 parent[d] = tptr;
          308                 break;
          309         case BAR:
          310         case RNEWE:
          311                 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
          312                 parent[d] = parent[c] = tptr;
          313                 break;
          314         case RCAT:
          315         case DIV:
          316                 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
          317                 parent[d] = parent[c] = tptr;
          318                 break;
          319         case RSCON:
          320                 parent[d] = tptr;
          321                 nullstr[tptr] = nullstr[d];
          322                 break;
          323 # ifdef DEBUG
          324         default:
          325                 warning("bad switch mn2 %d %d",a,d);
          326                 break;
          327 # endif
          328                 }
          329         if(tptr > treesize)
          330                 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
          331         return(tptr++);
          332 }
          333 
          334 int
          335 mnp(int a, void *p)
          336 {
          337         name[tptr] = a;
          338         left[tptr] = 0;
          339         parent[tptr] = 0;
          340         nullstr[tptr] = 0;
          341         ptr[tptr] = p;
          342         switch(a){
          343         case RCCL:
          344         case RNCCL:
          345                 if(strlen(p) == 0) nullstr[tptr] = TRUE;
          346                 break;
          347         default:
          348                 error("bad switch mnp %d %P", a, p);
          349                 break;
          350         }
          351         if(tptr > treesize)
          352                 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
          353         return(tptr++);
          354 }
          355 
          356 int
          357 mn1(int a, int d)
          358 {
          359         name[tptr] = a;
          360         left[tptr] = d;
          361         parent[tptr] = 0;
          362         nullstr[tptr] = 0;
          363         switch(a){
          364         case STAR:
          365         case QUEST:
          366                 nullstr[tptr] = TRUE;
          367                 parent[d] = tptr;
          368                 break;
          369         case PLUS:
          370         case CARAT:
          371                 nullstr[tptr] = nullstr[d];
          372                 parent[d] = tptr;
          373                 break;
          374         case S2FINAL:
          375                 nullstr[tptr] = TRUE;
          376                 break;
          377 # ifdef DEBUG
          378         case FINAL:
          379         case S1FINAL:
          380                 break;
          381         default:
          382                 warning("bad switch mn1 %d %d",a,d);
          383                 break;
          384 # endif
          385         }
          386         if(tptr > treesize)
          387                 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
          388         return(tptr++);
          389 }
          390 
          391 int
          392 mn0(int a)
          393 {
          394         name[tptr] = a;
          395         parent[tptr] = 0;
          396         nullstr[tptr] = 0;
          397         if(a >= NCH) switch(a){
          398         case RNULLS: nullstr[tptr] = TRUE; break;
          399 # ifdef DEBUG
          400         default:
          401                 warning("bad switch mn0 %d",a);
          402                 break;
          403 # endif
          404         }
          405         if(tptr > treesize)
          406                 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
          407         return(tptr++);
          408 }
          409 
          410 void
          411 munputc(int p)
          412 {
          413         *pushptr++ = peek;                /* watch out for this */
          414         peek = p;
          415         if(pushptr >= pushc+TOKENSIZE)
          416                 error("Too many characters pushed");
          417 }
          418 
          419 void
          420 munputs(uchar *p)
          421 {
          422         int i,j;
          423         *pushptr++ = peek;
          424         peek = p[0];
          425         i = strlen((char*)p);
          426         for(j = i-1; j>=1; j--)
          427                 *pushptr++ = p[j];
          428         if(pushptr >= pushc+TOKENSIZE)
          429                 error("Too many characters pushed");
          430 }
          431 
          432 int
          433 dupl(int n)
          434 {
          435         /* duplicate the subtree whose root is n, return ptr to it */
          436         int i;
          437 
          438         i = name[n];
          439         if(i < NCH) return(mn0(i));
          440         switch(i){
          441         case RNULLS:
          442                 return(mn0(i));
          443         case RCCL: case RNCCL:
          444                 return(mnp(i,ptr[n]));
          445         case FINAL: case S1FINAL: case S2FINAL:
          446                 return(mn1(i,left[n]));
          447         case STAR: case QUEST: case PLUS: case CARAT:
          448                 return(mn1(i,dupl(left[n])));
          449         case RSTR: case RSCON:
          450                 return(mn2(i,dupl(left[n]),right[n]));
          451         case BAR: case RNEWE: case RCAT: case DIV:
          452                 return(mn2(i,dupl(left[n]),dupl(right[n])));
          453 # ifdef DEBUG
          454         default:
          455                 warning("bad switch dupl %d",n);
          456 # endif
          457         }
          458         return(0);
          459 }
          460 
          461 # ifdef DEBUG
          462 void
          463 allprint(int c)
          464 {
          465         if(c < 0)
          466                 c += 256;        /* signed char */
          467         switch(c){
          468                 case 014:
          469                         print("\\f");
          470                         charc++;
          471                         break;
          472                 case '\n':
          473                         print("\\n");
          474                         charc++;
          475                         break;
          476                 case '\t':
          477                         print("\\t");
          478                         charc++;
          479                         break;
          480                 case '\b':
          481                         print("\\b");
          482                         charc++;
          483                         break;
          484                 case ' ':
          485                         print("\\\bb");
          486                         break;
          487                 default:
          488                         if(!isprint(c)){
          489                                 print("\\%-3o",c);
          490                                 charc += 3;
          491                         } else
          492                                 print("%c", c);
          493                         break;
          494         }
          495         charc++;
          496 }
          497 
          498 void
          499 strpt(uchar *s)
          500 {
          501         charc = 0;
          502         while(*s){
          503                 allprint(*s++);
          504                 if(charc > LINESIZE){
          505                         charc = 0;
          506                         print("\n\t");
          507                 }
          508         }
          509 }
          510 
          511 void
          512 sect1dump(void)
          513 {
          514         int i;
          515 
          516         print("Sect 1:\n");
          517         if(def[0]){
          518                 print("str        trans\n");
          519                 i = -1;
          520                 while(def[++i])
          521                         print("%s\t%s\n",def[i],subs[i]);
          522         }
          523         if(sname[0]){
          524                 print("start names\n");
          525                 i = -1;
          526                 while(sname[++i])
          527                         print("%s\n",sname[i]);
          528         }
          529 }
          530 
          531 void
          532 sect2dump(void)
          533 {
          534         print("Sect 2:\n");
          535         treedump();
          536 }
          537 
          538 void
          539 treedump(void)
          540 {
          541         int t;
          542         uchar *p;
          543         print("treedump %d nodes:\n",tptr);
          544         for(t=0;t<tptr;t++){
          545                 print("%4d ",t);
          546                 parent[t] ? print("p=%4d",parent[t]) : print("      ");
          547                 print("  ");
          548                 if(name[t] < NCH)
          549                                 allprint(name[t]);
          550                 else switch(name[t]){
          551                         case RSTR:
          552                                 print("%d ",left[t]);
          553                                 allprint(right[t]);
          554                                 break;
          555                         case RCCL:
          556                                 print("ccl ");
          557                                 allprint(ptr[t]);
          558                                 break;
          559                         case RNCCL:
          560                                 print("nccl ");
          561                                 allprint(ptr[t]);
          562                                 break;
          563                         case DIV:
          564                                 print("/ %d %d",left[t],right[t]);
          565                                 break;
          566                         case BAR:
          567                                 print("| %d %d",left[t],right[t]);
          568                                 break;
          569                         case RCAT:
          570                                 print("cat %d %d",left[t],right[t]);
          571                                 break;
          572                         case PLUS:
          573                                 print("+ %d",left[t]);
          574                                 break;
          575                         case STAR:
          576                                 print("* %d",left[t]);
          577                                 break;
          578                         case CARAT:
          579                                 print("^ %d",left[t]);
          580                                 break;
          581                         case QUEST:
          582                                 print("? %d",left[t]);
          583                                 break;
          584                         case RNULLS:
          585                                 print("nullstring");
          586                                 break;
          587                         case FINAL:
          588                                 print("final %d",left[t]);
          589                                 break;
          590                         case S1FINAL:
          591                                 print("s1final %d",left[t]);
          592                                 break;
          593                         case S2FINAL:
          594                                 print("s2final %d",left[t]);
          595                                 break;
          596                         case RNEWE:
          597                                 print("new %d %d",left[t],right[t]);
          598                                 break;
          599                         case RSCON:
          600                                 p = (uchar *)right[t];
          601                                 print("start %s",sname[*p++-1]);
          602                                 while(*p)
          603                                         print(", %s",sname[*p++-1]);
          604                                 print(" %d",left[t]);
          605                                 break;
          606                         default:
          607                                 print("unknown %d %d %d",name[t],left[t],right[t]);
          608                                 break;
          609                 }
          610                 if(nullstr[t])print("\t(null poss.)");
          611                 print("\n");
          612         }
          613 }
          614 # endif