Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

# 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,"%s:%d  ", yyfile, 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: %r");
                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;
        char *savfile;

        brac = 0;
        sw = TRUE;
        savline = 0;
        savfile = "?";

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;
                savfile=yyfile;
                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;
                savfile=yyfile;
                while( c=gch() ){
                        if( c=='*' ){
                                Bputc(&fout, c);
                                if( (c=gch()) == '/' ) goto loop;
                        }
                        Bputc(&fout, c);
                }
                yyline=savline;
                yyfile=savfile;
                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;
                yyfile = savfile;
                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);
                yyfile = sargv[fptr++];
                fin = Bopen(yyfile,OREAD);
                if(fin == 0)
                        error("%s - cannot open file: %r",yyfile);
                peek = Bgetc(fin);
                sargc--;
                sargv++;
        }
        if(c == Beof) {
                eof = TRUE;
                Bterm(fin);
                fin = 0;
                return(0);
        }
        if(c == '\n')yyline++;
        return(c);
}

int
mn2(int a, int d, uintptr 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
mnp(int a, void *p)
{
        name[tptr] = a;
        left[tptr] = 0;
        parent[tptr] = 0;
        nullstr[tptr] = 0;
        ptr[tptr] = p;
        switch(a){
        case RCCL:
        case RNCCL:
                if(strlen(p) == 0) nullstr[tptr] = TRUE;
                break;
        default:
                error("bad switch mnp %d %P", a, p);
                break;
        }
        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 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:
                return(mnp(i,ptr[n]));
        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)
{
        if(c < 0)
                c += 256;       /* signed char */
        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 ");
                                allprint(ptr[t]);
                                break;
                        case RNCCL:
                                print("nccl ");
                                allprint(ptr[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