13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier #include <ctype.h>
53e12c5d1SDavid du Colombier
63e12c5d1SDavid du Colombier #define Bungetrune Bungetc /* ok for now. */
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier /*
93e12c5d1SDavid du Colombier * all these are 32 bit
103e12c5d1SDavid du Colombier */
113e12c5d1SDavid du Colombier #define TBITSET ((32+NTERMS)/32) /* BOTCH?? +31 */
123e12c5d1SDavid du Colombier #define BIT(a,i) ((a)[(i)>>5] & (1<<((i)&037)))
133e12c5d1SDavid du Colombier #define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037)))
143e12c5d1SDavid du Colombier #define NWORDS(n) (((n)+32)/32)
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier #define PARSER "/sys/lib/yaccpar"
173e12c5d1SDavid du Colombier #define PARSERS "/sys/lib/yaccpars"
183e12c5d1SDavid du Colombier #define TEMPNAME "y.tmp.XXXXXX"
193e12c5d1SDavid du Colombier #define ACTNAME "y.acts.XXXXXX"
203e12c5d1SDavid du Colombier #define OFILE "tab.c"
213e12c5d1SDavid du Colombier #define FILEU "output"
223e12c5d1SDavid du Colombier #define FILED "tab.h"
233e12c5d1SDavid du Colombier #define FILEDEBUG "debug"
243e12c5d1SDavid du Colombier
253e12c5d1SDavid du Colombier enum
263e12c5d1SDavid du Colombier {
273e12c5d1SDavid du Colombier /*
283e12c5d1SDavid du Colombier * the following are adjustable
293e12c5d1SDavid du Colombier * according to memory size
303e12c5d1SDavid du Colombier */
3180ee5cbfSDavid du Colombier ACTSIZE = 40000,
3280ee5cbfSDavid du Colombier MEMSIZE = 40000,
33bd389b36SDavid du Colombier NSTATES = 2000,
3480ee5cbfSDavid du Colombier NTERMS = 511,
3559cc4ca5SDavid du Colombier NPROD = 1600,
3680ee5cbfSDavid du Colombier NNONTERM = 600,
37bd389b36SDavid du Colombier TEMPSIZE = 2000,
3880ee5cbfSDavid du Colombier CNAMSZ = 10000,
397dd7cddfSDavid du Colombier LSETSIZE = 2400,
403e12c5d1SDavid du Colombier WSETSIZE = 350,
413e12c5d1SDavid du Colombier
423e12c5d1SDavid du Colombier NAMESIZE = 50,
433e12c5d1SDavid du Colombier NTYPES = 63,
443e12c5d1SDavid du Colombier ISIZE = 400,
453e12c5d1SDavid du Colombier
463e12c5d1SDavid du Colombier PRIVATE = 0xE000, /* unicode private use */
473e12c5d1SDavid du Colombier
483e12c5d1SDavid du Colombier /* relationships which must hold:
493e12c5d1SDavid du Colombier TBITSET ints must hold NTERMS+1 bits...
503e12c5d1SDavid du Colombier WSETSIZE >= NNONTERM
513e12c5d1SDavid du Colombier LSETSIZE >= NNONTERM
523e12c5d1SDavid du Colombier TEMPSIZE >= NTERMS + NNONTERM + 1
533e12c5d1SDavid du Colombier TEMPSIZE >= NSTATES
543e12c5d1SDavid du Colombier */
553e12c5d1SDavid du Colombier
563e12c5d1SDavid du Colombier NTBASE = 010000,
573e12c5d1SDavid du Colombier ERRCODE = 8190,
583e12c5d1SDavid du Colombier ACCEPTCODE = 8191,
593e12c5d1SDavid du Colombier
603e12c5d1SDavid du Colombier NOASC = 0, /* no assoc. */
613e12c5d1SDavid du Colombier LASC = 1, /* left assoc. */
623e12c5d1SDavid du Colombier RASC = 2, /* right assoc. */
633e12c5d1SDavid du Colombier BASC = 3, /* binary assoc. */
643e12c5d1SDavid du Colombier
653e12c5d1SDavid du Colombier /* flags for state generation */
663e12c5d1SDavid du Colombier
673e12c5d1SDavid du Colombier DONE = 0,
683e12c5d1SDavid du Colombier MUSTDO = 1,
693e12c5d1SDavid du Colombier MUSTLOOKAHEAD = 2,
703e12c5d1SDavid du Colombier
713e12c5d1SDavid du Colombier /* flags for a rule having an action, and being reduced */
723e12c5d1SDavid du Colombier
733e12c5d1SDavid du Colombier ACTFLAG = 04,
743e12c5d1SDavid du Colombier REDFLAG = 010,
753e12c5d1SDavid du Colombier
763e12c5d1SDavid du Colombier /* output parser flags */
773e12c5d1SDavid du Colombier YYFLAG1 = -1000,
783e12c5d1SDavid du Colombier
793e12c5d1SDavid du Colombier /* parse tokens */
803e12c5d1SDavid du Colombier IDENTIFIER = PRIVATE,
813e12c5d1SDavid du Colombier MARK,
823e12c5d1SDavid du Colombier TERM,
833e12c5d1SDavid du Colombier LEFT,
843e12c5d1SDavid du Colombier RIGHT,
853e12c5d1SDavid du Colombier BINARY,
863e12c5d1SDavid du Colombier PREC,
873e12c5d1SDavid du Colombier LCURLY,
883e12c5d1SDavid du Colombier IDENTCOLON,
893e12c5d1SDavid du Colombier NUMBER,
903e12c5d1SDavid du Colombier START,
913e12c5d1SDavid du Colombier TYPEDEF,
923e12c5d1SDavid du Colombier TYPENAME,
933e12c5d1SDavid du Colombier UNION,
943e12c5d1SDavid du Colombier
953e12c5d1SDavid du Colombier ENDFILE = 0,
963e12c5d1SDavid du Colombier
973e12c5d1SDavid du Colombier EMPTY = 1,
983e12c5d1SDavid du Colombier WHOKNOWS = 0,
993e12c5d1SDavid du Colombier OK = 1,
1003e12c5d1SDavid du Colombier NOMORE = -1000,
1013e12c5d1SDavid du Colombier };
1023e12c5d1SDavid du Colombier
1033e12c5d1SDavid du Colombier /* macros for getting associativity and precedence levels */
1043e12c5d1SDavid du Colombier
1053e12c5d1SDavid du Colombier #define ASSOC(i) ((i)&03)
1063e12c5d1SDavid du Colombier #define PLEVEL(i) (((i)>>4)&077)
1073e12c5d1SDavid du Colombier #define TYPE(i) (((i)>>10)&077)
1083e12c5d1SDavid du Colombier
1093e12c5d1SDavid du Colombier /* macros for setting associativity and precedence levels */
1103e12c5d1SDavid du Colombier
1113e12c5d1SDavid du Colombier #define SETASC(i,j) i |= j
1123e12c5d1SDavid du Colombier #define SETPLEV(i,j) i |= (j<<4)
1133e12c5d1SDavid du Colombier #define SETTYPE(i,j) i |= (j<<10)
1143e12c5d1SDavid du Colombier
1153e12c5d1SDavid du Colombier /* looping macros */
1163e12c5d1SDavid du Colombier
1173e12c5d1SDavid du Colombier #define TLOOP(i) for(i=1; i<=ntokens; i++)
1183e12c5d1SDavid du Colombier #define NTLOOP(i) for(i=0; i<=nnonter; i++)
1193e12c5d1SDavid du Colombier #define PLOOP(s,i) for(i=s; i<nprod; i++)
1203e12c5d1SDavid du Colombier #define SLOOP(i) for(i=0; i<nstate; i++)
1213e12c5d1SDavid du Colombier #define WSBUMP(x) x++
1223e12c5d1SDavid du Colombier #define WSLOOP(s,j) for(j=s; j<cwp; j++)
1233e12c5d1SDavid du Colombier #define ITMLOOP(i,p,q) for(q=pstate[i+1], p=pstate[i]; p<q; p++)
1243e12c5d1SDavid du Colombier #define SETLOOP(i) for(i=0; i<tbitset; i++)
1253e12c5d1SDavid du Colombier
1263e12c5d1SDavid du Colombier /* command to clobber tempfiles after use */
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier #define ZAPFILE(x) if(x) remove(x)
1293e12c5d1SDavid du Colombier
1303e12c5d1SDavid du Colombier /* I/O descriptors */
1313e12c5d1SDavid du Colombier
1323e12c5d1SDavid du Colombier Biobuf* faction; /* file for saving actions */
1333e12c5d1SDavid du Colombier Biobuf* fdefine; /* file for #defines */
1343e12c5d1SDavid du Colombier Biobuf* fdebug; /* y.debug for strings for debugging */
1353e12c5d1SDavid du Colombier Biobuf* ftable; /* y.tab.c file */
1363e12c5d1SDavid du Colombier Biobuf* ftemp; /* tempfile to pass 2 */
1373e12c5d1SDavid du Colombier Biobuf* finput; /* input file */
1383e12c5d1SDavid du Colombier Biobuf* foutput; /* y.output file */
1393e12c5d1SDavid du Colombier
1403e12c5d1SDavid du Colombier /* communication variables between various I/O routines */
1413e12c5d1SDavid du Colombier
1423e12c5d1SDavid du Colombier char* infile; /* input file name */
1433e12c5d1SDavid du Colombier int numbval; /* value of an input number */
144*f8f81444SDavid du Colombier char tokname[NAMESIZE+UTFmax+1]; /* input token name, slop for runes and 0 */
1453e12c5d1SDavid du Colombier
1463e12c5d1SDavid du Colombier /* structure declarations */
1473e12c5d1SDavid du Colombier
1483e12c5d1SDavid du Colombier typedef
1493e12c5d1SDavid du Colombier struct
1503e12c5d1SDavid du Colombier {
151219b2ee8SDavid du Colombier int lset[TBITSET];
1523e12c5d1SDavid du Colombier } Lkset;
1533e12c5d1SDavid du Colombier
1543e12c5d1SDavid du Colombier typedef
1553e12c5d1SDavid du Colombier struct
1563e12c5d1SDavid du Colombier {
1573e12c5d1SDavid du Colombier int* pitem;
1583e12c5d1SDavid du Colombier Lkset* look;
1593e12c5d1SDavid du Colombier } Item;
1603e12c5d1SDavid du Colombier
1613e12c5d1SDavid du Colombier typedef
1623e12c5d1SDavid du Colombier struct
1633e12c5d1SDavid du Colombier {
1643e12c5d1SDavid du Colombier char* name;
165219b2ee8SDavid du Colombier int value;
1663e12c5d1SDavid du Colombier } Symb;
1673e12c5d1SDavid du Colombier
1683e12c5d1SDavid du Colombier typedef
1693e12c5d1SDavid du Colombier struct
1703e12c5d1SDavid du Colombier {
1713e12c5d1SDavid du Colombier int* pitem;
1723e12c5d1SDavid du Colombier int flag;
1733e12c5d1SDavid du Colombier Lkset ws;
1743e12c5d1SDavid du Colombier } Wset;
1753e12c5d1SDavid du Colombier
1763e12c5d1SDavid du Colombier /* storage of names */
1773e12c5d1SDavid du Colombier
1783e12c5d1SDavid du Colombier char cnames[CNAMSZ]; /* place where token and nonterminal names are stored */
1793e12c5d1SDavid du Colombier int cnamsz = CNAMSZ; /* size of cnames */
1803e12c5d1SDavid du Colombier char* cnamp = cnames; /* place where next name is to be put in */
1813e12c5d1SDavid du Colombier int ndefout = 4; /* number of defined symbols output */
1823e12c5d1SDavid du Colombier char* tempname;
1833e12c5d1SDavid du Colombier char* actname;
1843e12c5d1SDavid du Colombier char ttempname[] = TEMPNAME;
1853e12c5d1SDavid du Colombier char tactname[] = ACTNAME;
1863e12c5d1SDavid du Colombier char* parser = PARSER;
1873e12c5d1SDavid du Colombier char* yydebug;
1883e12c5d1SDavid du Colombier
1893e12c5d1SDavid du Colombier /* storage of types */
1903e12c5d1SDavid du Colombier int ntypes; /* number of types defined */
1913e12c5d1SDavid du Colombier char* typeset[NTYPES]; /* pointers to type tags */
1923e12c5d1SDavid du Colombier
1933e12c5d1SDavid du Colombier /* token information */
1943e12c5d1SDavid du Colombier
1953e12c5d1SDavid du Colombier int ntokens = 0 ; /* number of tokens */
1963e12c5d1SDavid du Colombier Symb tokset[NTERMS];
1973e12c5d1SDavid du Colombier int toklev[NTERMS]; /* vector with the precedence of the terminals */
1983e12c5d1SDavid du Colombier
1993e12c5d1SDavid du Colombier /* nonterminal information */
2003e12c5d1SDavid du Colombier
2013e12c5d1SDavid du Colombier int nnonter = -1; /* the number of nonterminals */
2023e12c5d1SDavid du Colombier Symb nontrst[NNONTERM];
2033e12c5d1SDavid du Colombier int start; /* start symbol */
2043e12c5d1SDavid du Colombier
2053e12c5d1SDavid du Colombier /* assigned token type values */
2063e12c5d1SDavid du Colombier int extval = 0;
2073e12c5d1SDavid du Colombier
2083e12c5d1SDavid du Colombier char* ytabc = OFILE; /* name of y.tab.c */
2093e12c5d1SDavid du Colombier
2103e12c5d1SDavid du Colombier /* grammar rule information */
2113e12c5d1SDavid du Colombier
2123e12c5d1SDavid du Colombier int mem0[MEMSIZE] ; /* production storage */
2133e12c5d1SDavid du Colombier int* mem = mem0;
2143e12c5d1SDavid du Colombier int nprod = 1; /* number of productions */
2153e12c5d1SDavid du Colombier int* prdptr[NPROD]; /* pointers to descriptions of productions */
2163e12c5d1SDavid du Colombier int levprd[NPROD]; /* precedence levels for the productions */
2173e12c5d1SDavid du Colombier int rlines[NPROD]; /* line number for this rule */
2183e12c5d1SDavid du Colombier
2193e12c5d1SDavid du Colombier /* state information */
2203e12c5d1SDavid du Colombier
2213e12c5d1SDavid du Colombier int nstate = 0; /* number of states */
2223e12c5d1SDavid du Colombier Item* pstate[NSTATES+2]; /* pointers to the descriptions of the states */
2233e12c5d1SDavid du Colombier int tystate[NSTATES]; /* contains type information about the states */
2243e12c5d1SDavid du Colombier int defact[NSTATES]; /* the default actions of states */
2253e12c5d1SDavid du Colombier int tstates[NTERMS]; /* states generated by terminal gotos */
2263e12c5d1SDavid du Colombier int ntstates[NNONTERM]; /* states generated by nonterminal gotos */
2273e12c5d1SDavid du Colombier int mstates[NSTATES]; /* chain of overflows of term/nonterm generation lists */
2283e12c5d1SDavid du Colombier int lastred; /* the number of the last reduction of a state */
2293e12c5d1SDavid du Colombier
2303e12c5d1SDavid du Colombier /* lookahead set information */
2313e12c5d1SDavid du Colombier
2323e12c5d1SDavid du Colombier Lkset lkst[LSETSIZE];
2333e12c5d1SDavid du Colombier int nolook; /* flag to turn off lookahead computations */
2343e12c5d1SDavid du Colombier int tbitset; /* size of lookahead sets */
2353e12c5d1SDavid du Colombier int nlset = 0; /* next lookahead set index */
2363e12c5d1SDavid du Colombier int nolook = 0; /* flag to suppress lookahead computations */
2373e12c5d1SDavid du Colombier Lkset clset; /* temporary storage for lookahead computations */
2383e12c5d1SDavid du Colombier
2393e12c5d1SDavid du Colombier /* working set information */
2403e12c5d1SDavid du Colombier
2413e12c5d1SDavid du Colombier Wset wsets[WSETSIZE];
2423e12c5d1SDavid du Colombier Wset* cwp;
2433e12c5d1SDavid du Colombier
2443e12c5d1SDavid du Colombier /* storage for action table */
2453e12c5d1SDavid du Colombier
2463e12c5d1SDavid du Colombier int amem[ACTSIZE]; /* action table storage */
2473e12c5d1SDavid du Colombier int* memp = amem; /* next free action table position */
2483e12c5d1SDavid du Colombier int indgo[NSTATES]; /* index to the stored goto table */
2493e12c5d1SDavid du Colombier
2503e12c5d1SDavid du Colombier /* temporary vector, indexable by states, terms, or ntokens */
2513e12c5d1SDavid du Colombier
2523e12c5d1SDavid du Colombier int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */
2533e12c5d1SDavid du Colombier int lineno = 1; /* current input line number */
2543e12c5d1SDavid du Colombier int fatfl = 1; /* if on, error is fatal */
2553e12c5d1SDavid du Colombier int nerrors = 0; /* number of errors */
2563e12c5d1SDavid du Colombier
2573e12c5d1SDavid du Colombier /* statistics collection variables */
2583e12c5d1SDavid du Colombier
2593e12c5d1SDavid du Colombier int zzgoent;
2603e12c5d1SDavid du Colombier int zzgobest;
2613e12c5d1SDavid du Colombier int zzacent;
2623e12c5d1SDavid du Colombier int zzexcp;
2633e12c5d1SDavid du Colombier int zzclose;
2643e12c5d1SDavid du Colombier int zzrrconf;
2653e12c5d1SDavid du Colombier int zzsrconf;
2663e12c5d1SDavid du Colombier
2673e12c5d1SDavid du Colombier int* ggreed = lkst[0].lset;
2683e12c5d1SDavid du Colombier int* pgo = wsets[0].ws.lset;
2693e12c5d1SDavid du Colombier int* yypgo = &nontrst[0].value;
2703e12c5d1SDavid du Colombier
2713e12c5d1SDavid du Colombier int maxspr = 0; /* maximum spread of any entry */
2723e12c5d1SDavid du Colombier int maxoff = 0; /* maximum offset into a array */
2733e12c5d1SDavid du Colombier int* pmem = mem0;
2743e12c5d1SDavid du Colombier int* maxa;
2753e12c5d1SDavid du Colombier int nxdb = 0;
2763e12c5d1SDavid du Colombier int adb = 0;
2773e12c5d1SDavid du Colombier
2783e12c5d1SDavid du Colombier
2793e12c5d1SDavid du Colombier /* storage for information about the nonterminals */
2803e12c5d1SDavid du Colombier
2813e12c5d1SDavid du Colombier int** pres[NNONTERM+2]; /* vector of pointers to productions yielding each nonterminal */
2823e12c5d1SDavid du Colombier Lkset* pfirst[NNONTERM+2]; /* vector of pointers to first sets for each nonterminal */
2833e12c5d1SDavid du Colombier int pempty[NNONTERM+1]; /* vector of nonterminals nontrivially deriving e */
2843e12c5d1SDavid du Colombier
2853e12c5d1SDavid du Colombier /* random stuff picked out from between functions */
2863e12c5d1SDavid du Colombier
2873e12c5d1SDavid du Colombier int indebug = 0;
2883e12c5d1SDavid du Colombier Wset* zzcwp = wsets;
2893e12c5d1SDavid du Colombier int zzgoent = 0;
2903e12c5d1SDavid du Colombier int zzgobest = 0;
2913e12c5d1SDavid du Colombier int zzacent = 0;
2923e12c5d1SDavid du Colombier int zzexcp = 0;
2933e12c5d1SDavid du Colombier int zzclose = 0;
2943e12c5d1SDavid du Colombier int zzsrconf = 0;
2953e12c5d1SDavid du Colombier int* zzmemsz = mem0;
2963e12c5d1SDavid du Colombier int zzrrconf = 0;
2973e12c5d1SDavid du Colombier int pidebug = 0; /* debugging flag for putitem */
2983e12c5d1SDavid du Colombier int gsdebug = 0;
2993e12c5d1SDavid du Colombier int cldebug = 0; /* debugging flag for closure */
3003e12c5d1SDavid du Colombier int pkdebug = 0;
3013e12c5d1SDavid du Colombier int g2debug = 0;
3023e12c5d1SDavid du Colombier
3033e12c5d1SDavid du Colombier struct
3043e12c5d1SDavid du Colombier {
3053e12c5d1SDavid du Colombier char* name;
3063e12c5d1SDavid du Colombier long value;
3073e12c5d1SDavid du Colombier } resrv[] =
3083e12c5d1SDavid du Colombier {
3093e12c5d1SDavid du Colombier "binary", BINARY,
3103e12c5d1SDavid du Colombier "left", LEFT,
3113e12c5d1SDavid du Colombier "nonassoc", BINARY,
3123e12c5d1SDavid du Colombier "prec", PREC,
3133e12c5d1SDavid du Colombier "right", RIGHT,
3143e12c5d1SDavid du Colombier "start", START,
3153e12c5d1SDavid du Colombier "term", TERM,
3163e12c5d1SDavid du Colombier "token", TERM,
3173e12c5d1SDavid du Colombier "type", TYPEDEF,
3183e12c5d1SDavid du Colombier "union", UNION,
3193e12c5d1SDavid du Colombier 0,
3203e12c5d1SDavid du Colombier };
3213e12c5d1SDavid du Colombier
3223e12c5d1SDavid du Colombier /* define functions */
3233e12c5d1SDavid du Colombier
3243e12c5d1SDavid du Colombier void main(int, char**);
3253e12c5d1SDavid du Colombier void others(void);
3263e12c5d1SDavid du Colombier char* chcopy(char*, char*);
3273e12c5d1SDavid du Colombier char* writem(int*);
3283e12c5d1SDavid du Colombier char* symnam(int);
3293e12c5d1SDavid du Colombier void summary(void);
3303e12c5d1SDavid du Colombier void error(char*, ...);
3313e12c5d1SDavid du Colombier void aryfil(int*, int, int);
3323e12c5d1SDavid du Colombier int setunion(int*, int*);
3333e12c5d1SDavid du Colombier void prlook(Lkset*);
3343e12c5d1SDavid du Colombier void cpres(void);
3353e12c5d1SDavid du Colombier void cpfir(void);
3363e12c5d1SDavid du Colombier int state(int);
3373e12c5d1SDavid du Colombier void putitem(int*, Lkset*);
3383e12c5d1SDavid du Colombier void cempty(void);
3393e12c5d1SDavid du Colombier void stagen(void);
3403e12c5d1SDavid du Colombier void closure(int);
3413e12c5d1SDavid du Colombier Lkset* flset(Lkset*);
3423e12c5d1SDavid du Colombier void cleantmp(void);
3433e12c5d1SDavid du Colombier void intr(void);
3443e12c5d1SDavid du Colombier void setup(int, char**);
3453e12c5d1SDavid du Colombier void finact(void);
3463e12c5d1SDavid du Colombier int defin(int, char*);
3473e12c5d1SDavid du Colombier void defout(int);
3483e12c5d1SDavid du Colombier char* cstash(char*);
3493e12c5d1SDavid du Colombier long gettok(void);
3503e12c5d1SDavid du Colombier int fdtype(int);
3513e12c5d1SDavid du Colombier int chfind(int, char*);
3523e12c5d1SDavid du Colombier void cpyunion(void);
3533e12c5d1SDavid du Colombier void cpycode(void);
3543e12c5d1SDavid du Colombier int skipcom(void);
3553e12c5d1SDavid du Colombier void cpyact(int);
3563e12c5d1SDavid du Colombier void openup(char*, int, int, int, char*);
3573e12c5d1SDavid du Colombier void output(void);
3583e12c5d1SDavid du Colombier int apack(int*, int);
3593e12c5d1SDavid du Colombier void go2out(void);
3603e12c5d1SDavid du Colombier void go2gen(int);
3613e12c5d1SDavid du Colombier void precftn(int, int, int);
3623e12c5d1SDavid du Colombier void wract(int);
3633e12c5d1SDavid du Colombier void wrstate(int);
3643e12c5d1SDavid du Colombier void warray(char*, int*, int);
3653e12c5d1SDavid du Colombier void hideprod(void);
3663e12c5d1SDavid du Colombier void callopt(void);
3673e12c5d1SDavid du Colombier void gin(int);
3683e12c5d1SDavid du Colombier void stin(int);
3693e12c5d1SDavid du Colombier int nxti(void);
3703e12c5d1SDavid du Colombier void osummary(void);
3713e12c5d1SDavid du Colombier void aoutput(void);
3723e12c5d1SDavid du Colombier void arout(char*, int*, int);
3733e12c5d1SDavid du Colombier int gtnm(void);
3743e12c5d1SDavid du Colombier
3753e12c5d1SDavid du Colombier void
main(int argc,char * argv[])3763e12c5d1SDavid du Colombier main(int argc, char *argv[])
3773e12c5d1SDavid du Colombier {
3783e12c5d1SDavid du Colombier
3793e12c5d1SDavid du Colombier setup(argc, argv); /* initialize and read productions */
3803e12c5d1SDavid du Colombier tbitset = NWORDS(ntokens);
3813e12c5d1SDavid du Colombier cpres(); /* make table of which productions yield a given nonterminal */
3823e12c5d1SDavid du Colombier cempty(); /* make a table of which nonterminals can match the empty string */
3833e12c5d1SDavid du Colombier cpfir(); /* make a table of firsts of nonterminals */
3843e12c5d1SDavid du Colombier stagen(); /* generate the states */
3853e12c5d1SDavid du Colombier output(); /* write the states and the tables */
3863e12c5d1SDavid du Colombier go2out();
3873e12c5d1SDavid du Colombier hideprod();
3883e12c5d1SDavid du Colombier summary();
3893e12c5d1SDavid du Colombier callopt();
3903e12c5d1SDavid du Colombier others();
3913e12c5d1SDavid du Colombier exits(0);
3923e12c5d1SDavid du Colombier }
3933e12c5d1SDavid du Colombier
3943e12c5d1SDavid du Colombier /*
3953e12c5d1SDavid du Colombier * put out other arrays, copy the parsers
3963e12c5d1SDavid du Colombier */
3973e12c5d1SDavid du Colombier void
others(void)3983e12c5d1SDavid du Colombier others(void)
3993e12c5d1SDavid du Colombier {
4003e12c5d1SDavid du Colombier int c, i, j;
4013e12c5d1SDavid du Colombier
4023e12c5d1SDavid du Colombier finput = Bopen(parser, OREAD);
4033e12c5d1SDavid du Colombier if(finput == 0)
4043e12c5d1SDavid du Colombier error("cannot find parser %s", parser);
4053e12c5d1SDavid du Colombier warray("yyr1", levprd, nprod);
4063e12c5d1SDavid du Colombier aryfil(temp1, nprod, 0);
4073e12c5d1SDavid du Colombier PLOOP(1, i)
4083e12c5d1SDavid du Colombier temp1[i] = prdptr[i+1]-prdptr[i]-2;
4093e12c5d1SDavid du Colombier warray("yyr2", temp1, nprod);
4103e12c5d1SDavid du Colombier
4113e12c5d1SDavid du Colombier aryfil(temp1, nstate, -1000);
4123e12c5d1SDavid du Colombier TLOOP(i)
4133e12c5d1SDavid du Colombier for(j=tstates[i]; j!=0; j=mstates[j])
4143e12c5d1SDavid du Colombier temp1[j] = i;
4153e12c5d1SDavid du Colombier NTLOOP(i)
4163e12c5d1SDavid du Colombier for(j=ntstates[i]; j!=0; j=mstates[j])
4173e12c5d1SDavid du Colombier temp1[j] = -i;
4183e12c5d1SDavid du Colombier warray("yychk", temp1, nstate);
4193e12c5d1SDavid du Colombier warray("yydef", defact, nstate);
4203e12c5d1SDavid du Colombier
4213e12c5d1SDavid du Colombier /* put out token translation tables */
4223e12c5d1SDavid du Colombier /* table 1 has 0-256 */
4233e12c5d1SDavid du Colombier aryfil(temp1, 256, 0);
4243e12c5d1SDavid du Colombier c = 0;
4253e12c5d1SDavid du Colombier TLOOP(i) {
4263e12c5d1SDavid du Colombier j = tokset[i].value;
4273e12c5d1SDavid du Colombier if(j >= 0 && j < 256) {
428219b2ee8SDavid du Colombier if(temp1[j]) {
429219b2ee8SDavid du Colombier print("yacc bug -- cant have 2 different Ts with same value\n");
430219b2ee8SDavid du Colombier print(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name);
431219b2ee8SDavid du Colombier nerrors++;
432219b2ee8SDavid du Colombier }
4333e12c5d1SDavid du Colombier temp1[j] = i;
4343e12c5d1SDavid du Colombier if(j > c)
4353e12c5d1SDavid du Colombier c = j;
4363e12c5d1SDavid du Colombier }
4373e12c5d1SDavid du Colombier }
4383e12c5d1SDavid du Colombier warray("yytok1", temp1, c+1);
4393e12c5d1SDavid du Colombier
4403e12c5d1SDavid du Colombier /* table 2 has PRIVATE-PRIVATE+256 */
4413e12c5d1SDavid du Colombier aryfil(temp1, 256, 0);
4423e12c5d1SDavid du Colombier c = 0;
4433e12c5d1SDavid du Colombier TLOOP(i) {
4443e12c5d1SDavid du Colombier j = tokset[i].value - PRIVATE;
4453e12c5d1SDavid du Colombier if(j >= 0 && j < 256) {
446219b2ee8SDavid du Colombier if(temp1[j]) {
447219b2ee8SDavid du Colombier print("yacc bug -- cant have 2 different Ts with same value\n");
448219b2ee8SDavid du Colombier print(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name);
449219b2ee8SDavid du Colombier nerrors++;
450219b2ee8SDavid du Colombier }
4513e12c5d1SDavid du Colombier temp1[j] = i;
4523e12c5d1SDavid du Colombier if(j > c)
4533e12c5d1SDavid du Colombier c = j;
4543e12c5d1SDavid du Colombier }
4553e12c5d1SDavid du Colombier }
4563e12c5d1SDavid du Colombier warray("yytok2", temp1, c+1);
4573e12c5d1SDavid du Colombier
4583e12c5d1SDavid du Colombier /* table 3 has everything else */
4593e12c5d1SDavid du Colombier Bprint(ftable, "long yytok3[] =\n{\n");
4603e12c5d1SDavid du Colombier c = 0;
4613e12c5d1SDavid du Colombier TLOOP(i) {
4623e12c5d1SDavid du Colombier j = tokset[i].value;
4633e12c5d1SDavid du Colombier if(j >= 0 && j < 256)
4643e12c5d1SDavid du Colombier continue;
4653e12c5d1SDavid du Colombier if(j >= PRIVATE && j < 256+PRIVATE)
4663e12c5d1SDavid du Colombier continue;
4673e12c5d1SDavid du Colombier
4683e12c5d1SDavid du Colombier Bprint(ftable, "%4d,%4d,", j, i);
4693e12c5d1SDavid du Colombier c++;
4703e12c5d1SDavid du Colombier if(c%5 == 0)
4713e12c5d1SDavid du Colombier Bprint(ftable, "\n");
4723e12c5d1SDavid du Colombier }
4733e12c5d1SDavid du Colombier Bprint(ftable, "%4d\n};\n", 0);
4743e12c5d1SDavid du Colombier
4753e12c5d1SDavid du Colombier /* copy parser text */
4763e12c5d1SDavid du Colombier while((c=Bgetrune(finput)) != Beof) {
4773e12c5d1SDavid du Colombier if(c == '$') {
4783e12c5d1SDavid du Colombier if((c = Bgetrune(finput)) != 'A')
4793e12c5d1SDavid du Colombier Bputrune(ftable, '$');
4803e12c5d1SDavid du Colombier else { /* copy actions */
4813e12c5d1SDavid du Colombier faction = Bopen(actname, OREAD);
4823e12c5d1SDavid du Colombier if(faction == 0)
4833e12c5d1SDavid du Colombier error("cannot reopen action tempfile");
4843e12c5d1SDavid du Colombier while((c=Bgetrune(faction)) != Beof)
4853e12c5d1SDavid du Colombier Bputrune(ftable, c);
486219b2ee8SDavid du Colombier Bterm(faction);
4873e12c5d1SDavid du Colombier ZAPFILE(actname);
4883e12c5d1SDavid du Colombier c = Bgetrune(finput);
4893e12c5d1SDavid du Colombier }
4903e12c5d1SDavid du Colombier }
4913e12c5d1SDavid du Colombier Bputrune(ftable, c);
4923e12c5d1SDavid du Colombier }
493219b2ee8SDavid du Colombier Bterm(ftable);
4943e12c5d1SDavid du Colombier }
4953e12c5d1SDavid du Colombier
4963e12c5d1SDavid du Colombier /*
4973e12c5d1SDavid du Colombier * copies string q into p, returning next free char ptr
4983e12c5d1SDavid du Colombier */
4993e12c5d1SDavid du Colombier char*
chcopy(char * p,char * q)5003e12c5d1SDavid du Colombier chcopy(char* p, char* q)
5013e12c5d1SDavid du Colombier {
5023e12c5d1SDavid du Colombier int c;
5033e12c5d1SDavid du Colombier
5043e12c5d1SDavid du Colombier while(c = *q) {
5053e12c5d1SDavid du Colombier if(c == '"')
5063e12c5d1SDavid du Colombier *p++ = '\\';
5073e12c5d1SDavid du Colombier *p++ = c;
5083e12c5d1SDavid du Colombier q++;
5093e12c5d1SDavid du Colombier }
5103e12c5d1SDavid du Colombier *p = 0;
5113e12c5d1SDavid du Colombier return p;
5123e12c5d1SDavid du Colombier }
5133e12c5d1SDavid du Colombier
5143e12c5d1SDavid du Colombier /*
5153e12c5d1SDavid du Colombier * creates output string for item pointed to by pp
5163e12c5d1SDavid du Colombier */
5173e12c5d1SDavid du Colombier char*
writem(int * pp)5183e12c5d1SDavid du Colombier writem(int *pp)
5193e12c5d1SDavid du Colombier {
5203e12c5d1SDavid du Colombier int i,*p;
5213e12c5d1SDavid du Colombier static char sarr[ISIZE];
5223e12c5d1SDavid du Colombier char* q;
5233e12c5d1SDavid du Colombier
5243e12c5d1SDavid du Colombier for(p=pp; *p>0; p++)
5253e12c5d1SDavid du Colombier ;
5263e12c5d1SDavid du Colombier p = prdptr[-*p];
5273e12c5d1SDavid du Colombier q = chcopy(sarr, nontrst[*p-NTBASE].name);
5283e12c5d1SDavid du Colombier q = chcopy(q, ": ");
5293e12c5d1SDavid du Colombier for(;;) {
5303e12c5d1SDavid du Colombier *q = ' ';
5313e12c5d1SDavid du Colombier p++;
5323e12c5d1SDavid du Colombier if(p == pp)
5333e12c5d1SDavid du Colombier *q = '.';
5343e12c5d1SDavid du Colombier q++;
5353e12c5d1SDavid du Colombier *q = '\0';
5363e12c5d1SDavid du Colombier i = *p;
5373e12c5d1SDavid du Colombier if(i <= 0)
5383e12c5d1SDavid du Colombier break;
5393e12c5d1SDavid du Colombier q = chcopy(q, symnam(i));
5403e12c5d1SDavid du Colombier if(q > &sarr[ISIZE-30])
5413e12c5d1SDavid du Colombier error("item too big");
5423e12c5d1SDavid du Colombier }
5433e12c5d1SDavid du Colombier
5443e12c5d1SDavid du Colombier /* an item calling for a reduction */
5453e12c5d1SDavid du Colombier i = *pp;
5463e12c5d1SDavid du Colombier if(i < 0 ) {
5473e12c5d1SDavid du Colombier q = chcopy(q, " (");
5483e12c5d1SDavid du Colombier sprint(q, "%d)", -i);
5493e12c5d1SDavid du Colombier }
5503e12c5d1SDavid du Colombier return sarr;
5513e12c5d1SDavid du Colombier }
5523e12c5d1SDavid du Colombier
5533e12c5d1SDavid du Colombier /*
5543e12c5d1SDavid du Colombier * return a pointer to the name of symbol i
5553e12c5d1SDavid du Colombier */
5563e12c5d1SDavid du Colombier char*
symnam(int i)5573e12c5d1SDavid du Colombier symnam(int i)
5583e12c5d1SDavid du Colombier {
5593e12c5d1SDavid du Colombier char* cp;
5603e12c5d1SDavid du Colombier
5613e12c5d1SDavid du Colombier cp = (i >= NTBASE)? nontrst[i-NTBASE].name: tokset[i].name;
5623e12c5d1SDavid du Colombier if(*cp == ' ')
5633e12c5d1SDavid du Colombier cp++;
5643e12c5d1SDavid du Colombier return cp;
5653e12c5d1SDavid du Colombier }
5663e12c5d1SDavid du Colombier
5673e12c5d1SDavid du Colombier /*
5683e12c5d1SDavid du Colombier * output the summary on y.output
5693e12c5d1SDavid du Colombier */
5703e12c5d1SDavid du Colombier void
summary(void)5713e12c5d1SDavid du Colombier summary(void)
5723e12c5d1SDavid du Colombier {
5733e12c5d1SDavid du Colombier
5743e12c5d1SDavid du Colombier if(foutput != 0) {
5753e12c5d1SDavid du Colombier Bprint(foutput, "\n%d/%d terminals, %d/%d nonterminals\n",
5763e12c5d1SDavid du Colombier ntokens, NTERMS, nnonter, NNONTERM);
5773e12c5d1SDavid du Colombier Bprint(foutput, "%d/%d grammar rules, %d/%d states\n",
5783e12c5d1SDavid du Colombier nprod, NPROD, nstate, NSTATES);
5793e12c5d1SDavid du Colombier Bprint(foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n",
5803e12c5d1SDavid du Colombier zzsrconf, zzrrconf);
5813e12c5d1SDavid du Colombier Bprint(foutput, "%d/%d working sets used\n",
5827dd7cddfSDavid du Colombier (int)(zzcwp-wsets), WSETSIZE);
5833e12c5d1SDavid du Colombier Bprint(foutput, "memory: states,etc. %d/%d, parser %d/%d\n",
5847dd7cddfSDavid du Colombier (int)(zzmemsz-mem0), MEMSIZE, (int)(memp-amem), ACTSIZE);
5853e12c5d1SDavid du Colombier Bprint(foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE);
5863e12c5d1SDavid du Colombier Bprint(foutput, "%d extra closures\n", zzclose - 2*nstate);
5873e12c5d1SDavid du Colombier Bprint(foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp);
5883e12c5d1SDavid du Colombier Bprint(foutput, "%d goto entries\n", zzgoent);
5893e12c5d1SDavid du Colombier Bprint(foutput, "%d entries saved by goto default\n", zzgobest);
5903e12c5d1SDavid du Colombier }
5913e12c5d1SDavid du Colombier if(zzsrconf != 0 || zzrrconf != 0) {
5923e12c5d1SDavid du Colombier print("\nconflicts: ");
5933e12c5d1SDavid du Colombier if(zzsrconf)
5943e12c5d1SDavid du Colombier print("%d shift/reduce", zzsrconf);
5953e12c5d1SDavid du Colombier if(zzsrconf && zzrrconf)
5963e12c5d1SDavid du Colombier print(", ");
5973e12c5d1SDavid du Colombier if(zzrrconf)
5983e12c5d1SDavid du Colombier print("%d reduce/reduce", zzrrconf);
5993e12c5d1SDavid du Colombier print("\n");
6003e12c5d1SDavid du Colombier }
6017dd7cddfSDavid du Colombier if(ftemp != 0) {
602219b2ee8SDavid du Colombier Bterm(ftemp);
6037dd7cddfSDavid du Colombier ftemp = 0;
6047dd7cddfSDavid du Colombier }
6057dd7cddfSDavid du Colombier if(fdefine != 0) {
606219b2ee8SDavid du Colombier Bterm(fdefine);
6077dd7cddfSDavid du Colombier fdefine = 0;
6087dd7cddfSDavid du Colombier }
6093e12c5d1SDavid du Colombier }
6103e12c5d1SDavid du Colombier
6113e12c5d1SDavid du Colombier /*
6123e12c5d1SDavid du Colombier * write out error comment -- NEEDS WORK
6133e12c5d1SDavid du Colombier */
6143e12c5d1SDavid du Colombier void
error(char * s,...)6153e12c5d1SDavid du Colombier error(char *s, ...)
6163e12c5d1SDavid du Colombier {
6173e12c5d1SDavid du Colombier
6183e12c5d1SDavid du Colombier nerrors++;
6193e12c5d1SDavid du Colombier fprint(2, "\n fatal error:");
6203e12c5d1SDavid du Colombier fprint(2, s, (&s)[1]);
621219b2ee8SDavid du Colombier fprint(2, ", %s:%d\n", infile, lineno);
6223e12c5d1SDavid du Colombier if(!fatfl)
6233e12c5d1SDavid du Colombier return;
6243e12c5d1SDavid du Colombier summary();
6253e12c5d1SDavid du Colombier cleantmp();
6263e12c5d1SDavid du Colombier exits("error");
6273e12c5d1SDavid du Colombier }
6283e12c5d1SDavid du Colombier
6293e12c5d1SDavid du Colombier /*
6303e12c5d1SDavid du Colombier * set elements 0 through n-1 to c
6313e12c5d1SDavid du Colombier */
6323e12c5d1SDavid du Colombier void
aryfil(int * v,int n,int c)6333e12c5d1SDavid du Colombier aryfil(int *v, int n, int c)
6343e12c5d1SDavid du Colombier {
6353e12c5d1SDavid du Colombier int i;
6363e12c5d1SDavid du Colombier
6373e12c5d1SDavid du Colombier for(i=0; i<n; i++)
6383e12c5d1SDavid du Colombier v[i] = c;
6393e12c5d1SDavid du Colombier }
6403e12c5d1SDavid du Colombier
6413e12c5d1SDavid du Colombier /*
6423e12c5d1SDavid du Colombier * set a to the union of a and b
6433e12c5d1SDavid du Colombier * return 1 if b is not a subset of a, 0 otherwise
6443e12c5d1SDavid du Colombier */
6453e12c5d1SDavid du Colombier int
setunion(int * a,int * b)6463e12c5d1SDavid du Colombier setunion(int *a, int *b)
6473e12c5d1SDavid du Colombier {
6483e12c5d1SDavid du Colombier int i, x, sub;
6493e12c5d1SDavid du Colombier
6503e12c5d1SDavid du Colombier sub = 0;
6513e12c5d1SDavid du Colombier SETLOOP(i) {
6523e12c5d1SDavid du Colombier x = *a;
6533e12c5d1SDavid du Colombier *a |= *b;
6543e12c5d1SDavid du Colombier if(*a != x)
6553e12c5d1SDavid du Colombier sub = 1;
6563e12c5d1SDavid du Colombier a++;
6573e12c5d1SDavid du Colombier b++;
6583e12c5d1SDavid du Colombier }
6593e12c5d1SDavid du Colombier return sub;
6603e12c5d1SDavid du Colombier }
6613e12c5d1SDavid du Colombier
6623e12c5d1SDavid du Colombier void
prlook(Lkset * p)6633e12c5d1SDavid du Colombier prlook(Lkset* p)
6643e12c5d1SDavid du Colombier {
6653e12c5d1SDavid du Colombier int j, *pp;
6663e12c5d1SDavid du Colombier
6673e12c5d1SDavid du Colombier pp = p->lset;
6683e12c5d1SDavid du Colombier if(pp == 0)
6693e12c5d1SDavid du Colombier Bprint(foutput, "\tNULL");
6703e12c5d1SDavid du Colombier else {
6713e12c5d1SDavid du Colombier Bprint(foutput, " { ");
6723e12c5d1SDavid du Colombier TLOOP(j)
6733e12c5d1SDavid du Colombier if(BIT(pp,j))
6743e12c5d1SDavid du Colombier Bprint(foutput, "%s ", symnam(j));
6753e12c5d1SDavid du Colombier Bprint(foutput, "}");
6763e12c5d1SDavid du Colombier }
6773e12c5d1SDavid du Colombier }
6783e12c5d1SDavid du Colombier
6793e12c5d1SDavid du Colombier /*
6803e12c5d1SDavid du Colombier * compute an array with the beginnings of productions yielding given nonterminals
6813e12c5d1SDavid du Colombier * The array pres points to these lists
6823e12c5d1SDavid du Colombier * the array pyield has the lists: the total size is only NPROD+1
6833e12c5d1SDavid du Colombier */
6843e12c5d1SDavid du Colombier void
cpres(void)6853e12c5d1SDavid du Colombier cpres(void)
6863e12c5d1SDavid du Colombier {
6873e12c5d1SDavid du Colombier int c, j, i, **pmem;
6883e12c5d1SDavid du Colombier static int *pyield[NPROD];
6893e12c5d1SDavid du Colombier
6903e12c5d1SDavid du Colombier pmem = pyield;
6913e12c5d1SDavid du Colombier NTLOOP(i) {
6923e12c5d1SDavid du Colombier c = i+NTBASE;
6933e12c5d1SDavid du Colombier pres[i] = pmem;
6943e12c5d1SDavid du Colombier fatfl = 0; /* make undefined symbols nonfatal */
6953e12c5d1SDavid du Colombier PLOOP(0, j)
6963e12c5d1SDavid du Colombier if(*prdptr[j] == c)
6973e12c5d1SDavid du Colombier *pmem++ = prdptr[j]+1;
6983e12c5d1SDavid du Colombier if(pres[i] == pmem)
6993e12c5d1SDavid du Colombier error("nonterminal %s not defined!", nontrst[i].name);
7003e12c5d1SDavid du Colombier }
7013e12c5d1SDavid du Colombier pres[i] = pmem;
7023e12c5d1SDavid du Colombier fatfl = 1;
7033e12c5d1SDavid du Colombier if(nerrors) {
7043e12c5d1SDavid du Colombier summary();
7053e12c5d1SDavid du Colombier cleantmp();
7063e12c5d1SDavid du Colombier exits("error");
7073e12c5d1SDavid du Colombier }
7083e12c5d1SDavid du Colombier if(pmem != &pyield[nprod])
7093e12c5d1SDavid du Colombier error("internal Yacc error: pyield %d", pmem-&pyield[nprod]);
7103e12c5d1SDavid du Colombier }
7113e12c5d1SDavid du Colombier
7123e12c5d1SDavid du Colombier /*
7133e12c5d1SDavid du Colombier * compute an array with the first of nonterminals
7143e12c5d1SDavid du Colombier */
7153e12c5d1SDavid du Colombier void
cpfir(void)7163e12c5d1SDavid du Colombier cpfir(void)
7173e12c5d1SDavid du Colombier {
7183e12c5d1SDavid du Colombier int *p, **s, i, **t, ch, changes;
7193e12c5d1SDavid du Colombier
7203e12c5d1SDavid du Colombier zzcwp = &wsets[nnonter];
7213e12c5d1SDavid du Colombier NTLOOP(i) {
7223e12c5d1SDavid du Colombier aryfil(wsets[i].ws.lset, tbitset, 0);
7233e12c5d1SDavid du Colombier t = pres[i+1];
7243e12c5d1SDavid du Colombier /* initially fill the sets */
7253e12c5d1SDavid du Colombier for(s=pres[i]; s<t; ++s)
7263e12c5d1SDavid du Colombier for(p = *s; (ch = *p) > 0; ++p) {
7273e12c5d1SDavid du Colombier if(ch < NTBASE) {
7283e12c5d1SDavid du Colombier SETBIT(wsets[i].ws.lset, ch);
7293e12c5d1SDavid du Colombier break;
7303e12c5d1SDavid du Colombier }
7313e12c5d1SDavid du Colombier if(!pempty[ch-NTBASE])
7323e12c5d1SDavid du Colombier break;
7333e12c5d1SDavid du Colombier }
7343e12c5d1SDavid du Colombier }
7353e12c5d1SDavid du Colombier
7363e12c5d1SDavid du Colombier /* now, reflect transitivity */
7373e12c5d1SDavid du Colombier changes = 1;
7383e12c5d1SDavid du Colombier while(changes) {
7393e12c5d1SDavid du Colombier changes = 0;
7403e12c5d1SDavid du Colombier NTLOOP(i) {
7413e12c5d1SDavid du Colombier t = pres[i+1];
7423e12c5d1SDavid du Colombier for(s = pres[i]; s < t; ++s)
7433e12c5d1SDavid du Colombier for(p = *s; (ch = (*p-NTBASE)) >= 0; ++p) {
7443e12c5d1SDavid du Colombier changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset);
7453e12c5d1SDavid du Colombier if(!pempty[ch])
7463e12c5d1SDavid du Colombier break;
7473e12c5d1SDavid du Colombier }
7483e12c5d1SDavid du Colombier }
7493e12c5d1SDavid du Colombier }
7503e12c5d1SDavid du Colombier
7513e12c5d1SDavid du Colombier NTLOOP(i)
7523e12c5d1SDavid du Colombier pfirst[i] = flset(&wsets[i].ws);
7533e12c5d1SDavid du Colombier if(!indebug)
7543e12c5d1SDavid du Colombier return;
7553e12c5d1SDavid du Colombier if(foutput != 0)
7563e12c5d1SDavid du Colombier NTLOOP(i) {
7573e12c5d1SDavid du Colombier Bprint(foutput, "\n%s: ", nontrst[i].name);
7583e12c5d1SDavid du Colombier prlook(pfirst[i]);
7593e12c5d1SDavid du Colombier Bprint(foutput, " %d\n", pempty[i]);
7603e12c5d1SDavid du Colombier }
7613e12c5d1SDavid du Colombier }
7623e12c5d1SDavid du Colombier
7633e12c5d1SDavid du Colombier /*
7643e12c5d1SDavid du Colombier * sorts last state,and sees if it equals earlier ones. returns state number
7653e12c5d1SDavid du Colombier */
7663e12c5d1SDavid du Colombier int
state(int c)7673e12c5d1SDavid du Colombier state(int c)
7683e12c5d1SDavid du Colombier {
7693e12c5d1SDavid du Colombier Item *p1, *p2, *k, *l, *q1, *q2;
7703e12c5d1SDavid du Colombier int size1, size2, i;
7713e12c5d1SDavid du Colombier
7723e12c5d1SDavid du Colombier p1 = pstate[nstate];
7733e12c5d1SDavid du Colombier p2 = pstate[nstate+1];
7743e12c5d1SDavid du Colombier if(p1 == p2)
7753e12c5d1SDavid du Colombier return 0; /* null state */
7763e12c5d1SDavid du Colombier /* sort the items */
7773e12c5d1SDavid du Colombier for(k = p2-1; k > p1; k--) /* make k the biggest */
7783e12c5d1SDavid du Colombier for(l = k-1; l >= p1; --l)
7793e12c5d1SDavid du Colombier if(l->pitem > k->pitem) {
7803e12c5d1SDavid du Colombier int *s;
7813e12c5d1SDavid du Colombier Lkset *ss;
7823e12c5d1SDavid du Colombier
7833e12c5d1SDavid du Colombier s = k->pitem;
7843e12c5d1SDavid du Colombier k->pitem = l->pitem;
7853e12c5d1SDavid du Colombier l->pitem = s;
7863e12c5d1SDavid du Colombier ss = k->look;
7873e12c5d1SDavid du Colombier k->look = l->look;
7883e12c5d1SDavid du Colombier l->look = ss;
7893e12c5d1SDavid du Colombier }
7903e12c5d1SDavid du Colombier size1 = p2 - p1; /* size of state */
7913e12c5d1SDavid du Colombier
7923e12c5d1SDavid du Colombier for(i = (c>=NTBASE)? ntstates[c-NTBASE]: tstates[c]; i != 0; i = mstates[i]) {
7933e12c5d1SDavid du Colombier /* get ith state */
7943e12c5d1SDavid du Colombier q1 = pstate[i];
7953e12c5d1SDavid du Colombier q2 = pstate[i+1];
7963e12c5d1SDavid du Colombier size2 = q2 - q1;
7973e12c5d1SDavid du Colombier if(size1 != size2)
7983e12c5d1SDavid du Colombier continue;
7993e12c5d1SDavid du Colombier k = p1;
8003e12c5d1SDavid du Colombier for(l = q1; l < q2; l++) {
8013e12c5d1SDavid du Colombier if(l->pitem != k->pitem)
8023e12c5d1SDavid du Colombier break;
8033e12c5d1SDavid du Colombier k++;
8043e12c5d1SDavid du Colombier }
8053e12c5d1SDavid du Colombier if(l != q2)
8063e12c5d1SDavid du Colombier continue;
8073e12c5d1SDavid du Colombier /* found it */
8083e12c5d1SDavid du Colombier pstate[nstate+1] = pstate[nstate]; /* delete last state */
8093e12c5d1SDavid du Colombier /* fix up lookaheads */
8103e12c5d1SDavid du Colombier if(nolook)
8113e12c5d1SDavid du Colombier return i;
8123e12c5d1SDavid du Colombier for(l = q1, k = p1; l < q2; ++l, ++k ) {
8133e12c5d1SDavid du Colombier int s;
8143e12c5d1SDavid du Colombier
8153e12c5d1SDavid du Colombier SETLOOP(s)
8163e12c5d1SDavid du Colombier clset.lset[s] = l->look->lset[s];
8173e12c5d1SDavid du Colombier if(setunion(clset.lset, k->look->lset)) {
8183e12c5d1SDavid du Colombier tystate[i] = MUSTDO;
8193e12c5d1SDavid du Colombier /* register the new set */
8203e12c5d1SDavid du Colombier l->look = flset( &clset );
8213e12c5d1SDavid du Colombier }
8223e12c5d1SDavid du Colombier }
8233e12c5d1SDavid du Colombier return i;
8243e12c5d1SDavid du Colombier }
8253e12c5d1SDavid du Colombier /* state is new */
8263e12c5d1SDavid du Colombier if(nolook)
8273e12c5d1SDavid du Colombier error("yacc state/nolook error");
8283e12c5d1SDavid du Colombier pstate[nstate+2] = p2;
8293e12c5d1SDavid du Colombier if(nstate+1 >= NSTATES)
8303e12c5d1SDavid du Colombier error("too many states");
8313e12c5d1SDavid du Colombier if(c >= NTBASE) {
8323e12c5d1SDavid du Colombier mstates[nstate] = ntstates[c-NTBASE];
8333e12c5d1SDavid du Colombier ntstates[c-NTBASE] = nstate;
8343e12c5d1SDavid du Colombier } else {
8353e12c5d1SDavid du Colombier mstates[nstate] = tstates[c];
8363e12c5d1SDavid du Colombier tstates[c] = nstate;
8373e12c5d1SDavid du Colombier }
8383e12c5d1SDavid du Colombier tystate[nstate] = MUSTDO;
8393e12c5d1SDavid du Colombier return nstate++;
8403e12c5d1SDavid du Colombier }
8413e12c5d1SDavid du Colombier
8423e12c5d1SDavid du Colombier void
putitem(int * ptr,Lkset * lptr)8433e12c5d1SDavid du Colombier putitem(int *ptr, Lkset *lptr)
8443e12c5d1SDavid du Colombier {
8453e12c5d1SDavid du Colombier Item *j;
8463e12c5d1SDavid du Colombier
8473e12c5d1SDavid du Colombier if(pidebug && foutput != 0)
8483e12c5d1SDavid du Colombier Bprint(foutput, "putitem(%s), state %d\n", writem(ptr), nstate);
8493e12c5d1SDavid du Colombier j = pstate[nstate+1];
8503e12c5d1SDavid du Colombier j->pitem = ptr;
8513e12c5d1SDavid du Colombier if(!nolook)
8523e12c5d1SDavid du Colombier j->look = flset(lptr);
8533e12c5d1SDavid du Colombier pstate[nstate+1] = ++j;
8543e12c5d1SDavid du Colombier if((int*)j > zzmemsz) {
8553e12c5d1SDavid du Colombier zzmemsz = (int*)j;
8563e12c5d1SDavid du Colombier if(zzmemsz >= &mem0[MEMSIZE])
8573e12c5d1SDavid du Colombier error("out of state space");
8583e12c5d1SDavid du Colombier }
8593e12c5d1SDavid du Colombier }
8603e12c5d1SDavid du Colombier
8613e12c5d1SDavid du Colombier /*
8623e12c5d1SDavid du Colombier * mark nonterminals which derive the empty string
8633e12c5d1SDavid du Colombier * also, look for nonterminals which don't derive any token strings
8643e12c5d1SDavid du Colombier */
8653e12c5d1SDavid du Colombier void
cempty(void)8663e12c5d1SDavid du Colombier cempty(void)
8673e12c5d1SDavid du Colombier {
8683e12c5d1SDavid du Colombier
8693e12c5d1SDavid du Colombier int i, *p;
8703e12c5d1SDavid du Colombier
8713e12c5d1SDavid du Colombier /* first, use the array pempty to detect productions that can never be reduced */
8723e12c5d1SDavid du Colombier /* set pempty to WHONOWS */
8733e12c5d1SDavid du Colombier aryfil(pempty, nnonter+1, WHOKNOWS);
8743e12c5d1SDavid du Colombier
8753e12c5d1SDavid du Colombier /* now, look at productions, marking nonterminals which derive something */
8763e12c5d1SDavid du Colombier more:
8773e12c5d1SDavid du Colombier PLOOP(0, i) {
8783e12c5d1SDavid du Colombier if(pempty[*prdptr[i] - NTBASE])
8793e12c5d1SDavid du Colombier continue;
8803e12c5d1SDavid du Colombier for(p = prdptr[i]+1; *p >= 0; ++p)
8813e12c5d1SDavid du Colombier if(*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS)
8823e12c5d1SDavid du Colombier break;
8833e12c5d1SDavid du Colombier /* production can be derived */
8843e12c5d1SDavid du Colombier if(*p < 0) {
8853e12c5d1SDavid du Colombier pempty[*prdptr[i]-NTBASE] = OK;
8863e12c5d1SDavid du Colombier goto more;
8873e12c5d1SDavid du Colombier }
8883e12c5d1SDavid du Colombier }
8893e12c5d1SDavid du Colombier
8903e12c5d1SDavid du Colombier /* now, look at the nonterminals, to see if they are all OK */
8913e12c5d1SDavid du Colombier NTLOOP(i) {
8923e12c5d1SDavid du Colombier /* the added production rises or falls as the start symbol ... */
8933e12c5d1SDavid du Colombier if(i == 0)
8943e12c5d1SDavid du Colombier continue;
8953e12c5d1SDavid du Colombier if(pempty[i] != OK) {
8963e12c5d1SDavid du Colombier fatfl = 0;
8973e12c5d1SDavid du Colombier error("nonterminal %s never derives any token string", nontrst[i].name);
8983e12c5d1SDavid du Colombier }
8993e12c5d1SDavid du Colombier }
9003e12c5d1SDavid du Colombier
9013e12c5d1SDavid du Colombier if(nerrors) {
9023e12c5d1SDavid du Colombier summary();
9033e12c5d1SDavid du Colombier cleantmp();
9043e12c5d1SDavid du Colombier exits("error");
9053e12c5d1SDavid du Colombier }
9063e12c5d1SDavid du Colombier
9073e12c5d1SDavid du Colombier /* now, compute the pempty array, to see which nonterminals derive the empty string */
9083e12c5d1SDavid du Colombier /* set pempty to WHOKNOWS */
9093e12c5d1SDavid du Colombier aryfil( pempty, nnonter+1, WHOKNOWS);
9103e12c5d1SDavid du Colombier
9113e12c5d1SDavid du Colombier /* loop as long as we keep finding empty nonterminals */
9123e12c5d1SDavid du Colombier
9133e12c5d1SDavid du Colombier again:
9143e12c5d1SDavid du Colombier PLOOP(1, i) {
9153e12c5d1SDavid du Colombier /* not known to be empty */
9163e12c5d1SDavid du Colombier if(pempty[*prdptr[i]-NTBASE] == WHOKNOWS) {
9173e12c5d1SDavid du Colombier for(p = prdptr[i]+1; *p >= NTBASE && pempty[*p-NTBASE] == EMPTY ; ++p)
9183e12c5d1SDavid du Colombier ;
9193e12c5d1SDavid du Colombier /* we have a nontrivially empty nonterminal */
9203e12c5d1SDavid du Colombier if(*p < 0) {
9213e12c5d1SDavid du Colombier pempty[*prdptr[i]-NTBASE] = EMPTY;
9223e12c5d1SDavid du Colombier /* got one ... try for another */
9233e12c5d1SDavid du Colombier goto again;
9243e12c5d1SDavid du Colombier }
9253e12c5d1SDavid du Colombier }
9263e12c5d1SDavid du Colombier }
9273e12c5d1SDavid du Colombier }
9283e12c5d1SDavid du Colombier
9293e12c5d1SDavid du Colombier /*
9303e12c5d1SDavid du Colombier * generate the states
9313e12c5d1SDavid du Colombier */
9323e12c5d1SDavid du Colombier void
stagen(void)9333e12c5d1SDavid du Colombier stagen(void)
9343e12c5d1SDavid du Colombier {
9353e12c5d1SDavid du Colombier
9367dd7cddfSDavid du Colombier int c, i, j, more;
9373e12c5d1SDavid du Colombier Wset *p, *q;
9383e12c5d1SDavid du Colombier
9393e12c5d1SDavid du Colombier /* initialize */
9403e12c5d1SDavid du Colombier nstate = 0;
9413e12c5d1SDavid du Colombier
9423e12c5d1SDavid du Colombier /* THIS IS FUNNY from the standpoint of portability
9433e12c5d1SDavid du Colombier * it represents the magic moment when the mem0 array, which has
9443e12c5d1SDavid du Colombier * been holding the productions, starts to hold item pointers, of a
9453e12c5d1SDavid du Colombier * different type...
9463e12c5d1SDavid du Colombier * someday, alloc should be used to allocate all this stuff... for now, we
9473e12c5d1SDavid du Colombier * accept that if pointers don't fit in integers, there is a problem...
9483e12c5d1SDavid du Colombier */
9493e12c5d1SDavid du Colombier
9503e12c5d1SDavid du Colombier pstate[0] = pstate[1] = (Item*)mem;
9513e12c5d1SDavid du Colombier aryfil(clset.lset, tbitset, 0);
9523e12c5d1SDavid du Colombier putitem(prdptr[0]+1, &clset);
9533e12c5d1SDavid du Colombier tystate[0] = MUSTDO;
9543e12c5d1SDavid du Colombier nstate = 1;
9553e12c5d1SDavid du Colombier pstate[2] = pstate[1];
9563e12c5d1SDavid du Colombier
9573e12c5d1SDavid du Colombier aryfil(amem, ACTSIZE, 0);
9583e12c5d1SDavid du Colombier
9593e12c5d1SDavid du Colombier /* now, the main state generation loop */
9607dd7cddfSDavid du Colombier for(more=1; more;) {
9617dd7cddfSDavid du Colombier more = 0;
9623e12c5d1SDavid du Colombier SLOOP(i) {
9633e12c5d1SDavid du Colombier if(tystate[i] != MUSTDO)
9643e12c5d1SDavid du Colombier continue;
9653e12c5d1SDavid du Colombier tystate[i] = DONE;
9663e12c5d1SDavid du Colombier aryfil(temp1, nnonter+1, 0);
9673e12c5d1SDavid du Colombier /* take state i, close it, and do gotos */
9683e12c5d1SDavid du Colombier closure(i);
9693e12c5d1SDavid du Colombier /* generate goto's */
9703e12c5d1SDavid du Colombier WSLOOP(wsets, p) {
9713e12c5d1SDavid du Colombier if(p->flag)
9723e12c5d1SDavid du Colombier continue;
9733e12c5d1SDavid du Colombier p->flag = 1;
9743e12c5d1SDavid du Colombier c = *(p->pitem);
9753e12c5d1SDavid du Colombier if(c <= 1) {
9763e12c5d1SDavid du Colombier if(pstate[i+1]-pstate[i] <= p-wsets)
9773e12c5d1SDavid du Colombier tystate[i] = MUSTLOOKAHEAD;
9783e12c5d1SDavid du Colombier continue;
9793e12c5d1SDavid du Colombier }
9803e12c5d1SDavid du Colombier /* do a goto on c */
9813e12c5d1SDavid du Colombier WSLOOP(p, q)
9823e12c5d1SDavid du Colombier /* this item contributes to the goto */
9833e12c5d1SDavid du Colombier if(c == *(q->pitem)) {
9843e12c5d1SDavid du Colombier putitem(q->pitem+1, &q->ws);
9853e12c5d1SDavid du Colombier q->flag = 1;
9863e12c5d1SDavid du Colombier }
9873e12c5d1SDavid du Colombier if(c < NTBASE)
9883e12c5d1SDavid du Colombier state(c); /* register new state */
9893e12c5d1SDavid du Colombier else
9903e12c5d1SDavid du Colombier temp1[c-NTBASE] = state(c);
9913e12c5d1SDavid du Colombier }
9923e12c5d1SDavid du Colombier if(gsdebug && foutput != 0) {
9933e12c5d1SDavid du Colombier Bprint(foutput, "%d: ", i);
9943e12c5d1SDavid du Colombier NTLOOP(j)
9953e12c5d1SDavid du Colombier if(temp1[j])
9967dd7cddfSDavid du Colombier Bprint(foutput, "%s %d, ",
9977dd7cddfSDavid du Colombier nontrst[j].name, temp1[j]);
9983e12c5d1SDavid du Colombier Bprint(foutput, "\n");
9993e12c5d1SDavid du Colombier }
10003e12c5d1SDavid du Colombier indgo[i] = apack(&temp1[1], nnonter-1) - 1;
10017dd7cddfSDavid du Colombier /* do some more */
10027dd7cddfSDavid du Colombier more = 1;
10033e12c5d1SDavid du Colombier }
10047dd7cddfSDavid du Colombier }
10053e12c5d1SDavid du Colombier }
10063e12c5d1SDavid du Colombier
10073e12c5d1SDavid du Colombier /*
10083e12c5d1SDavid du Colombier * generate the closure of state i
10093e12c5d1SDavid du Colombier */
10103e12c5d1SDavid du Colombier void
closure(int i)10113e12c5d1SDavid du Colombier closure(int i)
10123e12c5d1SDavid du Colombier {
10133e12c5d1SDavid du Colombier
10143e12c5d1SDavid du Colombier Wset *u, *v;
10153e12c5d1SDavid du Colombier Item *p, *q;
10163e12c5d1SDavid du Colombier int c, ch, work, k, *pi, **s, **t;
10173e12c5d1SDavid du Colombier
10183e12c5d1SDavid du Colombier zzclose++;
10193e12c5d1SDavid du Colombier
10203e12c5d1SDavid du Colombier /* first, copy kernel of state i to wsets */
10213e12c5d1SDavid du Colombier cwp = wsets;
10223e12c5d1SDavid du Colombier ITMLOOP(i, p, q) {
10233e12c5d1SDavid du Colombier cwp->pitem = p->pitem;
10243e12c5d1SDavid du Colombier cwp->flag = 1; /* this item must get closed */
10253e12c5d1SDavid du Colombier SETLOOP(k)
10263e12c5d1SDavid du Colombier cwp->ws.lset[k] = p->look->lset[k];
10273e12c5d1SDavid du Colombier WSBUMP(cwp);
10283e12c5d1SDavid du Colombier }
10293e12c5d1SDavid du Colombier
10303e12c5d1SDavid du Colombier /* now, go through the loop, closing each item */
10313e12c5d1SDavid du Colombier work = 1;
10323e12c5d1SDavid du Colombier while(work) {
10333e12c5d1SDavid du Colombier work = 0;
10343e12c5d1SDavid du Colombier WSLOOP(wsets, u) {
10353e12c5d1SDavid du Colombier if(u->flag == 0)
10363e12c5d1SDavid du Colombier continue;
10373e12c5d1SDavid du Colombier /* dot is before c */
10383e12c5d1SDavid du Colombier c = *(u->pitem);
10393e12c5d1SDavid du Colombier if(c < NTBASE) {
10403e12c5d1SDavid du Colombier u->flag = 0;
10413e12c5d1SDavid du Colombier /* only interesting case is where . is before nonterminal */
10423e12c5d1SDavid du Colombier continue;
10433e12c5d1SDavid du Colombier }
10443e12c5d1SDavid du Colombier
10453e12c5d1SDavid du Colombier /* compute the lookahead */
10463e12c5d1SDavid du Colombier aryfil(clset.lset, tbitset, 0);
10473e12c5d1SDavid du Colombier
10483e12c5d1SDavid du Colombier /* find items involving c */
10493e12c5d1SDavid du Colombier WSLOOP(u, v)
10503e12c5d1SDavid du Colombier if(v->flag == 1 && *(pi=v->pitem) == c) {
10513e12c5d1SDavid du Colombier v->flag = 0;
10523e12c5d1SDavid du Colombier if(nolook)
10533e12c5d1SDavid du Colombier continue;
10543e12c5d1SDavid du Colombier while((ch = *++pi) > 0) {
10553e12c5d1SDavid du Colombier /* terminal symbol */
10563e12c5d1SDavid du Colombier if(ch < NTBASE) {
10573e12c5d1SDavid du Colombier SETBIT(clset.lset, ch);
10583e12c5d1SDavid du Colombier break;
10593e12c5d1SDavid du Colombier }
10603e12c5d1SDavid du Colombier /* nonterminal symbol */
10613e12c5d1SDavid du Colombier setunion(clset.lset, pfirst[ch-NTBASE]->lset);
10623e12c5d1SDavid du Colombier if(!pempty[ch-NTBASE])
10633e12c5d1SDavid du Colombier break;
10643e12c5d1SDavid du Colombier }
10653e12c5d1SDavid du Colombier if(ch <= 0)
10663e12c5d1SDavid du Colombier setunion(clset.lset, v->ws.lset);
10673e12c5d1SDavid du Colombier }
10683e12c5d1SDavid du Colombier
10693e12c5d1SDavid du Colombier /*
10703e12c5d1SDavid du Colombier * now loop over productions derived from c
10713e12c5d1SDavid du Colombier * c is now nonterminal number
10723e12c5d1SDavid du Colombier */
10733e12c5d1SDavid du Colombier c -= NTBASE;
10743e12c5d1SDavid du Colombier t = pres[c+1];
10753e12c5d1SDavid du Colombier for(s = pres[c]; s < t; ++s) {
10763e12c5d1SDavid du Colombier /*
10773e12c5d1SDavid du Colombier * put these items into the closure
10783e12c5d1SDavid du Colombier * is the item there
10793e12c5d1SDavid du Colombier */
10803e12c5d1SDavid du Colombier WSLOOP(wsets, v)
10813e12c5d1SDavid du Colombier /* yes, it is there */
10823e12c5d1SDavid du Colombier if(v->pitem == *s) {
10833e12c5d1SDavid du Colombier if(nolook)
10843e12c5d1SDavid du Colombier goto nexts;
10853e12c5d1SDavid du Colombier if(setunion(v->ws.lset, clset.lset))
10863e12c5d1SDavid du Colombier v->flag = work = 1;
10873e12c5d1SDavid du Colombier goto nexts;
10883e12c5d1SDavid du Colombier }
10893e12c5d1SDavid du Colombier
10903e12c5d1SDavid du Colombier /* not there; make a new entry */
10913e12c5d1SDavid du Colombier if(cwp-wsets+1 >= WSETSIZE)
10923e12c5d1SDavid du Colombier error( "working set overflow");
10933e12c5d1SDavid du Colombier cwp->pitem = *s;
10943e12c5d1SDavid du Colombier cwp->flag = 1;
10953e12c5d1SDavid du Colombier if(!nolook) {
10963e12c5d1SDavid du Colombier work = 1;
10973e12c5d1SDavid du Colombier SETLOOP(k) cwp->ws.lset[k] = clset.lset[k];
10983e12c5d1SDavid du Colombier }
10993e12c5d1SDavid du Colombier WSBUMP(cwp);
11003e12c5d1SDavid du Colombier
11013e12c5d1SDavid du Colombier nexts:;
11023e12c5d1SDavid du Colombier }
11033e12c5d1SDavid du Colombier }
11043e12c5d1SDavid du Colombier }
11053e12c5d1SDavid du Colombier
11063e12c5d1SDavid du Colombier /* have computed closure; flags are reset; return */
11073e12c5d1SDavid du Colombier if(cwp > zzcwp)
11083e12c5d1SDavid du Colombier zzcwp = cwp;
11093e12c5d1SDavid du Colombier if(cldebug && foutput != 0) {
11103e12c5d1SDavid du Colombier Bprint(foutput, "\nState %d, nolook = %d\n", i, nolook);
11113e12c5d1SDavid du Colombier WSLOOP(wsets, u) {
11123e12c5d1SDavid du Colombier if(u->flag)
11133e12c5d1SDavid du Colombier Bprint(foutput, "flag set!\n");
11143e12c5d1SDavid du Colombier u->flag = 0;
11153e12c5d1SDavid du Colombier Bprint(foutput, "\t%s", writem(u->pitem));
11163e12c5d1SDavid du Colombier prlook(&u->ws);
11173e12c5d1SDavid du Colombier Bprint(foutput, "\n");
11183e12c5d1SDavid du Colombier }
11193e12c5d1SDavid du Colombier }
11203e12c5d1SDavid du Colombier }
11213e12c5d1SDavid du Colombier
11223e12c5d1SDavid du Colombier /*
11233e12c5d1SDavid du Colombier * decide if the lookahead set pointed to by p is known
11243e12c5d1SDavid du Colombier * return pointer to a perminent location for the set
11253e12c5d1SDavid du Colombier */
11263e12c5d1SDavid du Colombier Lkset*
flset(Lkset * p)11273e12c5d1SDavid du Colombier flset(Lkset *p)
11283e12c5d1SDavid du Colombier {
11293e12c5d1SDavid du Colombier Lkset *q;
11303e12c5d1SDavid du Colombier int *u, *v, *w, j;
11313e12c5d1SDavid du Colombier
11323e12c5d1SDavid du Colombier for(q = &lkst[nlset]; q-- > lkst;) {
11333e12c5d1SDavid du Colombier u = p->lset;
11343e12c5d1SDavid du Colombier v = q->lset;
11353e12c5d1SDavid du Colombier w = &v[tbitset];
11363e12c5d1SDavid du Colombier while(v < w)
11373e12c5d1SDavid du Colombier if(*u++ != *v++)
11383e12c5d1SDavid du Colombier goto more;
11393e12c5d1SDavid du Colombier /* we have matched */
11403e12c5d1SDavid du Colombier return q;
11413e12c5d1SDavid du Colombier more:;
11423e12c5d1SDavid du Colombier }
11433e12c5d1SDavid du Colombier /* add a new one */
11443e12c5d1SDavid du Colombier q = &lkst[nlset++];
11453e12c5d1SDavid du Colombier if(nlset >= LSETSIZE)
11463e12c5d1SDavid du Colombier error("too many lookahead sets");
11473e12c5d1SDavid du Colombier SETLOOP(j)
11483e12c5d1SDavid du Colombier q->lset[j] = p->lset[j];
11493e12c5d1SDavid du Colombier return q;
11503e12c5d1SDavid du Colombier }
11513e12c5d1SDavid du Colombier
11523e12c5d1SDavid du Colombier void
cleantmp(void)11533e12c5d1SDavid du Colombier cleantmp(void)
11543e12c5d1SDavid du Colombier {
11553e12c5d1SDavid du Colombier ZAPFILE(actname);
11563e12c5d1SDavid du Colombier ZAPFILE(tempname);
11573e12c5d1SDavid du Colombier }
11583e12c5d1SDavid du Colombier
11593e12c5d1SDavid du Colombier void
intr(void)11603e12c5d1SDavid du Colombier intr(void)
11613e12c5d1SDavid du Colombier {
11623e12c5d1SDavid du Colombier cleantmp();
11633e12c5d1SDavid du Colombier exits("interrupted");
11643e12c5d1SDavid du Colombier }
11653e12c5d1SDavid du Colombier
11663e12c5d1SDavid du Colombier void
usage(void)1167de8abbc9SDavid du Colombier usage(void)
1168de8abbc9SDavid du Colombier {
1169de8abbc9SDavid du Colombier fprint(2, "usage: yacc [-Dn] [-vdS] [-o outputfile] [-s stem] grammar\n");
1170de8abbc9SDavid du Colombier exits("usage");
1171de8abbc9SDavid du Colombier }
1172de8abbc9SDavid du Colombier
1173de8abbc9SDavid du Colombier void
setup(int argc,char * argv[])11743e12c5d1SDavid du Colombier setup(int argc, char *argv[])
11753e12c5d1SDavid du Colombier {
11763e12c5d1SDavid du Colombier long c, t;
11773e12c5d1SDavid du Colombier int i, j, lev, ty, ytab, *p;
11783e12c5d1SDavid du Colombier int vflag, dflag, stem;
11797dd7cddfSDavid du Colombier char actnm[8], *stemc, *s, dirbuf[128];
11803e12c5d1SDavid du Colombier
11813e12c5d1SDavid du Colombier ytab = 0;
11823e12c5d1SDavid du Colombier vflag = 0;
11833e12c5d1SDavid du Colombier dflag = 0;
11843e12c5d1SDavid du Colombier stem = 0;
11853e12c5d1SDavid du Colombier stemc = "y";
11863e12c5d1SDavid du Colombier foutput = 0;
11873e12c5d1SDavid du Colombier fdefine = 0;
11883e12c5d1SDavid du Colombier fdebug = 0;
11893e12c5d1SDavid du Colombier ARGBEGIN{
11903e12c5d1SDavid du Colombier case 'v':
11913e12c5d1SDavid du Colombier case 'V':
11923e12c5d1SDavid du Colombier vflag++;
11933e12c5d1SDavid du Colombier break;
11943e12c5d1SDavid du Colombier case 'D':
1195de8abbc9SDavid du Colombier yydebug = EARGF(usage());
11963e12c5d1SDavid du Colombier break;
11973e12c5d1SDavid du Colombier case 'd':
11983e12c5d1SDavid du Colombier dflag++;
11993e12c5d1SDavid du Colombier break;
12003e12c5d1SDavid du Colombier case 'o':
12013e12c5d1SDavid du Colombier ytab++;
1202de8abbc9SDavid du Colombier ytabc = EARGF(usage());
12033e12c5d1SDavid du Colombier break;
12043e12c5d1SDavid du Colombier case 's':
12053e12c5d1SDavid du Colombier stem++;
12063e12c5d1SDavid du Colombier stemc = ARGF();
12073e12c5d1SDavid du Colombier break;
12083e12c5d1SDavid du Colombier case 'S':
12093e12c5d1SDavid du Colombier parser = PARSERS;
12103e12c5d1SDavid du Colombier break;
12113e12c5d1SDavid du Colombier default:
12123e12c5d1SDavid du Colombier error("illegal option: %c", ARGC());
12133e12c5d1SDavid du Colombier }ARGEND
12143e12c5d1SDavid du Colombier openup(stemc, dflag, vflag, ytab, ytabc);
12153e12c5d1SDavid du Colombier
12163e12c5d1SDavid du Colombier ftemp = Bopen(tempname = mktemp(ttempname), OWRITE);
12173e12c5d1SDavid du Colombier faction = Bopen(actname = mktemp(tactname), OWRITE);
12183e12c5d1SDavid du Colombier if(ftemp == 0 || faction == 0)
12193e12c5d1SDavid du Colombier error("cannot open temp file");
12203e12c5d1SDavid du Colombier if(argc < 1)
12213e12c5d1SDavid du Colombier error("no input file");
12223e12c5d1SDavid du Colombier infile = argv[0];
12237dd7cddfSDavid du Colombier if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
122459cc4ca5SDavid du Colombier i = strlen(infile)+1+strlen(dirbuf)+1+10;
12257dd7cddfSDavid du Colombier s = malloc(i);
12267dd7cddfSDavid du Colombier if(s != nil){
12277dd7cddfSDavid du Colombier snprint(s, i, "%s/%s", dirbuf, infile);
12287dd7cddfSDavid du Colombier cleanname(s);
12297dd7cddfSDavid du Colombier infile = s;
12307dd7cddfSDavid du Colombier }
12317dd7cddfSDavid du Colombier }
12323e12c5d1SDavid du Colombier finput = Bopen(infile, OREAD);
12333e12c5d1SDavid du Colombier if(finput == 0)
12343e12c5d1SDavid du Colombier error("cannot open '%s'", argv[0]);
12353e12c5d1SDavid du Colombier cnamp = cnames;
12363e12c5d1SDavid du Colombier
12373e12c5d1SDavid du Colombier defin(0, "$end");
12383e12c5d1SDavid du Colombier extval = PRIVATE; /* tokens start in unicode 'private use' */
12393e12c5d1SDavid du Colombier defin(0, "error");
12403e12c5d1SDavid du Colombier defin(1, "$accept");
12413e12c5d1SDavid du Colombier defin(0, "$unk");
12423e12c5d1SDavid du Colombier mem = mem0;
12433e12c5d1SDavid du Colombier i = 0;
12443e12c5d1SDavid du Colombier
12453e12c5d1SDavid du Colombier for(t = gettok(); t != MARK && t != ENDFILE;)
12463e12c5d1SDavid du Colombier switch(t) {
12473e12c5d1SDavid du Colombier case ';':
12483e12c5d1SDavid du Colombier t = gettok();
12493e12c5d1SDavid du Colombier break;
12503e12c5d1SDavid du Colombier
12513e12c5d1SDavid du Colombier case START:
12523e12c5d1SDavid du Colombier if(gettok() != IDENTIFIER)
12533e12c5d1SDavid du Colombier error("bad %%start construction");
12543e12c5d1SDavid du Colombier start = chfind(1, tokname);
12553e12c5d1SDavid du Colombier t = gettok();
12563e12c5d1SDavid du Colombier continue;
12573e12c5d1SDavid du Colombier
12583e12c5d1SDavid du Colombier case TYPEDEF:
12593e12c5d1SDavid du Colombier if(gettok() != TYPENAME)
12603e12c5d1SDavid du Colombier error("bad syntax in %%type");
12613e12c5d1SDavid du Colombier ty = numbval;
12623e12c5d1SDavid du Colombier for(;;) {
12633e12c5d1SDavid du Colombier t = gettok();
12643e12c5d1SDavid du Colombier switch(t) {
12653e12c5d1SDavid du Colombier case IDENTIFIER:
12663e12c5d1SDavid du Colombier if((t=chfind(1, tokname)) < NTBASE) {
12673e12c5d1SDavid du Colombier j = TYPE(toklev[t]);
12683e12c5d1SDavid du Colombier if(j != 0 && j != ty)
12693e12c5d1SDavid du Colombier error("type redeclaration of token %s",
12703e12c5d1SDavid du Colombier tokset[t].name);
12713e12c5d1SDavid du Colombier else
12723e12c5d1SDavid du Colombier SETTYPE(toklev[t], ty);
12733e12c5d1SDavid du Colombier } else {
12743e12c5d1SDavid du Colombier j = nontrst[t-NTBASE].value;
12753e12c5d1SDavid du Colombier if(j != 0 && j != ty)
12763e12c5d1SDavid du Colombier error("type redeclaration of nonterminal %s",
12773e12c5d1SDavid du Colombier nontrst[t-NTBASE].name );
12783e12c5d1SDavid du Colombier else
12793e12c5d1SDavid du Colombier nontrst[t-NTBASE].value = ty;
12803e12c5d1SDavid du Colombier }
12813e12c5d1SDavid du Colombier case ',':
12823e12c5d1SDavid du Colombier continue;
12833e12c5d1SDavid du Colombier case ';':
12843e12c5d1SDavid du Colombier t = gettok();
12853e12c5d1SDavid du Colombier default:
12863e12c5d1SDavid du Colombier break;
12873e12c5d1SDavid du Colombier }
12883e12c5d1SDavid du Colombier break;
12893e12c5d1SDavid du Colombier }
12903e12c5d1SDavid du Colombier continue;
12913e12c5d1SDavid du Colombier
12923e12c5d1SDavid du Colombier case UNION:
12933e12c5d1SDavid du Colombier /* copy the union declaration to the output */
12943e12c5d1SDavid du Colombier cpyunion();
12953e12c5d1SDavid du Colombier t = gettok();
12963e12c5d1SDavid du Colombier continue;
12973e12c5d1SDavid du Colombier
12983e12c5d1SDavid du Colombier case LEFT:
12993e12c5d1SDavid du Colombier case BINARY:
13003e12c5d1SDavid du Colombier case RIGHT:
13013e12c5d1SDavid du Colombier i++;
13023e12c5d1SDavid du Colombier
13033e12c5d1SDavid du Colombier case TERM:
13043e12c5d1SDavid du Colombier /* nonzero means new prec. and assoc. */
13053e12c5d1SDavid du Colombier lev = t-TERM;
13063e12c5d1SDavid du Colombier ty = 0;
13073e12c5d1SDavid du Colombier
13083e12c5d1SDavid du Colombier /* get identifiers so defined */
13093e12c5d1SDavid du Colombier t = gettok();
13103e12c5d1SDavid du Colombier
13113e12c5d1SDavid du Colombier /* there is a type defined */
13123e12c5d1SDavid du Colombier if(t == TYPENAME) {
13133e12c5d1SDavid du Colombier ty = numbval;
13143e12c5d1SDavid du Colombier t = gettok();
13153e12c5d1SDavid du Colombier }
13163e12c5d1SDavid du Colombier for(;;) {
13173e12c5d1SDavid du Colombier switch(t) {
13183e12c5d1SDavid du Colombier case ',':
13193e12c5d1SDavid du Colombier t = gettok();
13203e12c5d1SDavid du Colombier continue;
13213e12c5d1SDavid du Colombier
13223e12c5d1SDavid du Colombier case ';':
13233e12c5d1SDavid du Colombier break;
13243e12c5d1SDavid du Colombier
13253e12c5d1SDavid du Colombier case IDENTIFIER:
13263e12c5d1SDavid du Colombier j = chfind(0, tokname);
13273e12c5d1SDavid du Colombier if(j >= NTBASE)
13283e12c5d1SDavid du Colombier error("%s defined earlier as nonterminal", tokname);
13293e12c5d1SDavid du Colombier if(lev) {
13303e12c5d1SDavid du Colombier if(ASSOC(toklev[j]))
13313e12c5d1SDavid du Colombier error("redeclaration of precedence of %s", tokname);
13323e12c5d1SDavid du Colombier SETASC(toklev[j], lev);
13333e12c5d1SDavid du Colombier SETPLEV(toklev[j], i);
13343e12c5d1SDavid du Colombier }
13353e12c5d1SDavid du Colombier if(ty) {
13363e12c5d1SDavid du Colombier if(TYPE(toklev[j]))
13373e12c5d1SDavid du Colombier error("redeclaration of type of %s", tokname);
13383e12c5d1SDavid du Colombier SETTYPE(toklev[j],ty);
13393e12c5d1SDavid du Colombier }
13403e12c5d1SDavid du Colombier t = gettok();
13413e12c5d1SDavid du Colombier if(t == NUMBER) {
13423e12c5d1SDavid du Colombier tokset[j].value = numbval;
13433e12c5d1SDavid du Colombier if(j < ndefout && j > 3)
13443e12c5d1SDavid du Colombier error("please define type number of %s earlier",
13453e12c5d1SDavid du Colombier tokset[j].name);
13463e12c5d1SDavid du Colombier t = gettok();
13473e12c5d1SDavid du Colombier }
13483e12c5d1SDavid du Colombier continue;
13493e12c5d1SDavid du Colombier }
13503e12c5d1SDavid du Colombier break;
13513e12c5d1SDavid du Colombier }
13523e12c5d1SDavid du Colombier continue;
13533e12c5d1SDavid du Colombier
13543e12c5d1SDavid du Colombier case LCURLY:
13553e12c5d1SDavid du Colombier defout(0);
13563e12c5d1SDavid du Colombier cpycode();
13573e12c5d1SDavid du Colombier t = gettok();
13583e12c5d1SDavid du Colombier continue;
13593e12c5d1SDavid du Colombier
13603e12c5d1SDavid du Colombier default:
13613e12c5d1SDavid du Colombier error("syntax error");
13623e12c5d1SDavid du Colombier }
13633e12c5d1SDavid du Colombier if(t == ENDFILE)
13643e12c5d1SDavid du Colombier error("unexpected EOF before %%");
13653e12c5d1SDavid du Colombier
13663e12c5d1SDavid du Colombier /* t is MARK */
13673e12c5d1SDavid du Colombier Bprint(ftable, "extern int yyerrflag;\n");
13683e12c5d1SDavid du Colombier Bprint(ftable, "#ifndef YYMAXDEPTH\n");
13693e12c5d1SDavid du Colombier Bprint(ftable, "#define YYMAXDEPTH 150\n");
13703e12c5d1SDavid du Colombier Bprint(ftable, "#endif\n" );
13713e12c5d1SDavid du Colombier if(!ntypes) {
13723e12c5d1SDavid du Colombier Bprint(ftable, "#ifndef YYSTYPE\n");
13733e12c5d1SDavid du Colombier Bprint(ftable, "#define YYSTYPE int\n");
13743e12c5d1SDavid du Colombier Bprint(ftable, "#endif\n");
13753e12c5d1SDavid du Colombier }
13763e12c5d1SDavid du Colombier Bprint(ftable, "YYSTYPE yylval;\n");
13773e12c5d1SDavid du Colombier Bprint(ftable, "YYSTYPE yyval;\n");
13783e12c5d1SDavid du Colombier
13793e12c5d1SDavid du Colombier prdptr[0] = mem;
13803e12c5d1SDavid du Colombier
13813e12c5d1SDavid du Colombier /* added production */
13823e12c5d1SDavid du Colombier *mem++ = NTBASE;
13833e12c5d1SDavid du Colombier
13843e12c5d1SDavid du Colombier /* if start is 0, we will overwrite with the lhs of the first rule */
13853e12c5d1SDavid du Colombier *mem++ = start;
13863e12c5d1SDavid du Colombier *mem++ = 1;
13873e12c5d1SDavid du Colombier *mem++ = 0;
13883e12c5d1SDavid du Colombier prdptr[1] = mem;
13893e12c5d1SDavid du Colombier while((t=gettok()) == LCURLY)
13903e12c5d1SDavid du Colombier cpycode();
13913e12c5d1SDavid du Colombier if(t != IDENTCOLON)
13923e12c5d1SDavid du Colombier error("bad syntax on first rule");
13933e12c5d1SDavid du Colombier
13943e12c5d1SDavid du Colombier if(!start)
13953e12c5d1SDavid du Colombier prdptr[0][1] = chfind(1, tokname);
13963e12c5d1SDavid du Colombier
13973e12c5d1SDavid du Colombier /* read rules */
13983e12c5d1SDavid du Colombier while(t != MARK && t != ENDFILE) {
13993e12c5d1SDavid du Colombier /* process a rule */
14003e12c5d1SDavid du Colombier rlines[nprod] = lineno;
14013e12c5d1SDavid du Colombier if(t == '|')
14023e12c5d1SDavid du Colombier *mem++ = *prdptr[nprod-1];
14033e12c5d1SDavid du Colombier else
14043e12c5d1SDavid du Colombier if(t == IDENTCOLON) {
14053e12c5d1SDavid du Colombier *mem = chfind(1, tokname);
14063e12c5d1SDavid du Colombier if(*mem < NTBASE)
14073e12c5d1SDavid du Colombier error("token illegal on LHS of grammar rule");
14083e12c5d1SDavid du Colombier mem++;
14093e12c5d1SDavid du Colombier } else
14103e12c5d1SDavid du Colombier error("illegal rule: missing semicolon or | ?");
14113e12c5d1SDavid du Colombier /* read rule body */
14123e12c5d1SDavid du Colombier t = gettok();
14133e12c5d1SDavid du Colombier
14143e12c5d1SDavid du Colombier more_rule:
14153e12c5d1SDavid du Colombier while(t == IDENTIFIER) {
14163e12c5d1SDavid du Colombier *mem = chfind(1, tokname);
14173e12c5d1SDavid du Colombier if(*mem < NTBASE)
14183e12c5d1SDavid du Colombier levprd[nprod] = toklev[*mem];
14193e12c5d1SDavid du Colombier mem++;
14203e12c5d1SDavid du Colombier t = gettok();
14213e12c5d1SDavid du Colombier }
14223e12c5d1SDavid du Colombier if(t == PREC) {
14233e12c5d1SDavid du Colombier if(gettok() != IDENTIFIER)
14243e12c5d1SDavid du Colombier error("illegal %%prec syntax");
14253e12c5d1SDavid du Colombier j = chfind(2, tokname);
14263e12c5d1SDavid du Colombier if(j >= NTBASE)
14273e12c5d1SDavid du Colombier error("nonterminal %s illegal after %%prec",
14283e12c5d1SDavid du Colombier nontrst[j-NTBASE].name);
14293e12c5d1SDavid du Colombier levprd[nprod] = toklev[j];
14303e12c5d1SDavid du Colombier t = gettok();
14313e12c5d1SDavid du Colombier }
14323e12c5d1SDavid du Colombier if(t == '=') {
14333e12c5d1SDavid du Colombier levprd[nprod] |= ACTFLAG;
14343e12c5d1SDavid du Colombier Bprint(faction, "\ncase %d:", nprod);
14353e12c5d1SDavid du Colombier cpyact(mem-prdptr[nprod]-1);
14363e12c5d1SDavid du Colombier Bprint(faction, " break;");
14373e12c5d1SDavid du Colombier if((t=gettok()) == IDENTIFIER) {
14383e12c5d1SDavid du Colombier
14393e12c5d1SDavid du Colombier /* action within rule... */
14403e12c5d1SDavid du Colombier sprint(actnm, "$$%d", nprod);
14413e12c5d1SDavid du Colombier
14423e12c5d1SDavid du Colombier /* make it a nonterminal */
14433e12c5d1SDavid du Colombier j = chfind(1, actnm);
14443e12c5d1SDavid du Colombier
14453e12c5d1SDavid du Colombier /*
14463e12c5d1SDavid du Colombier * the current rule will become rule number nprod+1
14473e12c5d1SDavid du Colombier * move the contents down, and make room for the null
14483e12c5d1SDavid du Colombier */
14493e12c5d1SDavid du Colombier for(p = mem; p >= prdptr[nprod]; --p)
14503e12c5d1SDavid du Colombier p[2] = *p;
14513e12c5d1SDavid du Colombier mem += 2;
14523e12c5d1SDavid du Colombier
14533e12c5d1SDavid du Colombier /* enter null production for action */
14543e12c5d1SDavid du Colombier p = prdptr[nprod];
14553e12c5d1SDavid du Colombier *p++ = j;
14563e12c5d1SDavid du Colombier *p++ = -nprod;
14573e12c5d1SDavid du Colombier
14583e12c5d1SDavid du Colombier /* update the production information */
14593e12c5d1SDavid du Colombier levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
14603e12c5d1SDavid du Colombier levprd[nprod] = ACTFLAG;
14613e12c5d1SDavid du Colombier if(++nprod >= NPROD)
14623e12c5d1SDavid du Colombier error("more than %d rules", NPROD);
14633e12c5d1SDavid du Colombier prdptr[nprod] = p;
14643e12c5d1SDavid du Colombier
14653e12c5d1SDavid du Colombier /* make the action appear in the original rule */
14663e12c5d1SDavid du Colombier *mem++ = j;
14673e12c5d1SDavid du Colombier
14683e12c5d1SDavid du Colombier /* get some more of the rule */
14693e12c5d1SDavid du Colombier goto more_rule;
14703e12c5d1SDavid du Colombier }
14713e12c5d1SDavid du Colombier }
14723e12c5d1SDavid du Colombier
14733e12c5d1SDavid du Colombier while(t == ';')
14743e12c5d1SDavid du Colombier t = gettok();
14753e12c5d1SDavid du Colombier *mem++ = -nprod;
14763e12c5d1SDavid du Colombier
14773e12c5d1SDavid du Colombier /* check that default action is reasonable */
14783e12c5d1SDavid du Colombier if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
14793e12c5d1SDavid du Colombier
14803e12c5d1SDavid du Colombier /* no explicit action, LHS has value */
14813e12c5d1SDavid du Colombier int tempty;
14823e12c5d1SDavid du Colombier
14833e12c5d1SDavid du Colombier tempty = prdptr[nprod][1];
14843e12c5d1SDavid du Colombier if(tempty < 0)
14853e12c5d1SDavid du Colombier error("must return a value, since LHS has a type");
14863e12c5d1SDavid du Colombier else
14873e12c5d1SDavid du Colombier if(tempty >= NTBASE)
14883e12c5d1SDavid du Colombier tempty = nontrst[tempty-NTBASE].value;
14893e12c5d1SDavid du Colombier else
14903e12c5d1SDavid du Colombier tempty = TYPE(toklev[tempty]);
14913e12c5d1SDavid du Colombier if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
14923e12c5d1SDavid du Colombier error("default action causes potential type clash");
14933e12c5d1SDavid du Colombier }
14943e12c5d1SDavid du Colombier nprod++;
14953e12c5d1SDavid du Colombier if(nprod >= NPROD)
14963e12c5d1SDavid du Colombier error("more than %d rules", NPROD);
14973e12c5d1SDavid du Colombier prdptr[nprod] = mem;
14983e12c5d1SDavid du Colombier levprd[nprod] = 0;
14993e12c5d1SDavid du Colombier }
15003e12c5d1SDavid du Colombier
15013e12c5d1SDavid du Colombier /* end of all rules */
15023e12c5d1SDavid du Colombier defout(1);
15033e12c5d1SDavid du Colombier
15043e12c5d1SDavid du Colombier finact();
15053e12c5d1SDavid du Colombier if(t == MARK) {
15063e12c5d1SDavid du Colombier Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
15073e12c5d1SDavid du Colombier while((c=Bgetrune(finput)) != Beof)
15083e12c5d1SDavid du Colombier Bputrune(ftable, c);
15093e12c5d1SDavid du Colombier }
1510219b2ee8SDavid du Colombier Bterm(finput);
15113e12c5d1SDavid du Colombier }
15123e12c5d1SDavid du Colombier
15133e12c5d1SDavid du Colombier /*
15143e12c5d1SDavid du Colombier * finish action routine
15153e12c5d1SDavid du Colombier */
15163e12c5d1SDavid du Colombier void
finact(void)15173e12c5d1SDavid du Colombier finact(void)
15183e12c5d1SDavid du Colombier {
15193e12c5d1SDavid du Colombier
1520219b2ee8SDavid du Colombier Bterm(faction);
1521bd389b36SDavid du Colombier Bprint(ftable, "#define YYEOFCODE %d\n", 1);
1522bd389b36SDavid du Colombier Bprint(ftable, "#define YYERRCODE %d\n", 2);
15233e12c5d1SDavid du Colombier }
15243e12c5d1SDavid du Colombier
15253e12c5d1SDavid du Colombier /*
15263e12c5d1SDavid du Colombier * define s to be a terminal if t=0
15273e12c5d1SDavid du Colombier * or a nonterminal if t=1
15283e12c5d1SDavid du Colombier */
15293e12c5d1SDavid du Colombier int
defin(int nt,char * s)15303e12c5d1SDavid du Colombier defin(int nt, char *s)
15313e12c5d1SDavid du Colombier {
15323e12c5d1SDavid du Colombier int val;
15333e12c5d1SDavid du Colombier Rune rune;
15343e12c5d1SDavid du Colombier
15353e12c5d1SDavid du Colombier val = 0;
15363e12c5d1SDavid du Colombier if(nt) {
15373e12c5d1SDavid du Colombier nnonter++;
15383e12c5d1SDavid du Colombier if(nnonter >= NNONTERM)
15393e12c5d1SDavid du Colombier error("too many nonterminals, limit %d",NNONTERM);
15403e12c5d1SDavid du Colombier nontrst[nnonter].name = cstash(s);
15413e12c5d1SDavid du Colombier return NTBASE + nnonter;
15423e12c5d1SDavid du Colombier }
15433e12c5d1SDavid du Colombier
15443e12c5d1SDavid du Colombier /* must be a token */
15453e12c5d1SDavid du Colombier ntokens++;
15463e12c5d1SDavid du Colombier if(ntokens >= NTERMS)
15473e12c5d1SDavid du Colombier error("too many terminals, limit %d", NTERMS);
15483e12c5d1SDavid du Colombier tokset[ntokens].name = cstash(s);
15493e12c5d1SDavid du Colombier
15503e12c5d1SDavid du Colombier /* establish value for token */
15513e12c5d1SDavid du Colombier /* single character literal */
15523e12c5d1SDavid du Colombier if(s[0] == ' ') {
15533e12c5d1SDavid du Colombier val = chartorune(&rune, &s[1]);
15543e12c5d1SDavid du Colombier if(s[val+1] == 0) {
15553e12c5d1SDavid du Colombier val = rune;
15563e12c5d1SDavid du Colombier goto out;
15573e12c5d1SDavid du Colombier }
15583e12c5d1SDavid du Colombier }
15593e12c5d1SDavid du Colombier
15603e12c5d1SDavid du Colombier /* escape sequence */
1561bd389b36SDavid du Colombier if(s[0] == ' ' && s[1] == '\\') {
1562bd389b36SDavid du Colombier if(s[3] == 0) {
15633e12c5d1SDavid du Colombier /* single character escape sequence */
15643e12c5d1SDavid du Colombier switch(s[2]) {
15653e12c5d1SDavid du Colombier case 'n': val = '\n'; break;
15663e12c5d1SDavid du Colombier case 'r': val = '\r'; break;
15673e12c5d1SDavid du Colombier case 'b': val = '\b'; break;
15683e12c5d1SDavid du Colombier case 't': val = '\t'; break;
15693e12c5d1SDavid du Colombier case 'f': val = '\f'; break;
15703e12c5d1SDavid du Colombier case '\'': val = '\''; break;
15713e12c5d1SDavid du Colombier case '"': val = '"'; break;
15723e12c5d1SDavid du Colombier case '\\': val = '\\'; break;
15733e12c5d1SDavid du Colombier default: error("invalid escape");
15743e12c5d1SDavid du Colombier }
15753e12c5d1SDavid du Colombier goto out;
15763e12c5d1SDavid du Colombier }
15773e12c5d1SDavid du Colombier
15783e12c5d1SDavid du Colombier /* \nnn sequence */
15793e12c5d1SDavid du Colombier if(s[2] >= '0' && s[2] <= '7') {
15803e12c5d1SDavid du Colombier if(s[3] < '0' ||
15813e12c5d1SDavid du Colombier s[3] > '7' ||
15823e12c5d1SDavid du Colombier s[4] < '0' ||
15833e12c5d1SDavid du Colombier s[4] > '7' ||
15843e12c5d1SDavid du Colombier s[5] != 0)
15853e12c5d1SDavid du Colombier error("illegal \\nnn construction");
15863e12c5d1SDavid du Colombier val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
15873e12c5d1SDavid du Colombier if(val == 0)
15883e12c5d1SDavid du Colombier error("'\\000' is illegal");
15893e12c5d1SDavid du Colombier goto out;
15903e12c5d1SDavid du Colombier }
1591bd389b36SDavid du Colombier error("unknown escape");
1592bd389b36SDavid du Colombier }
15933e12c5d1SDavid du Colombier val = extval++;
15943e12c5d1SDavid du Colombier
15953e12c5d1SDavid du Colombier out:
15963e12c5d1SDavid du Colombier tokset[ntokens].value = val;
15973e12c5d1SDavid du Colombier toklev[ntokens] = 0;
15983e12c5d1SDavid du Colombier return ntokens;
15993e12c5d1SDavid du Colombier }
16003e12c5d1SDavid du Colombier
16013e12c5d1SDavid du Colombier /*
16023e12c5d1SDavid du Colombier * write out the defines (at the end of the declaration section)
16033e12c5d1SDavid du Colombier */
16043e12c5d1SDavid du Colombier void
defout(int last)16053e12c5d1SDavid du Colombier defout(int last)
16063e12c5d1SDavid du Colombier {
16073e12c5d1SDavid du Colombier int i, c;
16083e12c5d1SDavid du Colombier char sar[NAMESIZE+10];
16093e12c5d1SDavid du Colombier
16103e12c5d1SDavid du Colombier for(i=ndefout; i<=ntokens; i++) {
16113e12c5d1SDavid du Colombier /* non-literals */
16123e12c5d1SDavid du Colombier c = tokset[i].name[0];
16133e12c5d1SDavid du Colombier if(c != ' ' && c != '$') {
16143e12c5d1SDavid du Colombier Bprint(ftable, "#define %s %d\n",
16153e12c5d1SDavid du Colombier tokset[i].name, tokset[i].value);
16163e12c5d1SDavid du Colombier if(fdefine)
16173e12c5d1SDavid du Colombier Bprint(fdefine, "#define\t%s\t%d\n",
16183e12c5d1SDavid du Colombier tokset[i].name, tokset[i].value);
16193e12c5d1SDavid du Colombier }
16203e12c5d1SDavid du Colombier }
16213e12c5d1SDavid du Colombier ndefout = ntokens+1;
16223e12c5d1SDavid du Colombier if(last && fdebug) {
16233e12c5d1SDavid du Colombier Bprint(fdebug, "char* yytoknames[] =\n{\n");
16243e12c5d1SDavid du Colombier TLOOP(i) {
16253e12c5d1SDavid du Colombier if(tokset[i].name) {
16263e12c5d1SDavid du Colombier chcopy(sar, tokset[i].name);
16273e12c5d1SDavid du Colombier Bprint(fdebug, "\t\"%s\",\n", sar);
16283e12c5d1SDavid du Colombier continue;
16293e12c5d1SDavid du Colombier }
16303e12c5d1SDavid du Colombier Bprint(fdebug, "\t0,\n");
16313e12c5d1SDavid du Colombier }
16323e12c5d1SDavid du Colombier Bprint(fdebug, "};\n");
16333e12c5d1SDavid du Colombier }
16343e12c5d1SDavid du Colombier }
16353e12c5d1SDavid du Colombier
16363e12c5d1SDavid du Colombier char*
cstash(char * s)16373e12c5d1SDavid du Colombier cstash(char *s)
16383e12c5d1SDavid du Colombier {
16393e12c5d1SDavid du Colombier char *temp;
16403e12c5d1SDavid du Colombier
16413e12c5d1SDavid du Colombier temp = cnamp;
16423e12c5d1SDavid du Colombier do {
16433e12c5d1SDavid du Colombier if(cnamp >= &cnames[cnamsz])
16443e12c5d1SDavid du Colombier error("too many characters in id's and literals");
16453e12c5d1SDavid du Colombier else
16463e12c5d1SDavid du Colombier *cnamp++ = *s;
16473e12c5d1SDavid du Colombier } while(*s++);
16483e12c5d1SDavid du Colombier return temp;
16493e12c5d1SDavid du Colombier }
16503e12c5d1SDavid du Colombier
16513e12c5d1SDavid du Colombier long
gettok(void)16523e12c5d1SDavid du Colombier gettok(void)
16533e12c5d1SDavid du Colombier {
16543e12c5d1SDavid du Colombier long c;
16553e12c5d1SDavid du Colombier Rune rune;
16563e12c5d1SDavid du Colombier int i, base, match, reserve;
16573e12c5d1SDavid du Colombier static int peekline;
16583e12c5d1SDavid du Colombier
16593e12c5d1SDavid du Colombier begin:
16603e12c5d1SDavid du Colombier reserve = 0;
16613e12c5d1SDavid du Colombier lineno += peekline;
16623e12c5d1SDavid du Colombier peekline = 0;
16633e12c5d1SDavid du Colombier c = Bgetrune(finput);
16643e12c5d1SDavid du Colombier while(c == ' ' || c == '\n' || c == '\t' || c == '\f') {
16653e12c5d1SDavid du Colombier if(c == '\n')
16663e12c5d1SDavid du Colombier lineno++;
16673e12c5d1SDavid du Colombier c = Bgetrune(finput);
16683e12c5d1SDavid du Colombier }
16693e12c5d1SDavid du Colombier
16703e12c5d1SDavid du Colombier /* skip comment */
16713e12c5d1SDavid du Colombier if(c == '/') {
16723e12c5d1SDavid du Colombier lineno += skipcom();
16733e12c5d1SDavid du Colombier goto begin;
16743e12c5d1SDavid du Colombier }
16753e12c5d1SDavid du Colombier switch(c) {
16763e12c5d1SDavid du Colombier case Beof:
16773e12c5d1SDavid du Colombier return ENDFILE;
16783e12c5d1SDavid du Colombier
16793e12c5d1SDavid du Colombier case '{':
16803e12c5d1SDavid du Colombier Bungetrune(finput);
16813e12c5d1SDavid du Colombier return '=';
16823e12c5d1SDavid du Colombier
16833e12c5d1SDavid du Colombier case '<':
16843e12c5d1SDavid du Colombier /* get, and look up, a type name (union member name) */
16853e12c5d1SDavid du Colombier i = 0;
16863e12c5d1SDavid du Colombier while((c=Bgetrune(finput)) != '>' && c >= 0 && c != '\n') {
16873e12c5d1SDavid du Colombier rune = c;
16883e12c5d1SDavid du Colombier c = runetochar(&tokname[i], &rune);
16893e12c5d1SDavid du Colombier if(i < NAMESIZE)
16903e12c5d1SDavid du Colombier i += c;
16913e12c5d1SDavid du Colombier }
16923e12c5d1SDavid du Colombier if(c != '>')
16933e12c5d1SDavid du Colombier error("unterminated < ... > clause");
16943e12c5d1SDavid du Colombier tokname[i] = 0;
16953e12c5d1SDavid du Colombier for(i=1; i<=ntypes; i++)
16963e12c5d1SDavid du Colombier if(!strcmp(typeset[i], tokname)) {
16973e12c5d1SDavid du Colombier numbval = i;
16983e12c5d1SDavid du Colombier return TYPENAME;
16993e12c5d1SDavid du Colombier }
17003e12c5d1SDavid du Colombier ntypes++;
17013e12c5d1SDavid du Colombier numbval = ntypes;
17023e12c5d1SDavid du Colombier typeset[numbval] = cstash(tokname);
17033e12c5d1SDavid du Colombier return TYPENAME;
17043e12c5d1SDavid du Colombier
17053e12c5d1SDavid du Colombier case '"':
17063e12c5d1SDavid du Colombier case '\'':
17073e12c5d1SDavid du Colombier match = c;
17083e12c5d1SDavid du Colombier tokname[0] = ' ';
17093e12c5d1SDavid du Colombier i = 1;
17103e12c5d1SDavid du Colombier for(;;) {
17113e12c5d1SDavid du Colombier c = Bgetrune(finput);
17123e12c5d1SDavid du Colombier if(c == '\n' || c <= 0)
17133e12c5d1SDavid du Colombier error("illegal or missing ' or \"" );
17143e12c5d1SDavid du Colombier if(c == '\\') {
17153e12c5d1SDavid du Colombier tokname[i] = '\\';
17163e12c5d1SDavid du Colombier if(i < NAMESIZE)
17173e12c5d1SDavid du Colombier i++;
17183e12c5d1SDavid du Colombier c = Bgetrune(finput);
17193e12c5d1SDavid du Colombier } else
17203e12c5d1SDavid du Colombier if(c == match)
17213e12c5d1SDavid du Colombier break;
17223e12c5d1SDavid du Colombier rune = c;
17233e12c5d1SDavid du Colombier c = runetochar(&tokname[i], &rune);
17243e12c5d1SDavid du Colombier if(i < NAMESIZE)
17253e12c5d1SDavid du Colombier i += c;
17263e12c5d1SDavid du Colombier }
17273e12c5d1SDavid du Colombier break;
17283e12c5d1SDavid du Colombier
17293e12c5d1SDavid du Colombier case '%':
17303e12c5d1SDavid du Colombier case '\\':
17313e12c5d1SDavid du Colombier switch(c = Bgetrune(finput)) {
17323e12c5d1SDavid du Colombier case '0': return TERM;
17333e12c5d1SDavid du Colombier case '<': return LEFT;
17343e12c5d1SDavid du Colombier case '2': return BINARY;
17353e12c5d1SDavid du Colombier case '>': return RIGHT;
17363e12c5d1SDavid du Colombier case '%':
17373e12c5d1SDavid du Colombier case '\\': return MARK;
17383e12c5d1SDavid du Colombier case '=': return PREC;
17393e12c5d1SDavid du Colombier case '{': return LCURLY;
17403e12c5d1SDavid du Colombier default: reserve = 1;
17413e12c5d1SDavid du Colombier }
17423e12c5d1SDavid du Colombier
17433e12c5d1SDavid du Colombier default:
17443e12c5d1SDavid du Colombier /* number */
17453e12c5d1SDavid du Colombier if(isdigit(c)) {
17463e12c5d1SDavid du Colombier numbval = c-'0';
17473e12c5d1SDavid du Colombier base = (c=='0')? 8: 10;
17483e12c5d1SDavid du Colombier for(c = Bgetrune(finput); isdigit(c); c = Bgetrune(finput))
17493e12c5d1SDavid du Colombier numbval = numbval*base + (c-'0');
17503e12c5d1SDavid du Colombier Bungetrune(finput);
17513e12c5d1SDavid du Colombier return NUMBER;
17523e12c5d1SDavid du Colombier }
17533e12c5d1SDavid du Colombier if(islower(c) || isupper(c) || c=='_' || c=='.' || c=='$') {
17543e12c5d1SDavid du Colombier i = 0;
17553e12c5d1SDavid du Colombier while(islower(c) || isupper(c) || isdigit(c) ||
17563e12c5d1SDavid du Colombier c == '-' || c=='_' || c=='.' || c=='$') {
17573e12c5d1SDavid du Colombier if(reserve && isupper(c))
17583e12c5d1SDavid du Colombier c += 'a'-'A';
17593e12c5d1SDavid du Colombier rune = c;
17603e12c5d1SDavid du Colombier c = runetochar(&tokname[i], &rune);
17613e12c5d1SDavid du Colombier if(i < NAMESIZE)
17623e12c5d1SDavid du Colombier i += c;
17633e12c5d1SDavid du Colombier c = Bgetrune(finput);
17643e12c5d1SDavid du Colombier }
17653e12c5d1SDavid du Colombier } else
17663e12c5d1SDavid du Colombier return c;
17673e12c5d1SDavid du Colombier Bungetrune(finput);
17683e12c5d1SDavid du Colombier }
17693e12c5d1SDavid du Colombier tokname[i] = 0;
17703e12c5d1SDavid du Colombier
17713e12c5d1SDavid du Colombier /* find a reserved word */
17723e12c5d1SDavid du Colombier if(reserve) {
17733e12c5d1SDavid du Colombier for(c=0; resrv[c].name; c++)
17743e12c5d1SDavid du Colombier if(strcmp(tokname, resrv[c].name) == 0)
17753e12c5d1SDavid du Colombier return resrv[c].value;
17763e12c5d1SDavid du Colombier error("invalid escape, or illegal reserved word: %s", tokname);
17773e12c5d1SDavid du Colombier }
17783e12c5d1SDavid du Colombier
17793e12c5d1SDavid du Colombier /* look ahead to distinguish IDENTIFIER from IDENTCOLON */
17803e12c5d1SDavid du Colombier c = Bgetrune(finput);
17813e12c5d1SDavid du Colombier while(c == ' ' || c == '\t'|| c == '\n' || c == '\f' || c == '/') {
17823e12c5d1SDavid du Colombier if(c == '\n')
17833e12c5d1SDavid du Colombier peekline++;
17843e12c5d1SDavid du Colombier /* look for comments */
17853e12c5d1SDavid du Colombier if(c == '/')
17863e12c5d1SDavid du Colombier peekline += skipcom();
17873e12c5d1SDavid du Colombier c = Bgetrune(finput);
17883e12c5d1SDavid du Colombier }
17893e12c5d1SDavid du Colombier if(c == ':')
17903e12c5d1SDavid du Colombier return IDENTCOLON;
17913e12c5d1SDavid du Colombier Bungetrune(finput);
17923e12c5d1SDavid du Colombier return IDENTIFIER;
17933e12c5d1SDavid du Colombier }
17943e12c5d1SDavid du Colombier
17953e12c5d1SDavid du Colombier /*
17963e12c5d1SDavid du Colombier * determine the type of a symbol
17973e12c5d1SDavid du Colombier */
17983e12c5d1SDavid du Colombier int
fdtype(int t)17993e12c5d1SDavid du Colombier fdtype(int t)
18003e12c5d1SDavid du Colombier {
18013e12c5d1SDavid du Colombier int v;
18023e12c5d1SDavid du Colombier
18033e12c5d1SDavid du Colombier if(t >= NTBASE)
18043e12c5d1SDavid du Colombier v = nontrst[t-NTBASE].value;
18053e12c5d1SDavid du Colombier else
18063e12c5d1SDavid du Colombier v = TYPE(toklev[t]);
18073e12c5d1SDavid du Colombier if(v <= 0)
18083e12c5d1SDavid du Colombier error("must specify type for %s", (t>=NTBASE)?
18093e12c5d1SDavid du Colombier nontrst[t-NTBASE].name: tokset[t].name);
18103e12c5d1SDavid du Colombier return v;
18113e12c5d1SDavid du Colombier }
18123e12c5d1SDavid du Colombier
18133e12c5d1SDavid du Colombier int
chfind(int t,char * s)18143e12c5d1SDavid du Colombier chfind(int t, char *s)
18153e12c5d1SDavid du Colombier {
18163e12c5d1SDavid du Colombier int i;
18173e12c5d1SDavid du Colombier
18183e12c5d1SDavid du Colombier if(s[0] == ' ')
18193e12c5d1SDavid du Colombier t = 0;
18203e12c5d1SDavid du Colombier TLOOP(i)
18213e12c5d1SDavid du Colombier if(!strcmp(s, tokset[i].name))
18223e12c5d1SDavid du Colombier return i;
18233e12c5d1SDavid du Colombier NTLOOP(i)
18243e12c5d1SDavid du Colombier if(!strcmp(s, nontrst[i].name))
18253e12c5d1SDavid du Colombier return NTBASE+i;
18263e12c5d1SDavid du Colombier
18273e12c5d1SDavid du Colombier /* cannot find name */
18283e12c5d1SDavid du Colombier if(t > 1)
18293e12c5d1SDavid du Colombier error("%s should have been defined earlier", s);
18303e12c5d1SDavid du Colombier return defin(t, s);
18313e12c5d1SDavid du Colombier }
18323e12c5d1SDavid du Colombier
18333e12c5d1SDavid du Colombier /*
18343e12c5d1SDavid du Colombier * copy the union declaration to the output, and the define file if present
18353e12c5d1SDavid du Colombier */
18363e12c5d1SDavid du Colombier void
cpyunion(void)18373e12c5d1SDavid du Colombier cpyunion(void)
18383e12c5d1SDavid du Colombier {
18393e12c5d1SDavid du Colombier long c;
18403e12c5d1SDavid du Colombier int level;
18413e12c5d1SDavid du Colombier
18423e12c5d1SDavid du Colombier Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
18433e12c5d1SDavid du Colombier Bprint(ftable, "typedef union ");
18443e12c5d1SDavid du Colombier if(fdefine != 0)
18453e12c5d1SDavid du Colombier Bprint(fdefine, "\ntypedef union ");
18463e12c5d1SDavid du Colombier
18473e12c5d1SDavid du Colombier level = 0;
18483e12c5d1SDavid du Colombier for(;;) {
18493e12c5d1SDavid du Colombier if((c=Bgetrune(finput)) == Beof)
18503e12c5d1SDavid du Colombier error("EOF encountered while processing %%union");
18513e12c5d1SDavid du Colombier Bputrune(ftable, c);
18523e12c5d1SDavid du Colombier if(fdefine != 0)
18533e12c5d1SDavid du Colombier Bputrune(fdefine, c);
18543e12c5d1SDavid du Colombier switch(c) {
18553e12c5d1SDavid du Colombier case '\n':
18563e12c5d1SDavid du Colombier lineno++;
18573e12c5d1SDavid du Colombier break;
18583e12c5d1SDavid du Colombier case '{':
18593e12c5d1SDavid du Colombier level++;
18603e12c5d1SDavid du Colombier break;
18613e12c5d1SDavid du Colombier case '}':
18623e12c5d1SDavid du Colombier level--;
18633e12c5d1SDavid du Colombier
18643e12c5d1SDavid du Colombier /* we are finished copying */
18653e12c5d1SDavid du Colombier if(level == 0) {
18663e12c5d1SDavid du Colombier Bprint(ftable, " YYSTYPE;\n");
18673e12c5d1SDavid du Colombier if(fdefine != 0)
18683e12c5d1SDavid du Colombier Bprint(fdefine, "\tYYSTYPE;\nextern\tYYSTYPE\tyylval;\n");
18693e12c5d1SDavid du Colombier return;
18703e12c5d1SDavid du Colombier }
18713e12c5d1SDavid du Colombier }
18723e12c5d1SDavid du Colombier }
18733e12c5d1SDavid du Colombier }
18743e12c5d1SDavid du Colombier
18753e12c5d1SDavid du Colombier /*
18763e12c5d1SDavid du Colombier * copies code between \{ and \}
18773e12c5d1SDavid du Colombier */
18783e12c5d1SDavid du Colombier void
cpycode(void)18793e12c5d1SDavid du Colombier cpycode(void)
18803e12c5d1SDavid du Colombier {
18813e12c5d1SDavid du Colombier
18823e12c5d1SDavid du Colombier long c;
18833e12c5d1SDavid du Colombier
18843e12c5d1SDavid du Colombier c = Bgetrune(finput);
18853e12c5d1SDavid du Colombier if(c == '\n') {
18863e12c5d1SDavid du Colombier c = Bgetrune(finput);
18873e12c5d1SDavid du Colombier lineno++;
18883e12c5d1SDavid du Colombier }
18893e12c5d1SDavid du Colombier Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
18903e12c5d1SDavid du Colombier while(c != Beof) {
18913e12c5d1SDavid du Colombier if(c == '\\') {
18923e12c5d1SDavid du Colombier if((c=Bgetrune(finput)) == '}')
18933e12c5d1SDavid du Colombier return;
18943e12c5d1SDavid du Colombier Bputc(ftable, '\\');
18953e12c5d1SDavid du Colombier }
18963e12c5d1SDavid du Colombier if(c == '%') {
18973e12c5d1SDavid du Colombier if((c=Bgetrune(finput)) == '}')
18983e12c5d1SDavid du Colombier return;
18993e12c5d1SDavid du Colombier Bputc(ftable, '%');
19003e12c5d1SDavid du Colombier }
19013e12c5d1SDavid du Colombier Bputrune(ftable, c);
19023e12c5d1SDavid du Colombier if(c == '\n')
19033e12c5d1SDavid du Colombier lineno++;
19043e12c5d1SDavid du Colombier c = Bgetrune(finput);
19053e12c5d1SDavid du Colombier }
19063e12c5d1SDavid du Colombier error("eof before %%}");
19073e12c5d1SDavid du Colombier }
19083e12c5d1SDavid du Colombier
19093e12c5d1SDavid du Colombier /*
19103e12c5d1SDavid du Colombier * skip over comments
19113e12c5d1SDavid du Colombier * skipcom is called after reading a '/'
19123e12c5d1SDavid du Colombier */
19133e12c5d1SDavid du Colombier int
skipcom(void)19143e12c5d1SDavid du Colombier skipcom(void)
19153e12c5d1SDavid du Colombier {
19163e12c5d1SDavid du Colombier long c;
19173e12c5d1SDavid du Colombier int i;
19183e12c5d1SDavid du Colombier
19193e12c5d1SDavid du Colombier /* i is the number of lines skipped */
19203e12c5d1SDavid du Colombier i = 0;
19213e12c5d1SDavid du Colombier c = Bgetrune(finput);
192243aadf5eSDavid du Colombier if(c == '/'){ /* C++ //: skip to end of line */
192343aadf5eSDavid du Colombier while((c = Bgetrune(finput)) != Beof)
192443aadf5eSDavid du Colombier if(c == '\n')
192543aadf5eSDavid du Colombier return 1;
192643aadf5eSDavid du Colombier }else if(c == '*'){ /* normal C comment */
192743aadf5eSDavid du Colombier while((c = Bgetrune(finput)) != Beof) {
19283e12c5d1SDavid du Colombier while(c == '*')
19293e12c5d1SDavid du Colombier if((c = Bgetrune(finput)) == '/')
19303e12c5d1SDavid du Colombier return i;
19313e12c5d1SDavid du Colombier if(c == '\n')
19323e12c5d1SDavid du Colombier i++;
19333e12c5d1SDavid du Colombier }
193443aadf5eSDavid du Colombier }else
193543aadf5eSDavid du Colombier error("illegal comment");
193643aadf5eSDavid du Colombier
19373e12c5d1SDavid du Colombier error("EOF inside comment");
19383e12c5d1SDavid du Colombier return 0;
19393e12c5d1SDavid du Colombier }
19403e12c5d1SDavid du Colombier
19413e12c5d1SDavid du Colombier /*
19423e12c5d1SDavid du Colombier * copy C action to the next ; or closing }
19433e12c5d1SDavid du Colombier */
19443e12c5d1SDavid du Colombier void
cpyact(int offset)19453e12c5d1SDavid du Colombier cpyact(int offset)
19463e12c5d1SDavid du Colombier {
19473e12c5d1SDavid du Colombier long c;
19483e12c5d1SDavid du Colombier int brac, match, j, s, fnd, tok;
19493e12c5d1SDavid du Colombier
19503e12c5d1SDavid du Colombier Bprint(faction, "\n#line\t%d\t\"%s\"\n", lineno, infile);
19513e12c5d1SDavid du Colombier brac = 0;
19523e12c5d1SDavid du Colombier
19533e12c5d1SDavid du Colombier loop:
19543e12c5d1SDavid du Colombier c = Bgetrune(finput);
19553e12c5d1SDavid du Colombier swt:
19563e12c5d1SDavid du Colombier switch(c) {
19573e12c5d1SDavid du Colombier case ';':
19583e12c5d1SDavid du Colombier if(brac == 0) {
19593e12c5d1SDavid du Colombier Bputrune(faction, c);
19603e12c5d1SDavid du Colombier return;
19613e12c5d1SDavid du Colombier }
19623e12c5d1SDavid du Colombier goto lcopy;
19633e12c5d1SDavid du Colombier
19643e12c5d1SDavid du Colombier case '{':
19653e12c5d1SDavid du Colombier brac++;
19663e12c5d1SDavid du Colombier goto lcopy;
19673e12c5d1SDavid du Colombier
19683e12c5d1SDavid du Colombier case '$':
19693e12c5d1SDavid du Colombier s = 1;
19703e12c5d1SDavid du Colombier tok = -1;
19713e12c5d1SDavid du Colombier c = Bgetrune(finput);
19723e12c5d1SDavid du Colombier
19733e12c5d1SDavid du Colombier /* type description */
19743e12c5d1SDavid du Colombier if(c == '<') {
19753e12c5d1SDavid du Colombier Bungetrune(finput);
19763e12c5d1SDavid du Colombier if(gettok() != TYPENAME)
19773e12c5d1SDavid du Colombier error("bad syntax on $<ident> clause");
19783e12c5d1SDavid du Colombier tok = numbval;
19793e12c5d1SDavid du Colombier c = Bgetrune(finput);
19803e12c5d1SDavid du Colombier }
19813e12c5d1SDavid du Colombier if(c == '$') {
19823e12c5d1SDavid du Colombier Bprint(faction, "yyval");
19833e12c5d1SDavid du Colombier
19843e12c5d1SDavid du Colombier /* put out the proper tag... */
19853e12c5d1SDavid du Colombier if(ntypes) {
19863e12c5d1SDavid du Colombier if(tok < 0)
19873e12c5d1SDavid du Colombier tok = fdtype(*prdptr[nprod]);
19883e12c5d1SDavid du Colombier Bprint(faction, ".%s", typeset[tok]);
19893e12c5d1SDavid du Colombier }
19903e12c5d1SDavid du Colombier goto loop;
19913e12c5d1SDavid du Colombier }
19923e12c5d1SDavid du Colombier if(c == '-') {
19933e12c5d1SDavid du Colombier s = -s;
19943e12c5d1SDavid du Colombier c = Bgetrune(finput);
19953e12c5d1SDavid du Colombier }
19963e12c5d1SDavid du Colombier if(isdigit(c)) {
19973e12c5d1SDavid du Colombier j = 0;
19983e12c5d1SDavid du Colombier while(isdigit(c)) {
19993e12c5d1SDavid du Colombier j = j*10 + (c-'0');
20003e12c5d1SDavid du Colombier c = Bgetrune(finput);
20013e12c5d1SDavid du Colombier }
20023e12c5d1SDavid du Colombier Bungetrune(finput);
20033e12c5d1SDavid du Colombier j = j*s - offset;
20043e12c5d1SDavid du Colombier if(j > 0)
20053e12c5d1SDavid du Colombier error("Illegal use of $%d", j+offset);
20063e12c5d1SDavid du Colombier
20073e12c5d1SDavid du Colombier dollar:
20083e12c5d1SDavid du Colombier Bprint(faction, "yypt[-%d].yyv", -j);
20093e12c5d1SDavid du Colombier
20103e12c5d1SDavid du Colombier /* put out the proper tag */
20113e12c5d1SDavid du Colombier if(ntypes) {
20123e12c5d1SDavid du Colombier if(j+offset <= 0 && tok < 0)
20133e12c5d1SDavid du Colombier error("must specify type of $%d", j+offset);
20143e12c5d1SDavid du Colombier if(tok < 0)
20153e12c5d1SDavid du Colombier tok = fdtype(prdptr[nprod][j+offset]);
20163e12c5d1SDavid du Colombier Bprint(faction, ".%s", typeset[tok]);
20173e12c5d1SDavid du Colombier }
20183e12c5d1SDavid du Colombier goto loop;
20193e12c5d1SDavid du Colombier }
20203e12c5d1SDavid du Colombier if(isupper(c) || islower(c) || c == '_' || c == '.') {
20213e12c5d1SDavid du Colombier int tok; /* tok used oustide for type info */
20223e12c5d1SDavid du Colombier
20233e12c5d1SDavid du Colombier /* look for $name */
20243e12c5d1SDavid du Colombier Bungetrune(finput);
20253e12c5d1SDavid du Colombier if(gettok() != IDENTIFIER)
20263e12c5d1SDavid du Colombier error("$ must be followed by an identifier");
20273e12c5d1SDavid du Colombier tok = chfind(2, tokname);
20283e12c5d1SDavid du Colombier if((c = Bgetrune(finput)) != '#') {
20293e12c5d1SDavid du Colombier Bungetrune(finput);
20303e12c5d1SDavid du Colombier fnd = -1;
20313e12c5d1SDavid du Colombier } else
20323e12c5d1SDavid du Colombier if(gettok() != NUMBER) {
20333e12c5d1SDavid du Colombier error("# must be followed by number");
20343e12c5d1SDavid du Colombier fnd = -1;
20353e12c5d1SDavid du Colombier } else
20363e12c5d1SDavid du Colombier fnd = numbval;
20373e12c5d1SDavid du Colombier for(j=1; j<=offset; ++j)
20383e12c5d1SDavid du Colombier if(tok == prdptr[nprod][j]) {
20393e12c5d1SDavid du Colombier if(--fnd <= 0) {
20403e12c5d1SDavid du Colombier j -= offset;
20413e12c5d1SDavid du Colombier goto dollar;
20423e12c5d1SDavid du Colombier }
20433e12c5d1SDavid du Colombier }
20443e12c5d1SDavid du Colombier error("$name or $name#number not found");
20453e12c5d1SDavid du Colombier }
20463e12c5d1SDavid du Colombier Bputc(faction, '$');
20473e12c5d1SDavid du Colombier if(s < 0 )
20483e12c5d1SDavid du Colombier Bputc(faction, '-');
20493e12c5d1SDavid du Colombier goto swt;
20503e12c5d1SDavid du Colombier
20513e12c5d1SDavid du Colombier case '}':
20523e12c5d1SDavid du Colombier brac--;
20533e12c5d1SDavid du Colombier if(brac)
20543e12c5d1SDavid du Colombier goto lcopy;
20553e12c5d1SDavid du Colombier Bputrune(faction, c);
20563e12c5d1SDavid du Colombier return;
20573e12c5d1SDavid du Colombier
20583e12c5d1SDavid du Colombier case '/':
20593e12c5d1SDavid du Colombier /* look for comments */
20603e12c5d1SDavid du Colombier Bputrune(faction, c);
20613e12c5d1SDavid du Colombier c = Bgetrune(finput);
20623e12c5d1SDavid du Colombier if(c != '*')
20633e12c5d1SDavid du Colombier goto swt;
20643e12c5d1SDavid du Colombier
2065889a2622SDavid du Colombier /* it really is a comment; copy it */
20663e12c5d1SDavid du Colombier Bputrune(faction, c);
20673e12c5d1SDavid du Colombier c = Bgetrune(finput);
20683e12c5d1SDavid du Colombier while(c >= 0) {
20693e12c5d1SDavid du Colombier while(c == '*') {
20703e12c5d1SDavid du Colombier Bputrune(faction, c);
20713e12c5d1SDavid du Colombier if((c=Bgetrune(finput)) == '/')
20723e12c5d1SDavid du Colombier goto lcopy;
20733e12c5d1SDavid du Colombier }
20743e12c5d1SDavid du Colombier Bputrune(faction, c);
20753e12c5d1SDavid du Colombier if(c == '\n')
20763e12c5d1SDavid du Colombier lineno++;
20773e12c5d1SDavid du Colombier c = Bgetrune(finput);
20783e12c5d1SDavid du Colombier }
20793e12c5d1SDavid du Colombier error("EOF inside comment");
20803e12c5d1SDavid du Colombier
20813e12c5d1SDavid du Colombier case '\'':
20823e12c5d1SDavid du Colombier /* character constant */
20833e12c5d1SDavid du Colombier match = '\'';
20843e12c5d1SDavid du Colombier goto string;
20853e12c5d1SDavid du Colombier
20863e12c5d1SDavid du Colombier case '"':
20873e12c5d1SDavid du Colombier /* character string */
20883e12c5d1SDavid du Colombier match = '"';
20893e12c5d1SDavid du Colombier
20903e12c5d1SDavid du Colombier string:
20913e12c5d1SDavid du Colombier Bputrune(faction, c);
20923e12c5d1SDavid du Colombier while(c = Bgetrune(finput)) {
20933e12c5d1SDavid du Colombier if(c == '\\') {
20943e12c5d1SDavid du Colombier Bputrune(faction, c);
20953e12c5d1SDavid du Colombier c = Bgetrune(finput);
20963e12c5d1SDavid du Colombier if(c == '\n')
20973e12c5d1SDavid du Colombier lineno++;
20983e12c5d1SDavid du Colombier } else
20993e12c5d1SDavid du Colombier if(c == match)
21003e12c5d1SDavid du Colombier goto lcopy;
21013e12c5d1SDavid du Colombier if(c == '\n')
21023e12c5d1SDavid du Colombier error("newline in string or char. const.");
21033e12c5d1SDavid du Colombier Bputrune(faction, c);
21043e12c5d1SDavid du Colombier }
21053e12c5d1SDavid du Colombier error("EOF in string or character constant");
21063e12c5d1SDavid du Colombier
21073e12c5d1SDavid du Colombier case Beof:
21083e12c5d1SDavid du Colombier error("action does not terminate");
21093e12c5d1SDavid du Colombier
21103e12c5d1SDavid du Colombier case '\n':
21113e12c5d1SDavid du Colombier lineno++;
21123e12c5d1SDavid du Colombier goto lcopy;
21133e12c5d1SDavid du Colombier }
21143e12c5d1SDavid du Colombier
21153e12c5d1SDavid du Colombier lcopy:
21163e12c5d1SDavid du Colombier Bputrune(faction, c);
21173e12c5d1SDavid du Colombier goto loop;
21183e12c5d1SDavid du Colombier }
21193e12c5d1SDavid du Colombier
21203e12c5d1SDavid du Colombier void
openup(char * stem,int dflag,int vflag,int ytab,char * ytabc)21213e12c5d1SDavid du Colombier openup(char *stem, int dflag, int vflag, int ytab, char *ytabc)
21223e12c5d1SDavid du Colombier {
21233e12c5d1SDavid du Colombier char buf[256];
21243e12c5d1SDavid du Colombier
21253e12c5d1SDavid du Colombier if(vflag) {
21264d44ba9bSDavid du Colombier snprint(buf, sizeof buf, "%s.%s", stem, FILEU);
21273e12c5d1SDavid du Colombier foutput = Bopen(buf, OWRITE);
21283e12c5d1SDavid du Colombier if(foutput == 0)
21293e12c5d1SDavid du Colombier error("cannot open %s", buf);
21303e12c5d1SDavid du Colombier }
21313e12c5d1SDavid du Colombier if(yydebug) {
21324d44ba9bSDavid du Colombier snprint(buf, sizeof buf, "%s.%s", stem, FILEDEBUG);
21333e12c5d1SDavid du Colombier if((fdebug = Bopen(buf, OWRITE)) == 0)
21343e12c5d1SDavid du Colombier error("can't open %s", buf);
21353e12c5d1SDavid du Colombier }
21363e12c5d1SDavid du Colombier if(dflag) {
21374d44ba9bSDavid du Colombier snprint(buf, sizeof buf, "%s.%s", stem, FILED);
21383e12c5d1SDavid du Colombier fdefine = Bopen(buf, OWRITE);
21393e12c5d1SDavid du Colombier if(fdefine == 0)
21403e12c5d1SDavid du Colombier error("can't create %s", buf);
21413e12c5d1SDavid du Colombier }
21423e12c5d1SDavid du Colombier if(ytab == 0)
21434d44ba9bSDavid du Colombier snprint(buf, sizeof buf, "%s.%s", stem, OFILE);
21443e12c5d1SDavid du Colombier else
21454d44ba9bSDavid du Colombier strecpy(buf, buf+sizeof buf, ytabc);
21463e12c5d1SDavid du Colombier ftable = Bopen(buf, OWRITE);
21473e12c5d1SDavid du Colombier if(ftable == 0)
21483e12c5d1SDavid du Colombier error("cannot open table file %s", buf);
21493e12c5d1SDavid du Colombier }
21503e12c5d1SDavid du Colombier
21513e12c5d1SDavid du Colombier /*
21523e12c5d1SDavid du Colombier * print the output for the states
21533e12c5d1SDavid du Colombier */
21543e12c5d1SDavid du Colombier void
output(void)21553e12c5d1SDavid du Colombier output(void)
21563e12c5d1SDavid du Colombier {
21573e12c5d1SDavid du Colombier int i, k, c;
21583e12c5d1SDavid du Colombier Wset *u, *v;
21593e12c5d1SDavid du Colombier
21603e12c5d1SDavid du Colombier Bprint(ftable, "short yyexca[] =\n{");
21613e12c5d1SDavid du Colombier if(fdebug)
21623e12c5d1SDavid du Colombier Bprint(fdebug, "char* yystates[] =\n{\n");
21633e12c5d1SDavid du Colombier
21643e12c5d1SDavid du Colombier /* output the stuff for state i */
21653e12c5d1SDavid du Colombier SLOOP(i) {
21663e12c5d1SDavid du Colombier nolook = tystate[i]!=MUSTLOOKAHEAD;
21673e12c5d1SDavid du Colombier closure(i);
21683e12c5d1SDavid du Colombier
21693e12c5d1SDavid du Colombier /* output actions */
21703e12c5d1SDavid du Colombier nolook = 1;
21713e12c5d1SDavid du Colombier aryfil(temp1, ntokens+nnonter+1, 0);
21723e12c5d1SDavid du Colombier WSLOOP(wsets, u) {
21733e12c5d1SDavid du Colombier c = *(u->pitem);
21743e12c5d1SDavid du Colombier if(c > 1 && c < NTBASE && temp1[c] == 0) {
21753e12c5d1SDavid du Colombier WSLOOP(u, v)
21763e12c5d1SDavid du Colombier if(c == *(v->pitem))
21773e12c5d1SDavid du Colombier putitem(v->pitem+1, (Lkset*)0);
21783e12c5d1SDavid du Colombier temp1[c] = state(c);
21793e12c5d1SDavid du Colombier } else
21803e12c5d1SDavid du Colombier if(c > NTBASE && temp1[(c -= NTBASE) + ntokens] == 0)
21813e12c5d1SDavid du Colombier temp1[c+ntokens] = amem[indgo[i]+c];
21823e12c5d1SDavid du Colombier }
21833e12c5d1SDavid du Colombier if(i == 1)
21843e12c5d1SDavid du Colombier temp1[1] = ACCEPTCODE;
21853e12c5d1SDavid du Colombier
21863e12c5d1SDavid du Colombier /* now, we have the shifts; look at the reductions */
21873e12c5d1SDavid du Colombier lastred = 0;
21883e12c5d1SDavid du Colombier WSLOOP(wsets, u) {
21893e12c5d1SDavid du Colombier c = *u->pitem;
21903e12c5d1SDavid du Colombier
21913e12c5d1SDavid du Colombier /* reduction */
21923e12c5d1SDavid du Colombier if(c <= 0) {
21933e12c5d1SDavid du Colombier lastred = -c;
21943e12c5d1SDavid du Colombier TLOOP(k)
21953e12c5d1SDavid du Colombier if(BIT(u->ws.lset, k)) {
21963e12c5d1SDavid du Colombier if(temp1[k] == 0)
21973e12c5d1SDavid du Colombier temp1[k] = c;
21983e12c5d1SDavid du Colombier else
21993e12c5d1SDavid du Colombier if(temp1[k] < 0) { /* reduce/reduce conflict */
22003e12c5d1SDavid du Colombier if(foutput)
22013e12c5d1SDavid du Colombier Bprint(foutput,
22023e12c5d1SDavid du Colombier "\n%d: reduce/reduce conflict"
22033e12c5d1SDavid du Colombier " (red'ns %d and %d ) on %s",
22043e12c5d1SDavid du Colombier i, -temp1[k], lastred,
22053e12c5d1SDavid du Colombier symnam(k));
22063e12c5d1SDavid du Colombier if(-temp1[k] > lastred)
22073e12c5d1SDavid du Colombier temp1[k] = -lastred;
22083e12c5d1SDavid du Colombier zzrrconf++;
22093e12c5d1SDavid du Colombier } else
22103e12c5d1SDavid du Colombier /* potential shift/reduce conflict */
22113e12c5d1SDavid du Colombier precftn( lastred, k, i );
22123e12c5d1SDavid du Colombier }
22133e12c5d1SDavid du Colombier }
22143e12c5d1SDavid du Colombier }
22153e12c5d1SDavid du Colombier wract(i);
22163e12c5d1SDavid du Colombier }
22173e12c5d1SDavid du Colombier
22183e12c5d1SDavid du Colombier if(fdebug)
22193e12c5d1SDavid du Colombier Bprint(fdebug, "};\n");
22203e12c5d1SDavid du Colombier Bprint(ftable, "};\n");
22213e12c5d1SDavid du Colombier Bprint(ftable, "#define YYNPROD %d\n", nprod);
22223e12c5d1SDavid du Colombier Bprint(ftable, "#define YYPRIVATE %d\n", PRIVATE);
22233e12c5d1SDavid du Colombier if(yydebug)
22243e12c5d1SDavid du Colombier Bprint(ftable, "#define yydebug %s\n", yydebug);
22253e12c5d1SDavid du Colombier }
22263e12c5d1SDavid du Colombier
22273e12c5d1SDavid du Colombier /*
22283e12c5d1SDavid du Colombier * pack state i from temp1 into amem
22293e12c5d1SDavid du Colombier */
22303e12c5d1SDavid du Colombier int
apack(int * p,int n)22313e12c5d1SDavid du Colombier apack(int *p, int n)
22323e12c5d1SDavid du Colombier {
22333e12c5d1SDavid du Colombier int *pp, *qq, *rr, off, *q, *r;
22343e12c5d1SDavid du Colombier
22353e12c5d1SDavid du Colombier /* we don't need to worry about checking because
22363e12c5d1SDavid du Colombier * we will only look at entries known to be there...
22373e12c5d1SDavid du Colombier * eliminate leading and trailing 0's
22383e12c5d1SDavid du Colombier */
22393e12c5d1SDavid du Colombier
22403e12c5d1SDavid du Colombier q = p+n;
22413e12c5d1SDavid du Colombier for(pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
22423e12c5d1SDavid du Colombier ;
22433e12c5d1SDavid du Colombier /* no actions */
22443e12c5d1SDavid du Colombier if(pp > q)
22453e12c5d1SDavid du Colombier return 0;
22463e12c5d1SDavid du Colombier p = pp;
22473e12c5d1SDavid du Colombier
22483e12c5d1SDavid du Colombier /* now, find a place for the elements from p to q, inclusive */
22493e12c5d1SDavid du Colombier r = &amem[ACTSIZE-1];
22503e12c5d1SDavid du Colombier for(rr = amem; rr <= r; rr++, off++) {
22513e12c5d1SDavid du Colombier for(qq = rr, pp = p; pp <= q; pp++, qq++)
22523e12c5d1SDavid du Colombier if(*pp != 0)
22533e12c5d1SDavid du Colombier if(*pp != *qq && *qq != 0)
22543e12c5d1SDavid du Colombier goto nextk;
22553e12c5d1SDavid du Colombier
22563e12c5d1SDavid du Colombier /* we have found an acceptable k */
22573e12c5d1SDavid du Colombier if(pkdebug && foutput != 0)
22587dd7cddfSDavid du Colombier Bprint(foutput, "off = %d, k = %d\n", off, (int)(rr-amem));
22593e12c5d1SDavid du Colombier for(qq = rr, pp = p; pp <= q; pp++, qq++)
22603e12c5d1SDavid du Colombier if(*pp) {
22613e12c5d1SDavid du Colombier if(qq > r)
22623e12c5d1SDavid du Colombier error("action table overflow");
22633e12c5d1SDavid du Colombier if(qq > memp)
22643e12c5d1SDavid du Colombier memp = qq;
22653e12c5d1SDavid du Colombier *qq = *pp;
22663e12c5d1SDavid du Colombier }
22673e12c5d1SDavid du Colombier if(pkdebug && foutput != 0)
22683e12c5d1SDavid du Colombier for(pp = amem; pp <= memp; pp += 10) {
22693e12c5d1SDavid du Colombier Bprint(foutput, "\t");
22703e12c5d1SDavid du Colombier for(qq = pp; qq <= pp+9; qq++)
22713e12c5d1SDavid du Colombier Bprint(foutput, "%d ", *qq);
22723e12c5d1SDavid du Colombier Bprint(foutput, "\n");
22733e12c5d1SDavid du Colombier }
22743e12c5d1SDavid du Colombier return(off);
22753e12c5d1SDavid du Colombier nextk:;
22763e12c5d1SDavid du Colombier }
22773e12c5d1SDavid du Colombier error("no space in action table");
22783e12c5d1SDavid du Colombier return 0;
22793e12c5d1SDavid du Colombier }
22803e12c5d1SDavid du Colombier
22813e12c5d1SDavid du Colombier /*
22823e12c5d1SDavid du Colombier * output the gotos for the nontermninals
22833e12c5d1SDavid du Colombier */
22843e12c5d1SDavid du Colombier void
go2out(void)22853e12c5d1SDavid du Colombier go2out(void)
22863e12c5d1SDavid du Colombier {
22873e12c5d1SDavid du Colombier int i, j, k, best, count, cbest, times;
22883e12c5d1SDavid du Colombier
22893e12c5d1SDavid du Colombier /* mark begining of gotos */
22903e12c5d1SDavid du Colombier Bprint(ftemp, "$\n");
22913e12c5d1SDavid du Colombier for(i = 1; i <= nnonter; i++) {
22923e12c5d1SDavid du Colombier go2gen(i);
22933e12c5d1SDavid du Colombier
22943e12c5d1SDavid du Colombier /* find the best one to make default */
22953e12c5d1SDavid du Colombier best = -1;
22963e12c5d1SDavid du Colombier times = 0;
22973e12c5d1SDavid du Colombier
22983e12c5d1SDavid du Colombier /* is j the most frequent */
22993e12c5d1SDavid du Colombier for(j = 0; j <= nstate; j++) {
23003e12c5d1SDavid du Colombier if(tystate[j] == 0)
23013e12c5d1SDavid du Colombier continue;
23023e12c5d1SDavid du Colombier if(tystate[j] == best)
23033e12c5d1SDavid du Colombier continue;
23043e12c5d1SDavid du Colombier
23053e12c5d1SDavid du Colombier /* is tystate[j] the most frequent */
23063e12c5d1SDavid du Colombier count = 0;
23073e12c5d1SDavid du Colombier cbest = tystate[j];
23083e12c5d1SDavid du Colombier for(k = j; k <= nstate; k++)
23093e12c5d1SDavid du Colombier if(tystate[k] == cbest)
23103e12c5d1SDavid du Colombier count++;
23113e12c5d1SDavid du Colombier if(count > times) {
23123e12c5d1SDavid du Colombier best = cbest;
23133e12c5d1SDavid du Colombier times = count;
23143e12c5d1SDavid du Colombier }
23153e12c5d1SDavid du Colombier }
23163e12c5d1SDavid du Colombier
23173e12c5d1SDavid du Colombier /* best is now the default entry */
23183e12c5d1SDavid du Colombier zzgobest += times-1;
23193e12c5d1SDavid du Colombier for(j = 0; j <= nstate; j++)
23203e12c5d1SDavid du Colombier if(tystate[j] != 0 && tystate[j] != best) {
23213e12c5d1SDavid du Colombier Bprint(ftemp, "%d,%d,", j, tystate[j]);
23223e12c5d1SDavid du Colombier zzgoent++;
23233e12c5d1SDavid du Colombier }
23243e12c5d1SDavid du Colombier
23253e12c5d1SDavid du Colombier /* now, the default */
23267dd7cddfSDavid du Colombier if(best == -1)
23277dd7cddfSDavid du Colombier best = 0;
23283e12c5d1SDavid du Colombier zzgoent++;
23293e12c5d1SDavid du Colombier Bprint(ftemp, "%d\n", best);
23303e12c5d1SDavid du Colombier }
23313e12c5d1SDavid du Colombier }
23323e12c5d1SDavid du Colombier
23333e12c5d1SDavid du Colombier /*
23343e12c5d1SDavid du Colombier * output the gotos for nonterminal c
23353e12c5d1SDavid du Colombier */
23363e12c5d1SDavid du Colombier void
go2gen(int c)23373e12c5d1SDavid du Colombier go2gen(int c)
23383e12c5d1SDavid du Colombier {
23393e12c5d1SDavid du Colombier int i, work, cc;
23403e12c5d1SDavid du Colombier Item *p, *q;
23413e12c5d1SDavid du Colombier
23423e12c5d1SDavid du Colombier
23433e12c5d1SDavid du Colombier /* first, find nonterminals with gotos on c */
23443e12c5d1SDavid du Colombier aryfil(temp1, nnonter+1, 0);
23453e12c5d1SDavid du Colombier temp1[c] = 1;
23463e12c5d1SDavid du Colombier work = 1;
23473e12c5d1SDavid du Colombier while(work) {
23483e12c5d1SDavid du Colombier work = 0;
23493e12c5d1SDavid du Colombier PLOOP(0, i)
23503e12c5d1SDavid du Colombier
23513e12c5d1SDavid du Colombier /* cc is a nonterminal */
23523e12c5d1SDavid du Colombier if((cc=prdptr[i][1]-NTBASE) >= 0)
23533e12c5d1SDavid du Colombier /* cc has a goto on c */
23543e12c5d1SDavid du Colombier if(temp1[cc] != 0) {
23553e12c5d1SDavid du Colombier
23563e12c5d1SDavid du Colombier /* thus, the left side of production i does too */
23573e12c5d1SDavid du Colombier cc = *prdptr[i]-NTBASE;
23583e12c5d1SDavid du Colombier if(temp1[cc] == 0) {
23593e12c5d1SDavid du Colombier work = 1;
23603e12c5d1SDavid du Colombier temp1[cc] = 1;
23613e12c5d1SDavid du Colombier }
23623e12c5d1SDavid du Colombier }
23633e12c5d1SDavid du Colombier }
23643e12c5d1SDavid du Colombier
23653e12c5d1SDavid du Colombier /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
23663e12c5d1SDavid du Colombier if(g2debug && foutput != 0) {
23673e12c5d1SDavid du Colombier Bprint(foutput, "%s: gotos on ", nontrst[c].name);
23683e12c5d1SDavid du Colombier NTLOOP(i)
23693e12c5d1SDavid du Colombier if(temp1[i])
23703e12c5d1SDavid du Colombier Bprint(foutput, "%s ", nontrst[i].name);
23713e12c5d1SDavid du Colombier Bprint(foutput, "\n");
23723e12c5d1SDavid du Colombier }
23733e12c5d1SDavid du Colombier
23743e12c5d1SDavid du Colombier /* now, go through and put gotos into tystate */
23753e12c5d1SDavid du Colombier aryfil(tystate, nstate, 0);
23763e12c5d1SDavid du Colombier SLOOP(i)
23773e12c5d1SDavid du Colombier ITMLOOP(i, p, q)
23783e12c5d1SDavid du Colombier if((cc = *p->pitem) >= NTBASE)
23793e12c5d1SDavid du Colombier /* goto on c is possible */
23803e12c5d1SDavid du Colombier if(temp1[cc-NTBASE]) {
23813e12c5d1SDavid du Colombier tystate[i] = amem[indgo[i]+c];
23823e12c5d1SDavid du Colombier break;
23833e12c5d1SDavid du Colombier }
23843e12c5d1SDavid du Colombier }
23853e12c5d1SDavid du Colombier
23863e12c5d1SDavid du Colombier /*
23873e12c5d1SDavid du Colombier * decide a shift/reduce conflict by precedence.
23883e12c5d1SDavid du Colombier * r is a rule number, t a token number
23893e12c5d1SDavid du Colombier * the conflict is in state s
23903e12c5d1SDavid du Colombier * temp1[t] is changed to reflect the action
23913e12c5d1SDavid du Colombier */
23923e12c5d1SDavid du Colombier void
precftn(int r,int t,int s)23933e12c5d1SDavid du Colombier precftn(int r, int t, int s)
23943e12c5d1SDavid du Colombier {
23953e12c5d1SDavid du Colombier int lp, lt, action;
23963e12c5d1SDavid du Colombier
23973e12c5d1SDavid du Colombier lp = levprd[r];
23983e12c5d1SDavid du Colombier lt = toklev[t];
23993e12c5d1SDavid du Colombier if(PLEVEL(lt) == 0 || PLEVEL(lp) == 0) {
24003e12c5d1SDavid du Colombier
24013e12c5d1SDavid du Colombier /* conflict */
24023e12c5d1SDavid du Colombier if(foutput != 0)
24033e12c5d1SDavid du Colombier Bprint(foutput,
24043e12c5d1SDavid du Colombier "\n%d: shift/reduce conflict (shift %d(%d), red'n %d(%d)) on %s",
24053e12c5d1SDavid du Colombier s, temp1[t], PLEVEL(lt), r, PLEVEL(lp), symnam(t));
24063e12c5d1SDavid du Colombier zzsrconf++;
24073e12c5d1SDavid du Colombier return;
24083e12c5d1SDavid du Colombier }
24093e12c5d1SDavid du Colombier if(PLEVEL(lt) == PLEVEL(lp))
24103e12c5d1SDavid du Colombier action = ASSOC(lt);
24113e12c5d1SDavid du Colombier else
24123e12c5d1SDavid du Colombier if(PLEVEL(lt) > PLEVEL(lp))
24133e12c5d1SDavid du Colombier action = RASC; /* shift */
24143e12c5d1SDavid du Colombier else
24153e12c5d1SDavid du Colombier action = LASC; /* reduce */
24163e12c5d1SDavid du Colombier switch(action) {
24173e12c5d1SDavid du Colombier case BASC: /* error action */
24183e12c5d1SDavid du Colombier temp1[t] = ERRCODE;
24193e12c5d1SDavid du Colombier break;
24203e12c5d1SDavid du Colombier case LASC: /* reduce */
24213e12c5d1SDavid du Colombier temp1[t] = -r;
24223e12c5d1SDavid du Colombier break;
24233e12c5d1SDavid du Colombier }
24243e12c5d1SDavid du Colombier }
24253e12c5d1SDavid du Colombier
24263e12c5d1SDavid du Colombier /*
24273e12c5d1SDavid du Colombier * output state i
24283e12c5d1SDavid du Colombier * temp1 has the actions, lastred the default
24293e12c5d1SDavid du Colombier */
24303e12c5d1SDavid du Colombier void
wract(int i)24313e12c5d1SDavid du Colombier wract(int i)
24323e12c5d1SDavid du Colombier {
24333e12c5d1SDavid du Colombier int p, p0, p1, ntimes, tred, count, j, flag;
24343e12c5d1SDavid du Colombier
24353e12c5d1SDavid du Colombier /* find the best choice for lastred */
24363e12c5d1SDavid du Colombier lastred = 0;
24373e12c5d1SDavid du Colombier ntimes = 0;
24383e12c5d1SDavid du Colombier TLOOP(j) {
24393e12c5d1SDavid du Colombier if(temp1[j] >= 0)
24403e12c5d1SDavid du Colombier continue;
24413e12c5d1SDavid du Colombier if(temp1[j]+lastred == 0)
24423e12c5d1SDavid du Colombier continue;
24433e12c5d1SDavid du Colombier /* count the number of appearances of temp1[j] */
24443e12c5d1SDavid du Colombier count = 0;
24453e12c5d1SDavid du Colombier tred = -temp1[j];
24463e12c5d1SDavid du Colombier levprd[tred] |= REDFLAG;
24473e12c5d1SDavid du Colombier TLOOP(p)
24483e12c5d1SDavid du Colombier if(temp1[p]+tred == 0)
24493e12c5d1SDavid du Colombier count++;
24503e12c5d1SDavid du Colombier if(count > ntimes) {
24513e12c5d1SDavid du Colombier lastred = tred;
24523e12c5d1SDavid du Colombier ntimes = count;
24533e12c5d1SDavid du Colombier }
24543e12c5d1SDavid du Colombier }
24553e12c5d1SDavid du Colombier
24563e12c5d1SDavid du Colombier /*
24573e12c5d1SDavid du Colombier * for error recovery, arrange that, if there is a shift on the
24583e12c5d1SDavid du Colombier * error recovery token, `error', that the default be the error action
24593e12c5d1SDavid du Colombier */
24603e12c5d1SDavid du Colombier if(temp1[2] > 0)
24613e12c5d1SDavid du Colombier lastred = 0;
24623e12c5d1SDavid du Colombier
24633e12c5d1SDavid du Colombier /* clear out entries in temp1 which equal lastred */
24643e12c5d1SDavid du Colombier TLOOP(p)
24653e12c5d1SDavid du Colombier if(temp1[p]+lastred == 0)
24663e12c5d1SDavid du Colombier temp1[p] = 0;
24673e12c5d1SDavid du Colombier
24683e12c5d1SDavid du Colombier wrstate(i);
24693e12c5d1SDavid du Colombier defact[i] = lastred;
24703e12c5d1SDavid du Colombier flag = 0;
24713e12c5d1SDavid du Colombier TLOOP(p0)
24723e12c5d1SDavid du Colombier if((p1=temp1[p0]) != 0) {
24733e12c5d1SDavid du Colombier if(p1 < 0) {
24743e12c5d1SDavid du Colombier p1 = -p1;
24753e12c5d1SDavid du Colombier goto exc;
24763e12c5d1SDavid du Colombier }
24773e12c5d1SDavid du Colombier if(p1 == ACCEPTCODE) {
24783e12c5d1SDavid du Colombier p1 = -1;
24793e12c5d1SDavid du Colombier goto exc;
24803e12c5d1SDavid du Colombier }
24813e12c5d1SDavid du Colombier if(p1 == ERRCODE) {
24823e12c5d1SDavid du Colombier p1 = 0;
24833e12c5d1SDavid du Colombier exc:
24843e12c5d1SDavid du Colombier if(flag++ == 0)
24853e12c5d1SDavid du Colombier Bprint(ftable, "-1, %d,\n", i);
24863e12c5d1SDavid du Colombier Bprint(ftable, "\t%d, %d,\n", p0, p1);
24873e12c5d1SDavid du Colombier zzexcp++;
24883e12c5d1SDavid du Colombier continue;
24893e12c5d1SDavid du Colombier }
24903e12c5d1SDavid du Colombier Bprint(ftemp, "%d,%d,", p0, p1);
24913e12c5d1SDavid du Colombier zzacent++;
24923e12c5d1SDavid du Colombier }
24933e12c5d1SDavid du Colombier if(flag) {
24943e12c5d1SDavid du Colombier defact[i] = -2;
24953e12c5d1SDavid du Colombier Bprint(ftable, "\t-2, %d,\n", lastred);
24963e12c5d1SDavid du Colombier }
24973e12c5d1SDavid du Colombier Bprint(ftemp, "\n");
24983e12c5d1SDavid du Colombier }
24993e12c5d1SDavid du Colombier
25003e12c5d1SDavid du Colombier /*
25013e12c5d1SDavid du Colombier * writes state i
25023e12c5d1SDavid du Colombier */
25033e12c5d1SDavid du Colombier void
wrstate(int i)25043e12c5d1SDavid du Colombier wrstate(int i)
25053e12c5d1SDavid du Colombier {
25063e12c5d1SDavid du Colombier int j0, j1;
25073e12c5d1SDavid du Colombier Item *pp, *qq;
25083e12c5d1SDavid du Colombier Wset *u;
25093e12c5d1SDavid du Colombier
25103e12c5d1SDavid du Colombier if(fdebug) {
25113e12c5d1SDavid du Colombier if(lastred) {
25123e12c5d1SDavid du Colombier Bprint(fdebug, " 0, /*%d*/\n", i);
25133e12c5d1SDavid du Colombier } else {
25143e12c5d1SDavid du Colombier Bprint(fdebug, " \"");
25153e12c5d1SDavid du Colombier ITMLOOP(i, pp, qq)
25163e12c5d1SDavid du Colombier Bprint(fdebug, "%s\\n", writem(pp->pitem));
25173e12c5d1SDavid du Colombier if(tystate[i] == MUSTLOOKAHEAD)
25183e12c5d1SDavid du Colombier WSLOOP(wsets + (pstate[i+1] - pstate[i]), u)
25193e12c5d1SDavid du Colombier if(*u->pitem < 0)
25203e12c5d1SDavid du Colombier Bprint(fdebug, "%s\\n", writem(u->pitem));
25213e12c5d1SDavid du Colombier Bprint(fdebug, "\", /*%d*/\n", i);
25223e12c5d1SDavid du Colombier }
25233e12c5d1SDavid du Colombier }
25243e12c5d1SDavid du Colombier if(foutput == 0)
25253e12c5d1SDavid du Colombier return;
25263e12c5d1SDavid du Colombier Bprint(foutput, "\nstate %d\n", i);
25273e12c5d1SDavid du Colombier ITMLOOP(i, pp, qq)
25283e12c5d1SDavid du Colombier Bprint(foutput, "\t%s\n", writem(pp->pitem));
25293e12c5d1SDavid du Colombier if(tystate[i] == MUSTLOOKAHEAD)
25303e12c5d1SDavid du Colombier /* print out empty productions in closure */
25313e12c5d1SDavid du Colombier WSLOOP(wsets+(pstate[i+1]-pstate[i]), u)
25323e12c5d1SDavid du Colombier if(*u->pitem < 0)
25333e12c5d1SDavid du Colombier Bprint(foutput, "\t%s\n", writem(u->pitem));
25343e12c5d1SDavid du Colombier
25353e12c5d1SDavid du Colombier /* check for state equal to another */
25363e12c5d1SDavid du Colombier TLOOP(j0)
25373e12c5d1SDavid du Colombier if((j1=temp1[j0]) != 0) {
25383e12c5d1SDavid du Colombier Bprint(foutput, "\n\t%s ", symnam(j0));
25393e12c5d1SDavid du Colombier /* shift, error, or accept */
25403e12c5d1SDavid du Colombier if(j1 > 0) {
25413e12c5d1SDavid du Colombier if(j1 == ACCEPTCODE)
25423e12c5d1SDavid du Colombier Bprint(foutput, "accept");
25433e12c5d1SDavid du Colombier else
25443e12c5d1SDavid du Colombier if(j1 == ERRCODE)
25453e12c5d1SDavid du Colombier Bprint(foutput, "error");
25463e12c5d1SDavid du Colombier else
25473e12c5d1SDavid du Colombier Bprint(foutput, "shift %d", j1);
25483e12c5d1SDavid du Colombier } else
25493e12c5d1SDavid du Colombier Bprint(foutput, "reduce %d (src line %d)", -j1, rlines[-j1]);
25503e12c5d1SDavid du Colombier }
25513e12c5d1SDavid du Colombier
25523e12c5d1SDavid du Colombier /* output the final production */
25533e12c5d1SDavid du Colombier if(lastred)
25543e12c5d1SDavid du Colombier Bprint(foutput, "\n\t. reduce %d (src line %d)\n\n",
25553e12c5d1SDavid du Colombier lastred, rlines[lastred]);
25563e12c5d1SDavid du Colombier else
25573e12c5d1SDavid du Colombier Bprint(foutput, "\n\t. error\n\n");
25583e12c5d1SDavid du Colombier
25593e12c5d1SDavid du Colombier /* now, output nonterminal actions */
25603e12c5d1SDavid du Colombier j1 = ntokens;
25613e12c5d1SDavid du Colombier for(j0 = 1; j0 <= nnonter; j0++) {
25623e12c5d1SDavid du Colombier j1++;
25633e12c5d1SDavid du Colombier if(temp1[j1])
25643e12c5d1SDavid du Colombier Bprint(foutput, "\t%s goto %d\n", symnam(j0+NTBASE), temp1[j1]);
25653e12c5d1SDavid du Colombier }
25663e12c5d1SDavid du Colombier }
25673e12c5d1SDavid du Colombier
25683e12c5d1SDavid du Colombier void
warray(char * s,int * v,int n)25693e12c5d1SDavid du Colombier warray(char *s, int *v, int n)
25703e12c5d1SDavid du Colombier {
25713e12c5d1SDavid du Colombier int i;
25723e12c5d1SDavid du Colombier
25733e12c5d1SDavid du Colombier Bprint(ftable, "short %s[] =\n{", s);
25743e12c5d1SDavid du Colombier for(i=0;;) {
25753e12c5d1SDavid du Colombier if(i%10 == 0)
25763e12c5d1SDavid du Colombier Bprint(ftable, "\n");
25773e12c5d1SDavid du Colombier Bprint(ftable, "%4d", v[i]);
25783e12c5d1SDavid du Colombier i++;
25793e12c5d1SDavid du Colombier if(i >= n) {
25803e12c5d1SDavid du Colombier Bprint(ftable, "\n};\n");
25813e12c5d1SDavid du Colombier break;
25823e12c5d1SDavid du Colombier }
25833e12c5d1SDavid du Colombier Bprint(ftable, ",");
25843e12c5d1SDavid du Colombier }
25853e12c5d1SDavid du Colombier }
25863e12c5d1SDavid du Colombier
25873e12c5d1SDavid du Colombier /*
25883e12c5d1SDavid du Colombier * in order to free up the mem and amem arrays for the optimizer,
25893e12c5d1SDavid du Colombier * and still be able to output yyr1, etc., after the sizes of
25903e12c5d1SDavid du Colombier * the action array is known, we hide the nonterminals
25913e12c5d1SDavid du Colombier * derived by productions in levprd.
25923e12c5d1SDavid du Colombier */
25933e12c5d1SDavid du Colombier
25943e12c5d1SDavid du Colombier void
hideprod(void)25953e12c5d1SDavid du Colombier hideprod(void)
25963e12c5d1SDavid du Colombier {
25973e12c5d1SDavid du Colombier int i, j;
25983e12c5d1SDavid du Colombier
25993e12c5d1SDavid du Colombier j = 0;
26003e12c5d1SDavid du Colombier levprd[0] = 0;
26013e12c5d1SDavid du Colombier PLOOP(1, i) {
26023e12c5d1SDavid du Colombier if(!(levprd[i] & REDFLAG)) {
26033e12c5d1SDavid du Colombier j++;
26043e12c5d1SDavid du Colombier if(foutput != 0)
26053e12c5d1SDavid du Colombier Bprint(foutput, "Rule not reduced: %s\n", writem(prdptr[i]));
26063e12c5d1SDavid du Colombier }
26073e12c5d1SDavid du Colombier levprd[i] = *prdptr[i] - NTBASE;
26083e12c5d1SDavid du Colombier }
26093e12c5d1SDavid du Colombier if(j)
26103e12c5d1SDavid du Colombier print("%d rules never reduced\n", j);
26113e12c5d1SDavid du Colombier }
26123e12c5d1SDavid du Colombier
26133e12c5d1SDavid du Colombier void
callopt(void)26143e12c5d1SDavid du Colombier callopt(void)
26153e12c5d1SDavid du Colombier {
26163e12c5d1SDavid du Colombier int i, *p, j, k, *q;
26173e12c5d1SDavid du Colombier
26183e12c5d1SDavid du Colombier /* read the arrays from tempfile and set parameters */
26197dd7cddfSDavid du Colombier finput = Bopen(tempname, OREAD);
26207dd7cddfSDavid du Colombier if(finput == 0)
26213e12c5d1SDavid du Colombier error("optimizer cannot open tempfile");
26227dd7cddfSDavid du Colombier
26233e12c5d1SDavid du Colombier pgo[0] = 0;
26243e12c5d1SDavid du Colombier temp1[0] = 0;
26253e12c5d1SDavid du Colombier nstate = 0;
26263e12c5d1SDavid du Colombier nnonter = 0;
26273e12c5d1SDavid du Colombier for(;;) {
26283e12c5d1SDavid du Colombier switch(gtnm()) {
26293e12c5d1SDavid du Colombier case '\n':
26303e12c5d1SDavid du Colombier nstate++;
26313e12c5d1SDavid du Colombier pmem--;
26323e12c5d1SDavid du Colombier temp1[nstate] = pmem - mem0;
26333e12c5d1SDavid du Colombier case ',':
26343e12c5d1SDavid du Colombier continue;
26353e12c5d1SDavid du Colombier case '$':
26363e12c5d1SDavid du Colombier break;
26373e12c5d1SDavid du Colombier default:
26383e12c5d1SDavid du Colombier error("bad tempfile");
26393e12c5d1SDavid du Colombier }
26403e12c5d1SDavid du Colombier break;
26413e12c5d1SDavid du Colombier }
26423e12c5d1SDavid du Colombier
26433e12c5d1SDavid du Colombier pmem--;
26443e12c5d1SDavid du Colombier temp1[nstate] = yypgo[0] = pmem - mem0;
26453e12c5d1SDavid du Colombier for(;;) {
26463e12c5d1SDavid du Colombier switch(gtnm()) {
26473e12c5d1SDavid du Colombier case '\n':
26483e12c5d1SDavid du Colombier nnonter++;
26493e12c5d1SDavid du Colombier yypgo[nnonter] = pmem-mem0;
26503e12c5d1SDavid du Colombier case ',':
26513e12c5d1SDavid du Colombier continue;
26523e12c5d1SDavid du Colombier case -1:
26533e12c5d1SDavid du Colombier break;
26543e12c5d1SDavid du Colombier default:
26553e12c5d1SDavid du Colombier error("bad tempfile");
26563e12c5d1SDavid du Colombier }
26573e12c5d1SDavid du Colombier break;
26583e12c5d1SDavid du Colombier }
26593e12c5d1SDavid du Colombier pmem--;
26603e12c5d1SDavid du Colombier yypgo[nnonter--] = pmem - mem0;
26613e12c5d1SDavid du Colombier for(i = 0; i < nstate; i++) {
26623e12c5d1SDavid du Colombier k = 32000;
26633e12c5d1SDavid du Colombier j = 0;
26643e12c5d1SDavid du Colombier q = mem0 + temp1[i+1];
26653e12c5d1SDavid du Colombier for(p = mem0 + temp1[i]; p < q ; p += 2) {
26663e12c5d1SDavid du Colombier if(*p > j)
26673e12c5d1SDavid du Colombier j = *p;
26683e12c5d1SDavid du Colombier if(*p < k)
26693e12c5d1SDavid du Colombier k = *p;
26703e12c5d1SDavid du Colombier }
26713e12c5d1SDavid du Colombier /* nontrivial situation */
26723e12c5d1SDavid du Colombier if(k <= j) {
26733e12c5d1SDavid du Colombier /* j is now the range */
26743e12c5d1SDavid du Colombier /* j -= k; /* call scj */
26753e12c5d1SDavid du Colombier if(k > maxoff)
26763e12c5d1SDavid du Colombier maxoff = k;
26773e12c5d1SDavid du Colombier }
26783e12c5d1SDavid du Colombier tystate[i] = (temp1[i+1]-temp1[i]) + 2*j;
26793e12c5d1SDavid du Colombier if(j > maxspr)
26803e12c5d1SDavid du Colombier maxspr = j;
26813e12c5d1SDavid du Colombier }
26823e12c5d1SDavid du Colombier
26833e12c5d1SDavid du Colombier /* initialize ggreed table */
26843e12c5d1SDavid du Colombier for(i = 1; i <= nnonter; i++) {
26853e12c5d1SDavid du Colombier ggreed[i] = 1;
26863e12c5d1SDavid du Colombier j = 0;
26873e12c5d1SDavid du Colombier
26883e12c5d1SDavid du Colombier /* minimum entry index is always 0 */
26893e12c5d1SDavid du Colombier q = mem0 + yypgo[i+1] - 1;
26903e12c5d1SDavid du Colombier for(p = mem0+yypgo[i]; p < q ; p += 2) {
26913e12c5d1SDavid du Colombier ggreed[i] += 2;
26923e12c5d1SDavid du Colombier if(*p > j)
26933e12c5d1SDavid du Colombier j = *p;
26943e12c5d1SDavid du Colombier }
26953e12c5d1SDavid du Colombier ggreed[i] = ggreed[i] + 2*j;
26963e12c5d1SDavid du Colombier if(j > maxoff)
26973e12c5d1SDavid du Colombier maxoff = j;
26983e12c5d1SDavid du Colombier }
26993e12c5d1SDavid du Colombier
27003e12c5d1SDavid du Colombier /* now, prepare to put the shift actions into the amem array */
27013e12c5d1SDavid du Colombier for(i = 0; i < ACTSIZE; i++)
27023e12c5d1SDavid du Colombier amem[i] = 0;
27033e12c5d1SDavid du Colombier maxa = amem;
27043e12c5d1SDavid du Colombier for(i = 0; i < nstate; i++) {
27053e12c5d1SDavid du Colombier if(tystate[i] == 0 && adb > 1)
27063e12c5d1SDavid du Colombier Bprint(ftable, "State %d: null\n", i);
27073e12c5d1SDavid du Colombier indgo[i] = YYFLAG1;
27083e12c5d1SDavid du Colombier }
27093e12c5d1SDavid du Colombier while((i = nxti()) != NOMORE)
27103e12c5d1SDavid du Colombier if(i >= 0)
27113e12c5d1SDavid du Colombier stin(i);
27123e12c5d1SDavid du Colombier else
27133e12c5d1SDavid du Colombier gin(-i);
27143e12c5d1SDavid du Colombier
27153e12c5d1SDavid du Colombier /* print amem array */
27163e12c5d1SDavid du Colombier if(adb > 2 )
27173e12c5d1SDavid du Colombier for(p = amem; p <= maxa; p += 10) {
27187dd7cddfSDavid du Colombier Bprint(ftable, "%4d ", (int)(p-amem));
27193e12c5d1SDavid du Colombier for(i = 0; i < 10; ++i)
27203e12c5d1SDavid du Colombier Bprint(ftable, "%4d ", p[i]);
27213e12c5d1SDavid du Colombier Bprint(ftable, "\n");
27223e12c5d1SDavid du Colombier }
27233e12c5d1SDavid du Colombier
27243e12c5d1SDavid du Colombier /* write out the output appropriate to the language */
27253e12c5d1SDavid du Colombier aoutput();
27263e12c5d1SDavid du Colombier osummary();
27273e12c5d1SDavid du Colombier ZAPFILE(tempname);
27283e12c5d1SDavid du Colombier }
27293e12c5d1SDavid du Colombier
27303e12c5d1SDavid du Colombier void
gin(int i)27313e12c5d1SDavid du Colombier gin(int i)
27323e12c5d1SDavid du Colombier {
27333e12c5d1SDavid du Colombier int *p, *r, *s, *q1, *q2;
27343e12c5d1SDavid du Colombier
27353e12c5d1SDavid du Colombier /* enter gotos on nonterminal i into array amem */
27363e12c5d1SDavid du Colombier ggreed[i] = 0;
27373e12c5d1SDavid du Colombier
27383e12c5d1SDavid du Colombier q2 = mem0+ yypgo[i+1] - 1;
27393e12c5d1SDavid du Colombier q1 = mem0 + yypgo[i];
27403e12c5d1SDavid du Colombier
27413e12c5d1SDavid du Colombier /* now, find amem place for it */
27423e12c5d1SDavid du Colombier for(p = amem; p < &amem[ACTSIZE]; p++) {
27433e12c5d1SDavid du Colombier if(*p)
27443e12c5d1SDavid du Colombier continue;
27453e12c5d1SDavid du Colombier for(r = q1; r < q2; r += 2) {
27463e12c5d1SDavid du Colombier s = p + *r + 1;
27473e12c5d1SDavid du Colombier if(*s)
27483e12c5d1SDavid du Colombier goto nextgp;
27493e12c5d1SDavid du Colombier if(s > maxa)
27503e12c5d1SDavid du Colombier if((maxa = s) > &amem[ACTSIZE])
27513e12c5d1SDavid du Colombier error("a array overflow");
27523e12c5d1SDavid du Colombier }
27533e12c5d1SDavid du Colombier /* we have found amem spot */
27543e12c5d1SDavid du Colombier *p = *q2;
27553e12c5d1SDavid du Colombier if(p > maxa)
27563e12c5d1SDavid du Colombier if((maxa = p) > &amem[ACTSIZE])
27573e12c5d1SDavid du Colombier error("a array overflow");
27583e12c5d1SDavid du Colombier for(r = q1; r < q2; r += 2) {
27593e12c5d1SDavid du Colombier s = p + *r + 1;
27603e12c5d1SDavid du Colombier *s = r[1];
27613e12c5d1SDavid du Colombier }
27623e12c5d1SDavid du Colombier pgo[i] = p-amem;
27633e12c5d1SDavid du Colombier if(adb > 1)
27643e12c5d1SDavid du Colombier Bprint(ftable, "Nonterminal %d, entry at %d\n", i, pgo[i]);
27653e12c5d1SDavid du Colombier return;
27663e12c5d1SDavid du Colombier
27673e12c5d1SDavid du Colombier nextgp:;
27683e12c5d1SDavid du Colombier }
27693e12c5d1SDavid du Colombier error("cannot place goto %d\n", i);
27703e12c5d1SDavid du Colombier }
27713e12c5d1SDavid du Colombier
27723e12c5d1SDavid du Colombier void
stin(int i)27733e12c5d1SDavid du Colombier stin(int i)
27743e12c5d1SDavid du Colombier {
27753e12c5d1SDavid du Colombier int *r, *s, n, flag, j, *q1, *q2;
27763e12c5d1SDavid du Colombier
27773e12c5d1SDavid du Colombier tystate[i] = 0;
27783e12c5d1SDavid du Colombier
27793e12c5d1SDavid du Colombier /* enter state i into the amem array */
27803e12c5d1SDavid du Colombier q2 = mem0+temp1[i+1];
27813e12c5d1SDavid du Colombier q1 = mem0+temp1[i];
27823e12c5d1SDavid du Colombier /* find an acceptable place */
27833e12c5d1SDavid du Colombier for(n = -maxoff; n < ACTSIZE; n++) {
27843e12c5d1SDavid du Colombier flag = 0;
27853e12c5d1SDavid du Colombier for(r = q1; r < q2; r += 2) {
27863e12c5d1SDavid du Colombier if((s = *r + n + amem) < amem)
27873e12c5d1SDavid du Colombier goto nextn;
27883e12c5d1SDavid du Colombier if(*s == 0)
27893e12c5d1SDavid du Colombier flag++;
27903e12c5d1SDavid du Colombier else
27913e12c5d1SDavid du Colombier if(*s != r[1])
27923e12c5d1SDavid du Colombier goto nextn;
27933e12c5d1SDavid du Colombier }
27943e12c5d1SDavid du Colombier
27953e12c5d1SDavid du Colombier /* check that the position equals another only if the states are identical */
27963e12c5d1SDavid du Colombier for(j=0; j<nstate; j++) {
27973e12c5d1SDavid du Colombier if(indgo[j] == n) {
27983e12c5d1SDavid du Colombier
27993e12c5d1SDavid du Colombier /* we have some disagreement */
28003e12c5d1SDavid du Colombier if(flag)
28013e12c5d1SDavid du Colombier goto nextn;
28023e12c5d1SDavid du Colombier if(temp1[j+1]+temp1[i] == temp1[j]+temp1[i+1]) {
28033e12c5d1SDavid du Colombier
28043e12c5d1SDavid du Colombier /* states are equal */
28053e12c5d1SDavid du Colombier indgo[i] = n;
28063e12c5d1SDavid du Colombier if(adb > 1)
28073e12c5d1SDavid du Colombier Bprint(ftable,
28083e12c5d1SDavid du Colombier "State %d: entry at %d equals state %d\n",
28093e12c5d1SDavid du Colombier i, n, j);
28103e12c5d1SDavid du Colombier return;
28113e12c5d1SDavid du Colombier }
28123e12c5d1SDavid du Colombier
28133e12c5d1SDavid du Colombier /* we have some disagreement */
28143e12c5d1SDavid du Colombier goto nextn;
28153e12c5d1SDavid du Colombier }
28163e12c5d1SDavid du Colombier }
28173e12c5d1SDavid du Colombier
28183e12c5d1SDavid du Colombier for(r = q1; r < q2; r += 2) {
28193e12c5d1SDavid du Colombier if((s = *r+n+amem) >= &amem[ACTSIZE])
28203e12c5d1SDavid du Colombier error("out of space in optimizer a array");
28213e12c5d1SDavid du Colombier if(s > maxa)
28223e12c5d1SDavid du Colombier maxa = s;
28233e12c5d1SDavid du Colombier if(*s != 0 && *s != r[1])
28243e12c5d1SDavid du Colombier error("clobber of a array, pos'n %d, by %d", s-amem, r[1]);
28253e12c5d1SDavid du Colombier *s = r[1];
28263e12c5d1SDavid du Colombier }
28273e12c5d1SDavid du Colombier indgo[i] = n;
28283e12c5d1SDavid du Colombier if(adb > 1)
28293e12c5d1SDavid du Colombier Bprint(ftable, "State %d: entry at %d\n", i, indgo[i]);
28303e12c5d1SDavid du Colombier return;
28313e12c5d1SDavid du Colombier nextn:;
28323e12c5d1SDavid du Colombier }
28333e12c5d1SDavid du Colombier error("Error; failure to place state %d\n", i);
28343e12c5d1SDavid du Colombier }
28353e12c5d1SDavid du Colombier
28363e12c5d1SDavid du Colombier /*
28373e12c5d1SDavid du Colombier * finds the next i
28383e12c5d1SDavid du Colombier */
28393e12c5d1SDavid du Colombier int
nxti(void)28403e12c5d1SDavid du Colombier nxti(void)
28413e12c5d1SDavid du Colombier {
28423e12c5d1SDavid du Colombier int i, max, maxi;
28433e12c5d1SDavid du Colombier
28443e12c5d1SDavid du Colombier max = 0;
28453e12c5d1SDavid du Colombier maxi = 0;
28463e12c5d1SDavid du Colombier for(i = 1; i <= nnonter; i++)
28473e12c5d1SDavid du Colombier if(ggreed[i] >= max) {
28483e12c5d1SDavid du Colombier max = ggreed[i];
28493e12c5d1SDavid du Colombier maxi = -i;
28503e12c5d1SDavid du Colombier }
28513e12c5d1SDavid du Colombier for(i = 0; i < nstate; ++i)
28523e12c5d1SDavid du Colombier if(tystate[i] >= max) {
28533e12c5d1SDavid du Colombier max = tystate[i];
28543e12c5d1SDavid du Colombier maxi = i;
28553e12c5d1SDavid du Colombier }
28563e12c5d1SDavid du Colombier if(nxdb)
28573e12c5d1SDavid du Colombier Bprint(ftable, "nxti = %d, max = %d\n", maxi, max);
28583e12c5d1SDavid du Colombier if(max == 0)
28593e12c5d1SDavid du Colombier return NOMORE;
28603e12c5d1SDavid du Colombier return maxi;
28613e12c5d1SDavid du Colombier }
28623e12c5d1SDavid du Colombier
28633e12c5d1SDavid du Colombier /*
28643e12c5d1SDavid du Colombier * write summary
28653e12c5d1SDavid du Colombier */
28663e12c5d1SDavid du Colombier void
osummary(void)28673e12c5d1SDavid du Colombier osummary(void)
28683e12c5d1SDavid du Colombier {
28693e12c5d1SDavid du Colombier
28703e12c5d1SDavid du Colombier int i, *p;
28713e12c5d1SDavid du Colombier
28723e12c5d1SDavid du Colombier if(foutput == 0)
28733e12c5d1SDavid du Colombier return;
28743e12c5d1SDavid du Colombier i = 0;
28753e12c5d1SDavid du Colombier for(p = maxa; p >= amem; p--)
28763e12c5d1SDavid du Colombier if(*p == 0)
28773e12c5d1SDavid du Colombier i++;
28783e12c5d1SDavid du Colombier
28793e12c5d1SDavid du Colombier Bprint(foutput, "Optimizer space used: input %d/%d, output %d/%d\n",
28807dd7cddfSDavid du Colombier (int)(pmem-mem0+1), MEMSIZE, (int)(maxa-amem+1), ACTSIZE);
28817dd7cddfSDavid du Colombier Bprint(foutput, "%d table entries, %d zero\n", (int)(maxa-amem+1), i);
28823e12c5d1SDavid du Colombier Bprint(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff);
28833e12c5d1SDavid du Colombier }
28843e12c5d1SDavid du Colombier
28853e12c5d1SDavid du Colombier /*
28863e12c5d1SDavid du Colombier * this version is for C
28873e12c5d1SDavid du Colombier * write out the optimized parser
28883e12c5d1SDavid du Colombier */
28893e12c5d1SDavid du Colombier void
aoutput(void)28903e12c5d1SDavid du Colombier aoutput(void)
28913e12c5d1SDavid du Colombier {
28927dd7cddfSDavid du Colombier Bprint(ftable, "#define\tYYLAST\t%d\n", (int)(maxa-amem+1));
28933e12c5d1SDavid du Colombier arout("yyact", amem, (maxa-amem)+1);
28943e12c5d1SDavid du Colombier arout("yypact", indgo, nstate);
28953e12c5d1SDavid du Colombier arout("yypgo", pgo, nnonter+1);
28963e12c5d1SDavid du Colombier }
28973e12c5d1SDavid du Colombier
28983e12c5d1SDavid du Colombier void
arout(char * s,int * v,int n)28993e12c5d1SDavid du Colombier arout(char *s, int *v, int n)
29003e12c5d1SDavid du Colombier {
29013e12c5d1SDavid du Colombier int i;
29023e12c5d1SDavid du Colombier
29033e12c5d1SDavid du Colombier Bprint(ftable, "short %s[] =\n{", s);
29043e12c5d1SDavid du Colombier for(i = 0; i < n;) {
29053e12c5d1SDavid du Colombier if(i%10 == 0)
29063e12c5d1SDavid du Colombier Bprint(ftable, "\n");
29073e12c5d1SDavid du Colombier Bprint(ftable, "%4d", v[i]);
29083e12c5d1SDavid du Colombier i++;
29093e12c5d1SDavid du Colombier if(i == n)
29103e12c5d1SDavid du Colombier Bprint(ftable, "\n};\n");
29113e12c5d1SDavid du Colombier else
29123e12c5d1SDavid du Colombier Bprint(ftable, ",");
29133e12c5d1SDavid du Colombier }
29143e12c5d1SDavid du Colombier }
29153e12c5d1SDavid du Colombier
29163e12c5d1SDavid du Colombier /*
29173e12c5d1SDavid du Colombier * read and convert an integer from the standard input
29183e12c5d1SDavid du Colombier * return the terminating character
29193e12c5d1SDavid du Colombier * blanks, tabs, and newlines are ignored
29203e12c5d1SDavid du Colombier */
29213e12c5d1SDavid du Colombier int
gtnm(void)29223e12c5d1SDavid du Colombier gtnm(void)
29233e12c5d1SDavid du Colombier {
29247dd7cddfSDavid du Colombier int sign, val, c;
29253e12c5d1SDavid du Colombier
29267dd7cddfSDavid du Colombier sign = 0;
29273e12c5d1SDavid du Colombier val = 0;
29283e12c5d1SDavid du Colombier while((c=Bgetrune(finput)) != Beof) {
29297dd7cddfSDavid du Colombier if(isdigit(c)) {
29303e12c5d1SDavid du Colombier val = val*10 + c-'0';
29317dd7cddfSDavid du Colombier continue;
29327dd7cddfSDavid du Colombier }
29337dd7cddfSDavid du Colombier if(c == '-') {
29347dd7cddfSDavid du Colombier sign = 1;
29357dd7cddfSDavid du Colombier continue;
29367dd7cddfSDavid du Colombier }
29373e12c5d1SDavid du Colombier break;
29383e12c5d1SDavid du Colombier }
29397dd7cddfSDavid du Colombier if(sign)
29407dd7cddfSDavid du Colombier val = -val;
29417dd7cddfSDavid du Colombier *pmem++ = val;
29427dd7cddfSDavid du Colombier if(pmem >= &mem0[MEMSIZE])
29433e12c5d1SDavid du Colombier error("out of space");
29443e12c5d1SDavid du Colombier return c;
29453e12c5d1SDavid du Colombier }
2946