diff options
Diffstat (limited to 'src/cmd/lex/sub1.c')
-rw-r--r-- | src/cmd/lex/sub1.c | 591 |
1 files changed, 591 insertions, 0 deletions
diff --git a/src/cmd/lex/sub1.c b/src/cmd/lex/sub1.c new file mode 100644 index 00000000..cb393a46 --- /dev/null +++ b/src/cmd/lex/sub1.c @@ -0,0 +1,591 @@ +# include "ldefs.h" +uchar * +getl(uchar *p) /* return next line of input, throw away trailing '\n' */ + /* returns 0 if eof is had immediately */ +{ + int c; + uchar *s, *t; + + t = s = p; + while(((c = gch()) != 0) && c != '\n') + *t++ = c; + *t = 0; + if(c == 0 && s == t) return((uchar *)0); + prev = '\n'; + pres = '\n'; + return(s); +} + +void +printerr(char *type, char *fmt, va_list argl) +{ + char buf[1024]; + + if(!eof)fprint(errorf,"%d: ",yyline); + fprint(errorf,"(%s) ", type); + vseprint(buf, buf+sizeof(buf), fmt, argl); + fprint(errorf, "%s\n", buf); +} + + +void +error(char *s,...) +{ + va_list argl; + + va_start(argl, s); + printerr("Error", s, argl); + va_end(argl); +# ifdef DEBUG + if(debug && sect != ENDSECTION) { + sect1dump(); + sect2dump(); + } +# endif + if( +# ifdef DEBUG + debug || +# endif + report == 1) statistics(); + exits("error"); /* error return code */ +} + +void +warning(char *s,...) +{ + va_list argl; + + va_start(argl, s); + printerr("Warning", s, argl); + va_end(argl); + Bflush(&fout); +} + +void +lgate(void) +{ + int fd; + + if (lgatflg) return; + lgatflg=1; + if(foutopen == 0){ + fd = create("lex.yy.c", OWRITE, 0666); + if(fd < 0) + error("Can't open lex.yy.c"); + Binit(&fout, fd, OWRITE); + foutopen = 1; + } + phead1(); +} + +void +cclinter(int sw) +{ + /* sw = 1 ==> ccl */ + int i, j, k; + int m; + if(!sw){ /* is NCCL */ + for(i=1;i<NCH;i++) + symbol[i] ^= 1; /* reverse value */ + } + for(i=1;i<NCH;i++) + if(symbol[i]) break; + if(i >= NCH) return; + i = cindex[i]; + /* see if ccl is already in our table */ + j = 0; + if(i){ + for(j=1;j<NCH;j++){ + if((symbol[j] && cindex[j] != i) || + (!symbol[j] && cindex[j] == i)) break; + } + } + if(j >= NCH) return; /* already in */ + m = 0; + k = 0; + for(i=1;i<NCH;i++) + if(symbol[i]){ + if(!cindex[i]){ + cindex[i] = ccount; + symbol[i] = 0; + m = 1; + } else k = 1; + } + /* m == 1 implies last value of ccount has been used */ + if(m)ccount++; + if(k == 0) return; /* is now in as ccount wholly */ + /* intersection must be computed */ + for(i=1;i<NCH;i++){ + if(symbol[i]){ + m = 0; + j = cindex[i]; /* will be non-zero */ + for(k=1;k<NCH;k++){ + if(cindex[k] == j){ + if(symbol[k]) symbol[k] = 0; + else { + cindex[k] = ccount; + m = 1; + } + } + } + if(m)ccount++; + } + } +} + +int +usescape(int c) +{ + int d; + switch(c){ + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'b': c = '\b'; break; + case 'f': c = 014; break; /* form feed for ascii */ + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + while('0' <= (d=gch()) && d <= '7'){ + c = c * 8 + (d-'0'); + if(!('0' <= peek && peek <= '7')) break; + } + break; + } + return(c); +} + +int +lookup(uchar *s, uchar **t) +{ + int i; + i = 0; + while(*t){ + if(strcmp((char *)s, *(char **)t) == 0) + return(i); + i++; + t++; + } + return(-1); +} + +int +cpyact(void) +{ /* copy C action to the next ; or closing } */ + int brac, c, mth; + int savline, sw; + + brac = 0; + sw = TRUE; + savline = 0; + +while(!eof){ + c = gch(); +swt: + switch( c ){ + +case '|': if(brac == 0 && sw == TRUE){ + if(peek == '|')gch(); /* eat up an extra '|' */ + return(0); + } + break; + +case ';': + if( brac == 0 ){ + Bputc(&fout, c); + Bputc(&fout, '\n'); + return(1); + } + break; + +case '{': + brac++; + savline=yyline; + break; + +case '}': + brac--; + if( brac == 0 ){ + Bputc(&fout, c); + Bputc(&fout, '\n'); + return(1); + } + break; + +case '/': /* look for comments */ + Bputc(&fout, c); + c = gch(); + if( c != '*' ) goto swt; + + /* it really is a comment */ + + Bputc(&fout, c); + savline=yyline; + while( c=gch() ){ + if( c=='*' ){ + Bputc(&fout, c); + if( (c=gch()) == '/' ) goto loop; + } + Bputc(&fout, c); + } + yyline=savline; + error( "EOF inside comment" ); + +case '\'': /* character constant */ + mth = '\''; + goto string; + +case '"': /* character string */ + mth = '"'; + + string: + + Bputc(&fout, c); + while( c=gch() ){ + if( c=='\\' ){ + Bputc(&fout, c); + c=gch(); + } + else if( c==mth ) goto loop; + Bputc(&fout, c); + if (c == '\n') { + yyline--; + error( "Non-terminated string or character constant"); + } + } + error( "EOF in string or character constant" ); + +case '\0': + yyline = savline; + error("Action does not terminate"); +default: + break; /* usual character */ + } +loop: + if(c != ' ' && c != '\t' && c != '\n') sw = FALSE; + Bputc(&fout, c); + } + error("Premature EOF"); + return(0); +} + +int +gch(void){ + int c; + prev = pres; + c = pres = peek; + peek = pushptr > pushc ? *--pushptr : Bgetc(fin); + if(peek == Beof && sargc > 1){ + Bterm(fin); + fin = Bopen(sargv[fptr++],OREAD); + if(fin == 0) + error("Cannot open file %s",sargv[fptr-1]); + peek = Bgetc(fin); + sargc--; + sargv++; + } + if(c == Beof) { + eof = TRUE; + Bterm(fin); + return(0); + } + if(c == '\n')yyline++; + return(c); +} + +int +mn2(int a, int d, int c) +{ + name[tptr] = a; + left[tptr] = d; + right[tptr] = c; + parent[tptr] = 0; + nullstr[tptr] = 0; + switch(a){ + case RSTR: + parent[d] = tptr; + break; + case BAR: + case RNEWE: + if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE; + parent[d] = parent[c] = tptr; + break; + case RCAT: + case DIV: + if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE; + parent[d] = parent[c] = tptr; + break; + case RSCON: + parent[d] = tptr; + nullstr[tptr] = nullstr[d]; + break; +# ifdef DEBUG + default: + warning("bad switch mn2 %d %d",a,d); + break; +# endif + } + if(tptr > treesize) + error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); + return(tptr++); +} + +int +mn1(int a, int d) +{ + name[tptr] = a; + left[tptr] = d; + parent[tptr] = 0; + nullstr[tptr] = 0; + switch(a){ + case RCCL: + case RNCCL: + if(strlen((char *)d) == 0) nullstr[tptr] = TRUE; + break; + case STAR: + case QUEST: + nullstr[tptr] = TRUE; + parent[d] = tptr; + break; + case PLUS: + case CARAT: + nullstr[tptr] = nullstr[d]; + parent[d] = tptr; + break; + case S2FINAL: + nullstr[tptr] = TRUE; + break; +# ifdef DEBUG + case FINAL: + case S1FINAL: + break; + default: + warning("bad switch mn1 %d %d",a,d); + break; +# endif + } + if(tptr > treesize) + error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); + return(tptr++); +} + +int +mn0(int a) +{ + name[tptr] = a; + parent[tptr] = 0; + nullstr[tptr] = 0; + if(a >= NCH) switch(a){ + case RNULLS: nullstr[tptr] = TRUE; break; +# ifdef DEBUG + default: + warning("bad switch mn0 %d",a); + break; +# endif + } + if(tptr > treesize) + error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); + return(tptr++); +} + +void +munputc(int p) +{ + *pushptr++ = peek; /* watch out for this */ + peek = p; + if(pushptr >= pushc+TOKENSIZE) + error("Too many characters pushed"); +} + +void +munputs(uchar *p) +{ + int i,j; + *pushptr++ = peek; + peek = p[0]; + i = strlen((char*)p); + for(j = i-1; j>=1; j--) + *pushptr++ = p[j]; + if(pushptr >= pushc+TOKENSIZE) + error("Too many characters pushed"); +} + +int +dupl(int n) +{ + /* duplicate the subtree whose root is n, return ptr to it */ + int i; + + i = name[n]; + if(i < NCH) return(mn0(i)); + switch(i){ + case RNULLS: + return(mn0(i)); + case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL: + return(mn1(i,left[n])); + case STAR: case QUEST: case PLUS: case CARAT: + return(mn1(i,dupl(left[n]))); + case RSTR: case RSCON: + return(mn2(i,dupl(left[n]),right[n])); + case BAR: case RNEWE: case RCAT: case DIV: + return(mn2(i,dupl(left[n]),dupl(right[n]))); +# ifdef DEBUG + default: + warning("bad switch dupl %d",n); +# endif + } + return(0); +} + +# ifdef DEBUG +void +allprint(int c) +{ + switch(c){ + case 014: + print("\\f"); + charc++; + break; + case '\n': + print("\\n"); + charc++; + break; + case '\t': + print("\\t"); + charc++; + break; + case '\b': + print("\\b"); + charc++; + break; + case ' ': + print("\\\bb"); + break; + default: + if(!isprint(c)){ + print("\\%-3o",c); + charc += 3; + } else + print("%c", c); + break; + } + charc++; +} + +void +strpt(uchar *s) +{ + charc = 0; + while(*s){ + allprint(*s++); + if(charc > LINESIZE){ + charc = 0; + print("\n\t"); + } + } +} + +void +sect1dump(void) +{ + int i; + + print("Sect 1:\n"); + if(def[0]){ + print("str trans\n"); + i = -1; + while(def[++i]) + print("%s\t%s\n",def[i],subs[i]); + } + if(sname[0]){ + print("start names\n"); + i = -1; + while(sname[++i]) + print("%s\n",sname[i]); + } +} + +void +sect2dump(void) +{ + print("Sect 2:\n"); + treedump(); +} + +void +treedump(void) +{ + int t; + uchar *p; + print("treedump %d nodes:\n",tptr); + for(t=0;t<tptr;t++){ + print("%4d ",t); + parent[t] ? print("p=%4d",parent[t]) : print(" "); + print(" "); + if(name[t] < NCH) + allprint(name[t]); + else switch(name[t]){ + case RSTR: + print("%d ",left[t]); + allprint(right[t]); + break; + case RCCL: + print("ccl "); + strpt(left[t]); + break; + case RNCCL: + print("nccl "); + strpt(left[t]); + break; + case DIV: + print("/ %d %d",left[t],right[t]); + break; + case BAR: + print("| %d %d",left[t],right[t]); + break; + case RCAT: + print("cat %d %d",left[t],right[t]); + break; + case PLUS: + print("+ %d",left[t]); + break; + case STAR: + print("* %d",left[t]); + break; + case CARAT: + print("^ %d",left[t]); + break; + case QUEST: + print("? %d",left[t]); + break; + case RNULLS: + print("nullstring"); + break; + case FINAL: + print("final %d",left[t]); + break; + case S1FINAL: + print("s1final %d",left[t]); + break; + case S2FINAL: + print("s2final %d",left[t]); + break; + case RNEWE: + print("new %d %d",left[t],right[t]); + break; + case RSCON: + p = (uchar *)right[t]; + print("start %s",sname[*p++-1]); + while(*p) + print(", %s",sname[*p++-1]); + print(" %d",left[t]); + break; + default: + print("unknown %d %d %d",name[t],left[t],right[t]); + break; + } + if(nullstr[t])print("\t(null poss.)"); + print("\n"); + } +} +# endif |