1*18eb7a2dSCharles.Forsyth #include <lib9.h>
2*18eb7a2dSCharles.Forsyth #include <bio.h>
3*18eb7a2dSCharles.Forsyth #include <ctype.h>
4*18eb7a2dSCharles.Forsyth
5*18eb7a2dSCharles.Forsyth #define Bungetrune Bungetc /* ok for now. */
6*18eb7a2dSCharles.Forsyth
7*18eb7a2dSCharles.Forsyth /*
8*18eb7a2dSCharles.Forsyth * all these are 32 bit
9*18eb7a2dSCharles.Forsyth */
10*18eb7a2dSCharles.Forsyth #define TBITSET ((32+NTERMS)/32) /* BOTCH?? +31 */
11*18eb7a2dSCharles.Forsyth #define BIT(a,i) ((a)[(i)>>5] & (1<<((i)&037)))
12*18eb7a2dSCharles.Forsyth #define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037)))
13*18eb7a2dSCharles.Forsyth #define NWORDS(n) (((n)+32)/32)
14*18eb7a2dSCharles.Forsyth
15*18eb7a2dSCharles.Forsyth #ifndef PARSER
16*18eb7a2dSCharles.Forsyth #define PARSER "yaccpar"
17*18eb7a2dSCharles.Forsyth #define PARSERS "yaccpars"
18*18eb7a2dSCharles.Forsyth #endif
19*18eb7a2dSCharles.Forsyth #define TEMPNAME "y.tmp.XXXXXX"
20*18eb7a2dSCharles.Forsyth #define ACTNAME "y.acts.XXXXXX"
21*18eb7a2dSCharles.Forsyth #define OFILE "tab.c"
22*18eb7a2dSCharles.Forsyth #define FILEU "output"
23*18eb7a2dSCharles.Forsyth #define FILED "tab.h"
24*18eb7a2dSCharles.Forsyth #define FILEDEBUG "debug"
25*18eb7a2dSCharles.Forsyth
26*18eb7a2dSCharles.Forsyth enum
27*18eb7a2dSCharles.Forsyth {
28*18eb7a2dSCharles.Forsyth /*
29*18eb7a2dSCharles.Forsyth * the following are adjustable
30*18eb7a2dSCharles.Forsyth * according to memory size
31*18eb7a2dSCharles.Forsyth */
32*18eb7a2dSCharles.Forsyth ACTSIZE = 30000,
33*18eb7a2dSCharles.Forsyth MEMSIZE = 30000,
34*18eb7a2dSCharles.Forsyth NSTATES = 2000,
35*18eb7a2dSCharles.Forsyth NTERMS = 255,
36*18eb7a2dSCharles.Forsyth NPROD = 800,
37*18eb7a2dSCharles.Forsyth NNONTERM = 300,
38*18eb7a2dSCharles.Forsyth TEMPSIZE = 2000,
39*18eb7a2dSCharles.Forsyth CNAMSZ = 5000,
40*18eb7a2dSCharles.Forsyth LSETSIZE = 2400,
41*18eb7a2dSCharles.Forsyth WSETSIZE = 350,
42*18eb7a2dSCharles.Forsyth
43*18eb7a2dSCharles.Forsyth NAMESIZE = 50,
44*18eb7a2dSCharles.Forsyth NTYPES = 63,
45*18eb7a2dSCharles.Forsyth ISIZE = 400,
46*18eb7a2dSCharles.Forsyth
47*18eb7a2dSCharles.Forsyth PRIVATE = 0xE000, /* unicode private use */
48*18eb7a2dSCharles.Forsyth
49*18eb7a2dSCharles.Forsyth /* relationships which must hold:
50*18eb7a2dSCharles.Forsyth TBITSET ints must hold NTERMS+1 bits...
51*18eb7a2dSCharles.Forsyth WSETSIZE >= NNONTERM
52*18eb7a2dSCharles.Forsyth LSETSIZE >= NNONTERM
53*18eb7a2dSCharles.Forsyth TEMPSIZE >= NTERMS + NNONTERM + 1
54*18eb7a2dSCharles.Forsyth TEMPSIZE >= NSTATES
55*18eb7a2dSCharles.Forsyth */
56*18eb7a2dSCharles.Forsyth
57*18eb7a2dSCharles.Forsyth NTBASE = 010000,
58*18eb7a2dSCharles.Forsyth ERRCODE = 8190,
59*18eb7a2dSCharles.Forsyth ACCEPTCODE = 8191,
60*18eb7a2dSCharles.Forsyth
61*18eb7a2dSCharles.Forsyth NOASC = 0, /* no assoc. */
62*18eb7a2dSCharles.Forsyth LASC = 1, /* left assoc. */
63*18eb7a2dSCharles.Forsyth RASC = 2, /* right assoc. */
64*18eb7a2dSCharles.Forsyth BASC = 3, /* binary assoc. */
65*18eb7a2dSCharles.Forsyth
66*18eb7a2dSCharles.Forsyth /* flags for state generation */
67*18eb7a2dSCharles.Forsyth
68*18eb7a2dSCharles.Forsyth DONE = 0,
69*18eb7a2dSCharles.Forsyth MUSTDO = 1,
70*18eb7a2dSCharles.Forsyth MUSTLOOKAHEAD = 2,
71*18eb7a2dSCharles.Forsyth
72*18eb7a2dSCharles.Forsyth /* flags for a rule having an action, and being reduced */
73*18eb7a2dSCharles.Forsyth
74*18eb7a2dSCharles.Forsyth ACTFLAG = 04,
75*18eb7a2dSCharles.Forsyth REDFLAG = 010,
76*18eb7a2dSCharles.Forsyth
77*18eb7a2dSCharles.Forsyth /* output parser flags */
78*18eb7a2dSCharles.Forsyth YYFLAG1 = -1000,
79*18eb7a2dSCharles.Forsyth
80*18eb7a2dSCharles.Forsyth /* parse tokens */
81*18eb7a2dSCharles.Forsyth IDENTIFIER = PRIVATE,
82*18eb7a2dSCharles.Forsyth MARK,
83*18eb7a2dSCharles.Forsyth TERM,
84*18eb7a2dSCharles.Forsyth LEFT,
85*18eb7a2dSCharles.Forsyth RIGHT,
86*18eb7a2dSCharles.Forsyth BINARY,
87*18eb7a2dSCharles.Forsyth PREC,
88*18eb7a2dSCharles.Forsyth LCURLY,
89*18eb7a2dSCharles.Forsyth IDENTCOLON,
90*18eb7a2dSCharles.Forsyth NUMBER,
91*18eb7a2dSCharles.Forsyth START,
92*18eb7a2dSCharles.Forsyth TYPEDEF,
93*18eb7a2dSCharles.Forsyth TYPENAME,
94*18eb7a2dSCharles.Forsyth UNION,
95*18eb7a2dSCharles.Forsyth
96*18eb7a2dSCharles.Forsyth ENDFILE = 0,
97*18eb7a2dSCharles.Forsyth
98*18eb7a2dSCharles.Forsyth EMPTY = 1,
99*18eb7a2dSCharles.Forsyth WHOKNOWS = 0,
100*18eb7a2dSCharles.Forsyth OK = 1,
101*18eb7a2dSCharles.Forsyth NOMORE = -1000,
102*18eb7a2dSCharles.Forsyth };
103*18eb7a2dSCharles.Forsyth
104*18eb7a2dSCharles.Forsyth /* macros for getting associativity and precedence levels */
105*18eb7a2dSCharles.Forsyth
106*18eb7a2dSCharles.Forsyth #define ASSOC(i) ((i)&03)
107*18eb7a2dSCharles.Forsyth #define PLEVEL(i) (((i)>>4)&077)
108*18eb7a2dSCharles.Forsyth #define TYPE(i) (((i)>>10)&077)
109*18eb7a2dSCharles.Forsyth
110*18eb7a2dSCharles.Forsyth /* macros for setting associativity and precedence levels */
111*18eb7a2dSCharles.Forsyth
112*18eb7a2dSCharles.Forsyth #define SETASC(i,j) i |= j
113*18eb7a2dSCharles.Forsyth #define SETPLEV(i,j) i |= (j<<4)
114*18eb7a2dSCharles.Forsyth #define SETTYPE(i,j) i |= (j<<10)
115*18eb7a2dSCharles.Forsyth
116*18eb7a2dSCharles.Forsyth /* looping macros */
117*18eb7a2dSCharles.Forsyth
118*18eb7a2dSCharles.Forsyth #define TLOOP(i) for(i=1; i<=ntokens; i++)
119*18eb7a2dSCharles.Forsyth #define NTLOOP(i) for(i=0; i<=nnonter; i++)
120*18eb7a2dSCharles.Forsyth #define PLOOP(s,i) for(i=s; i<nprod; i++)
121*18eb7a2dSCharles.Forsyth #define SLOOP(i) for(i=0; i<nstate; i++)
122*18eb7a2dSCharles.Forsyth #define WSBUMP(x) x++
123*18eb7a2dSCharles.Forsyth #define WSLOOP(s,j) for(j=s; j<cwp; j++)
124*18eb7a2dSCharles.Forsyth #define ITMLOOP(i,p,q) for(q=pstate[i+1], p=pstate[i]; p<q; p++)
125*18eb7a2dSCharles.Forsyth #define SETLOOP(i) for(i=0; i<tbitset; i++)
126*18eb7a2dSCharles.Forsyth
127*18eb7a2dSCharles.Forsyth /* command to clobber tempfiles after use */
128*18eb7a2dSCharles.Forsyth
129*18eb7a2dSCharles.Forsyth #define ZAPFILE(x) if(x) remove(x)
130*18eb7a2dSCharles.Forsyth
131*18eb7a2dSCharles.Forsyth /* I/O descriptors */
132*18eb7a2dSCharles.Forsyth
133*18eb7a2dSCharles.Forsyth Biobuf* faction; /* file for saving actions */
134*18eb7a2dSCharles.Forsyth Biobuf* fdefine; /* file for #defines */
135*18eb7a2dSCharles.Forsyth Biobuf* fdebug; /* y.debug for strings for debugging */
136*18eb7a2dSCharles.Forsyth Biobuf* ftable; /* y.tab.c file */
137*18eb7a2dSCharles.Forsyth Biobuf* ftemp; /* tempfile to pass 2 */
138*18eb7a2dSCharles.Forsyth Biobuf* finput; /* input file */
139*18eb7a2dSCharles.Forsyth Biobuf* foutput; /* y.output file */
140*18eb7a2dSCharles.Forsyth
141*18eb7a2dSCharles.Forsyth /* communication variables between various I/O routines */
142*18eb7a2dSCharles.Forsyth
143*18eb7a2dSCharles.Forsyth char* infile; /* input file name */
144*18eb7a2dSCharles.Forsyth int numbval; /* value of an input number */
145*18eb7a2dSCharles.Forsyth char tokname[NAMESIZE+4]; /* input token name, slop for runes and 0 */
146*18eb7a2dSCharles.Forsyth
147*18eb7a2dSCharles.Forsyth /* structure declarations */
148*18eb7a2dSCharles.Forsyth
149*18eb7a2dSCharles.Forsyth typedef
150*18eb7a2dSCharles.Forsyth struct
151*18eb7a2dSCharles.Forsyth {
152*18eb7a2dSCharles.Forsyth int lset[TBITSET];
153*18eb7a2dSCharles.Forsyth } Lkset;
154*18eb7a2dSCharles.Forsyth
155*18eb7a2dSCharles.Forsyth typedef
156*18eb7a2dSCharles.Forsyth struct
157*18eb7a2dSCharles.Forsyth {
158*18eb7a2dSCharles.Forsyth int* pitem;
159*18eb7a2dSCharles.Forsyth Lkset* look;
160*18eb7a2dSCharles.Forsyth } Item;
161*18eb7a2dSCharles.Forsyth
162*18eb7a2dSCharles.Forsyth typedef
163*18eb7a2dSCharles.Forsyth struct
164*18eb7a2dSCharles.Forsyth {
165*18eb7a2dSCharles.Forsyth char* name;
166*18eb7a2dSCharles.Forsyth int value;
167*18eb7a2dSCharles.Forsyth } Symb;
168*18eb7a2dSCharles.Forsyth
169*18eb7a2dSCharles.Forsyth typedef
170*18eb7a2dSCharles.Forsyth struct
171*18eb7a2dSCharles.Forsyth {
172*18eb7a2dSCharles.Forsyth int* pitem;
173*18eb7a2dSCharles.Forsyth int flag;
174*18eb7a2dSCharles.Forsyth Lkset ws;
175*18eb7a2dSCharles.Forsyth } Wset;
176*18eb7a2dSCharles.Forsyth
177*18eb7a2dSCharles.Forsyth /* storage of names */
178*18eb7a2dSCharles.Forsyth
179*18eb7a2dSCharles.Forsyth char cnames[CNAMSZ]; /* place where token and nonterminal names are stored */
180*18eb7a2dSCharles.Forsyth int cnamsz = CNAMSZ; /* size of cnames */
181*18eb7a2dSCharles.Forsyth char* cnamp = cnames; /* place where next name is to be put in */
182*18eb7a2dSCharles.Forsyth int ndefout = 4; /* number of defined symbols output */
183*18eb7a2dSCharles.Forsyth char* tempname;
184*18eb7a2dSCharles.Forsyth char* actname;
185*18eb7a2dSCharles.Forsyth char ttempname[] = TEMPNAME;
186*18eb7a2dSCharles.Forsyth char tactname[] = ACTNAME;
187*18eb7a2dSCharles.Forsyth char* parser = PARSER;
188*18eb7a2dSCharles.Forsyth char* yydebug;
189*18eb7a2dSCharles.Forsyth char par[256]; /* full path of parser */
190*18eb7a2dSCharles.Forsyth
191*18eb7a2dSCharles.Forsyth /* storage of types */
192*18eb7a2dSCharles.Forsyth int ntypes; /* number of types defined */
193*18eb7a2dSCharles.Forsyth char* typeset[NTYPES]; /* pointers to type tags */
194*18eb7a2dSCharles.Forsyth
195*18eb7a2dSCharles.Forsyth /* token information */
196*18eb7a2dSCharles.Forsyth
197*18eb7a2dSCharles.Forsyth int ntokens = 0 ; /* number of tokens */
198*18eb7a2dSCharles.Forsyth Symb tokset[NTERMS];
199*18eb7a2dSCharles.Forsyth int toklev[NTERMS]; /* vector with the precedence of the terminals */
200*18eb7a2dSCharles.Forsyth
201*18eb7a2dSCharles.Forsyth /* nonterminal information */
202*18eb7a2dSCharles.Forsyth
203*18eb7a2dSCharles.Forsyth int nnonter = -1; /* the number of nonterminals */
204*18eb7a2dSCharles.Forsyth Symb nontrst[NNONTERM];
205*18eb7a2dSCharles.Forsyth int start; /* start symbol */
206*18eb7a2dSCharles.Forsyth
207*18eb7a2dSCharles.Forsyth /* assigned token type values */
208*18eb7a2dSCharles.Forsyth int extval = 0;
209*18eb7a2dSCharles.Forsyth
210*18eb7a2dSCharles.Forsyth char* ytabc = OFILE; /* name of y.tab.c */
211*18eb7a2dSCharles.Forsyth
212*18eb7a2dSCharles.Forsyth /* grammar rule information */
213*18eb7a2dSCharles.Forsyth
214*18eb7a2dSCharles.Forsyth int mem0[MEMSIZE] ; /* production storage */
215*18eb7a2dSCharles.Forsyth int* mem = mem0;
216*18eb7a2dSCharles.Forsyth int nprod = 1; /* number of productions */
217*18eb7a2dSCharles.Forsyth int* prdptr[NPROD]; /* pointers to descriptions of productions */
218*18eb7a2dSCharles.Forsyth int levprd[NPROD]; /* precedence levels for the productions */
219*18eb7a2dSCharles.Forsyth int rlines[NPROD]; /* line number for this rule */
220*18eb7a2dSCharles.Forsyth
221*18eb7a2dSCharles.Forsyth /* state information */
222*18eb7a2dSCharles.Forsyth
223*18eb7a2dSCharles.Forsyth int nstate = 0; /* number of states */
224*18eb7a2dSCharles.Forsyth Item* pstate[NSTATES+2]; /* pointers to the descriptions of the states */
225*18eb7a2dSCharles.Forsyth int tystate[NSTATES]; /* contains type information about the states */
226*18eb7a2dSCharles.Forsyth int defact[NSTATES]; /* the default actions of states */
227*18eb7a2dSCharles.Forsyth int tstates[NTERMS]; /* states generated by terminal gotos */
228*18eb7a2dSCharles.Forsyth int ntstates[NNONTERM]; /* states generated by nonterminal gotos */
229*18eb7a2dSCharles.Forsyth int mstates[NSTATES]; /* chain of overflows of term/nonterm generation lists */
230*18eb7a2dSCharles.Forsyth int lastred; /* the number of the last reduction of a state */
231*18eb7a2dSCharles.Forsyth
232*18eb7a2dSCharles.Forsyth /* lookahead set information */
233*18eb7a2dSCharles.Forsyth
234*18eb7a2dSCharles.Forsyth Lkset lkst[LSETSIZE];
235*18eb7a2dSCharles.Forsyth int nolook; /* flag to turn off lookahead computations */
236*18eb7a2dSCharles.Forsyth int tbitset; /* size of lookahead sets */
237*18eb7a2dSCharles.Forsyth int nlset = 0; /* next lookahead set index */
238*18eb7a2dSCharles.Forsyth int nolook = 0; /* flag to suppress lookahead computations */
239*18eb7a2dSCharles.Forsyth Lkset clset; /* temporary storage for lookahead computations */
240*18eb7a2dSCharles.Forsyth
241*18eb7a2dSCharles.Forsyth /* working set information */
242*18eb7a2dSCharles.Forsyth
243*18eb7a2dSCharles.Forsyth Wset wsets[WSETSIZE];
244*18eb7a2dSCharles.Forsyth Wset* cwp;
245*18eb7a2dSCharles.Forsyth
246*18eb7a2dSCharles.Forsyth /* storage for action table */
247*18eb7a2dSCharles.Forsyth
248*18eb7a2dSCharles.Forsyth int amem[ACTSIZE]; /* action table storage */
249*18eb7a2dSCharles.Forsyth int* memp = amem; /* next free action table position */
250*18eb7a2dSCharles.Forsyth int indgo[NSTATES]; /* index to the stored goto table */
251*18eb7a2dSCharles.Forsyth
252*18eb7a2dSCharles.Forsyth /* temporary vector, indexable by states, terms, or ntokens */
253*18eb7a2dSCharles.Forsyth
254*18eb7a2dSCharles.Forsyth int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */
255*18eb7a2dSCharles.Forsyth int lineno = 1; /* current input line number */
256*18eb7a2dSCharles.Forsyth int fatfl = 1; /* if on, error is fatal */
257*18eb7a2dSCharles.Forsyth int nerrors = 0; /* number of errors */
258*18eb7a2dSCharles.Forsyth
259*18eb7a2dSCharles.Forsyth /* statistics collection variables */
260*18eb7a2dSCharles.Forsyth
261*18eb7a2dSCharles.Forsyth int zzgoent;
262*18eb7a2dSCharles.Forsyth int zzgobest;
263*18eb7a2dSCharles.Forsyth int zzacent;
264*18eb7a2dSCharles.Forsyth int zzexcp;
265*18eb7a2dSCharles.Forsyth int zzclose;
266*18eb7a2dSCharles.Forsyth int zzrrconf;
267*18eb7a2dSCharles.Forsyth int zzsrconf;
268*18eb7a2dSCharles.Forsyth
269*18eb7a2dSCharles.Forsyth int* ggreed = lkst[0].lset;
270*18eb7a2dSCharles.Forsyth int* pgo = wsets[0].ws.lset;
271*18eb7a2dSCharles.Forsyth int* yypgo = &nontrst[0].value;
272*18eb7a2dSCharles.Forsyth
273*18eb7a2dSCharles.Forsyth int maxspr = 0; /* maximum spread of any entry */
274*18eb7a2dSCharles.Forsyth int maxoff = 0; /* maximum offset into a array */
275*18eb7a2dSCharles.Forsyth int* pmem = mem0;
276*18eb7a2dSCharles.Forsyth int* maxa;
277*18eb7a2dSCharles.Forsyth int nxdb = 0;
278*18eb7a2dSCharles.Forsyth int adb = 0;
279*18eb7a2dSCharles.Forsyth
280*18eb7a2dSCharles.Forsyth
281*18eb7a2dSCharles.Forsyth /* storage for information about the nonterminals */
282*18eb7a2dSCharles.Forsyth
283*18eb7a2dSCharles.Forsyth int** pres[NNONTERM+2]; /* vector of pointers to productions yielding each nonterminal */
284*18eb7a2dSCharles.Forsyth Lkset* pfirst[NNONTERM+2]; /* vector of pointers to first sets for each nonterminal */
285*18eb7a2dSCharles.Forsyth int pempty[NNONTERM+1]; /* vector of nonterminals nontrivially deriving e */
286*18eb7a2dSCharles.Forsyth
287*18eb7a2dSCharles.Forsyth /* random stuff picked out from between functions */
288*18eb7a2dSCharles.Forsyth
289*18eb7a2dSCharles.Forsyth int indebug = 0;
290*18eb7a2dSCharles.Forsyth Wset* zzcwp = wsets;
291*18eb7a2dSCharles.Forsyth int zzgoent = 0;
292*18eb7a2dSCharles.Forsyth int zzgobest = 0;
293*18eb7a2dSCharles.Forsyth int zzacent = 0;
294*18eb7a2dSCharles.Forsyth int zzexcp = 0;
295*18eb7a2dSCharles.Forsyth int zzclose = 0;
296*18eb7a2dSCharles.Forsyth int zzsrconf = 0;
297*18eb7a2dSCharles.Forsyth int* zzmemsz = mem0;
298*18eb7a2dSCharles.Forsyth int zzrrconf = 0;
299*18eb7a2dSCharles.Forsyth int pidebug = 0; /* debugging flag for putitem */
300*18eb7a2dSCharles.Forsyth int gsdebug = 0;
301*18eb7a2dSCharles.Forsyth int cldebug = 0; /* debugging flag for closure */
302*18eb7a2dSCharles.Forsyth int pkdebug = 0;
303*18eb7a2dSCharles.Forsyth int g2debug = 0;
304*18eb7a2dSCharles.Forsyth
305*18eb7a2dSCharles.Forsyth struct
306*18eb7a2dSCharles.Forsyth {
307*18eb7a2dSCharles.Forsyth char* name;
308*18eb7a2dSCharles.Forsyth long value;
309*18eb7a2dSCharles.Forsyth } resrv[] =
310*18eb7a2dSCharles.Forsyth {
311*18eb7a2dSCharles.Forsyth "binary", BINARY,
312*18eb7a2dSCharles.Forsyth "left", LEFT,
313*18eb7a2dSCharles.Forsyth "nonassoc", BINARY,
314*18eb7a2dSCharles.Forsyth "prec", PREC,
315*18eb7a2dSCharles.Forsyth "right", RIGHT,
316*18eb7a2dSCharles.Forsyth "start", START,
317*18eb7a2dSCharles.Forsyth "term", TERM,
318*18eb7a2dSCharles.Forsyth "token", TERM,
319*18eb7a2dSCharles.Forsyth "type", TYPEDEF,
320*18eb7a2dSCharles.Forsyth "union", UNION,
321*18eb7a2dSCharles.Forsyth 0,
322*18eb7a2dSCharles.Forsyth };
323*18eb7a2dSCharles.Forsyth
324*18eb7a2dSCharles.Forsyth /* define functions */
325*18eb7a2dSCharles.Forsyth
326*18eb7a2dSCharles.Forsyth void main(int, char**);
327*18eb7a2dSCharles.Forsyth void others(void);
328*18eb7a2dSCharles.Forsyth char* chcopy(char*, char*);
329*18eb7a2dSCharles.Forsyth char* writem(int*);
330*18eb7a2dSCharles.Forsyth char* symnam(int);
331*18eb7a2dSCharles.Forsyth void summary(void);
332*18eb7a2dSCharles.Forsyth void error(char*, ...);
333*18eb7a2dSCharles.Forsyth void aryfil(int*, int, int);
334*18eb7a2dSCharles.Forsyth int setunion(int*, int*);
335*18eb7a2dSCharles.Forsyth void prlook(Lkset*);
336*18eb7a2dSCharles.Forsyth void cpres(void);
337*18eb7a2dSCharles.Forsyth void cpfir(void);
338*18eb7a2dSCharles.Forsyth int state(int);
339*18eb7a2dSCharles.Forsyth void putitem(int*, Lkset*);
340*18eb7a2dSCharles.Forsyth void cempty(void);
341*18eb7a2dSCharles.Forsyth void stagen(void);
342*18eb7a2dSCharles.Forsyth void closure(int);
343*18eb7a2dSCharles.Forsyth Lkset* flset(Lkset*);
344*18eb7a2dSCharles.Forsyth void cleantmp(void);
345*18eb7a2dSCharles.Forsyth void intr(void);
346*18eb7a2dSCharles.Forsyth void setup(int, char**);
347*18eb7a2dSCharles.Forsyth void finact(void);
348*18eb7a2dSCharles.Forsyth int defin(int, char*);
349*18eb7a2dSCharles.Forsyth void defout(int);
350*18eb7a2dSCharles.Forsyth char* cstash(char*);
351*18eb7a2dSCharles.Forsyth long gettok(void);
352*18eb7a2dSCharles.Forsyth int fdtype(int);
353*18eb7a2dSCharles.Forsyth int chfind(int, char*);
354*18eb7a2dSCharles.Forsyth void cpyunion(void);
355*18eb7a2dSCharles.Forsyth void cpycode(void);
356*18eb7a2dSCharles.Forsyth int skipcom(void);
357*18eb7a2dSCharles.Forsyth void cpyact(int);
358*18eb7a2dSCharles.Forsyth void openup(char*, int, int, int, char*);
359*18eb7a2dSCharles.Forsyth void output(void);
360*18eb7a2dSCharles.Forsyth int apack(int*, int);
361*18eb7a2dSCharles.Forsyth void go2out(void);
362*18eb7a2dSCharles.Forsyth void go2gen(int);
363*18eb7a2dSCharles.Forsyth void precftn(int, int, int);
364*18eb7a2dSCharles.Forsyth void wract(int);
365*18eb7a2dSCharles.Forsyth void wrstate(int);
366*18eb7a2dSCharles.Forsyth void warray(char*, int*, int);
367*18eb7a2dSCharles.Forsyth void hideprod(void);
368*18eb7a2dSCharles.Forsyth void callopt(void);
369*18eb7a2dSCharles.Forsyth void gin(int);
370*18eb7a2dSCharles.Forsyth void stin(int);
371*18eb7a2dSCharles.Forsyth int nxti(void);
372*18eb7a2dSCharles.Forsyth void osummary(void);
373*18eb7a2dSCharles.Forsyth void aoutput(void);
374*18eb7a2dSCharles.Forsyth void arout(char*, int*, int);
375*18eb7a2dSCharles.Forsyth int gtnm(void);
376*18eb7a2dSCharles.Forsyth
377*18eb7a2dSCharles.Forsyth void
main(int argc,char * argv[])378*18eb7a2dSCharles.Forsyth main(int argc, char *argv[])
379*18eb7a2dSCharles.Forsyth {
380*18eb7a2dSCharles.Forsyth
381*18eb7a2dSCharles.Forsyth setup(argc, argv); /* initialize and read productions */
382*18eb7a2dSCharles.Forsyth tbitset = NWORDS(ntokens);
383*18eb7a2dSCharles.Forsyth cpres(); /* make table of which productions yield a given nonterminal */
384*18eb7a2dSCharles.Forsyth cempty(); /* make a table of which nonterminals can match the empty string */
385*18eb7a2dSCharles.Forsyth cpfir(); /* make a table of firsts of nonterminals */
386*18eb7a2dSCharles.Forsyth stagen(); /* generate the states */
387*18eb7a2dSCharles.Forsyth output(); /* write the states and the tables */
388*18eb7a2dSCharles.Forsyth go2out();
389*18eb7a2dSCharles.Forsyth hideprod();
390*18eb7a2dSCharles.Forsyth summary();
391*18eb7a2dSCharles.Forsyth callopt();
392*18eb7a2dSCharles.Forsyth others();
393*18eb7a2dSCharles.Forsyth exits(0);
394*18eb7a2dSCharles.Forsyth }
395*18eb7a2dSCharles.Forsyth
396*18eb7a2dSCharles.Forsyth /*
397*18eb7a2dSCharles.Forsyth * put out other arrays, copy the parsers
398*18eb7a2dSCharles.Forsyth */
399*18eb7a2dSCharles.Forsyth void
others(void)400*18eb7a2dSCharles.Forsyth others(void)
401*18eb7a2dSCharles.Forsyth {
402*18eb7a2dSCharles.Forsyth int c, i, j;
403*18eb7a2dSCharles.Forsyth
404*18eb7a2dSCharles.Forsyth finput = Bopen(parser, OREAD);
405*18eb7a2dSCharles.Forsyth if(finput == 0)
406*18eb7a2dSCharles.Forsyth error("cannot find parser %s", parser);
407*18eb7a2dSCharles.Forsyth warray("yyr1", levprd, nprod);
408*18eb7a2dSCharles.Forsyth aryfil(temp1, nprod, 0);
409*18eb7a2dSCharles.Forsyth PLOOP(1, i)
410*18eb7a2dSCharles.Forsyth temp1[i] = prdptr[i+1]-prdptr[i]-2;
411*18eb7a2dSCharles.Forsyth warray("yyr2", temp1, nprod);
412*18eb7a2dSCharles.Forsyth
413*18eb7a2dSCharles.Forsyth aryfil(temp1, nstate, -1000);
414*18eb7a2dSCharles.Forsyth TLOOP(i)
415*18eb7a2dSCharles.Forsyth for(j=tstates[i]; j!=0; j=mstates[j])
416*18eb7a2dSCharles.Forsyth temp1[j] = i;
417*18eb7a2dSCharles.Forsyth NTLOOP(i)
418*18eb7a2dSCharles.Forsyth for(j=ntstates[i]; j!=0; j=mstates[j])
419*18eb7a2dSCharles.Forsyth temp1[j] = -i;
420*18eb7a2dSCharles.Forsyth warray("yychk", temp1, nstate);
421*18eb7a2dSCharles.Forsyth warray("yydef", defact, nstate);
422*18eb7a2dSCharles.Forsyth
423*18eb7a2dSCharles.Forsyth /* put out token translation tables */
424*18eb7a2dSCharles.Forsyth /* table 1 has 0-256 */
425*18eb7a2dSCharles.Forsyth aryfil(temp1, 256, 0);
426*18eb7a2dSCharles.Forsyth c = 0;
427*18eb7a2dSCharles.Forsyth TLOOP(i) {
428*18eb7a2dSCharles.Forsyth j = tokset[i].value;
429*18eb7a2dSCharles.Forsyth if(j >= 0 && j < 256) {
430*18eb7a2dSCharles.Forsyth if(temp1[j]) {
431*18eb7a2dSCharles.Forsyth print("yacc bug -- cant have 2 different Ts with same value\n");
432*18eb7a2dSCharles.Forsyth print(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name);
433*18eb7a2dSCharles.Forsyth nerrors++;
434*18eb7a2dSCharles.Forsyth }
435*18eb7a2dSCharles.Forsyth temp1[j] = i;
436*18eb7a2dSCharles.Forsyth if(j > c)
437*18eb7a2dSCharles.Forsyth c = j;
438*18eb7a2dSCharles.Forsyth }
439*18eb7a2dSCharles.Forsyth }
440*18eb7a2dSCharles.Forsyth warray("yytok1", temp1, c+1);
441*18eb7a2dSCharles.Forsyth
442*18eb7a2dSCharles.Forsyth /* table 2 has PRIVATE-PRIVATE+256 */
443*18eb7a2dSCharles.Forsyth aryfil(temp1, 256, 0);
444*18eb7a2dSCharles.Forsyth c = 0;
445*18eb7a2dSCharles.Forsyth TLOOP(i) {
446*18eb7a2dSCharles.Forsyth j = tokset[i].value - PRIVATE;
447*18eb7a2dSCharles.Forsyth if(j >= 0 && j < 256) {
448*18eb7a2dSCharles.Forsyth if(temp1[j]) {
449*18eb7a2dSCharles.Forsyth print("yacc bug -- cant have 2 different Ts with same value\n");
450*18eb7a2dSCharles.Forsyth print(" %s and %s\n", tokset[i].name, tokset[temp1[j]].name);
451*18eb7a2dSCharles.Forsyth nerrors++;
452*18eb7a2dSCharles.Forsyth }
453*18eb7a2dSCharles.Forsyth temp1[j] = i;
454*18eb7a2dSCharles.Forsyth if(j > c)
455*18eb7a2dSCharles.Forsyth c = j;
456*18eb7a2dSCharles.Forsyth }
457*18eb7a2dSCharles.Forsyth }
458*18eb7a2dSCharles.Forsyth warray("yytok2", temp1, c+1);
459*18eb7a2dSCharles.Forsyth
460*18eb7a2dSCharles.Forsyth /* table 3 has everything else */
461*18eb7a2dSCharles.Forsyth Bprint(ftable, "long yytok3[] =\n{\n");
462*18eb7a2dSCharles.Forsyth c = 0;
463*18eb7a2dSCharles.Forsyth TLOOP(i) {
464*18eb7a2dSCharles.Forsyth j = tokset[i].value;
465*18eb7a2dSCharles.Forsyth if(j >= 0 && j < 256)
466*18eb7a2dSCharles.Forsyth continue;
467*18eb7a2dSCharles.Forsyth if(j >= PRIVATE && j < 256+PRIVATE)
468*18eb7a2dSCharles.Forsyth continue;
469*18eb7a2dSCharles.Forsyth
470*18eb7a2dSCharles.Forsyth Bprint(ftable, "%4d,%4d,", j, i);
471*18eb7a2dSCharles.Forsyth c++;
472*18eb7a2dSCharles.Forsyth if(c%5 == 0)
473*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n");
474*18eb7a2dSCharles.Forsyth }
475*18eb7a2dSCharles.Forsyth Bprint(ftable, "%4d\n};\n", 0);
476*18eb7a2dSCharles.Forsyth
477*18eb7a2dSCharles.Forsyth /* copy parser text */
478*18eb7a2dSCharles.Forsyth while((c=Bgetrune(finput)) != Beof) {
479*18eb7a2dSCharles.Forsyth if(c == '$') {
480*18eb7a2dSCharles.Forsyth if((c = Bgetrune(finput)) != 'A')
481*18eb7a2dSCharles.Forsyth Bputrune(ftable, '$');
482*18eb7a2dSCharles.Forsyth else { /* copy actions */
483*18eb7a2dSCharles.Forsyth faction = Bopen(actname, OREAD);
484*18eb7a2dSCharles.Forsyth if(faction == 0)
485*18eb7a2dSCharles.Forsyth error("cannot reopen action tempfile");
486*18eb7a2dSCharles.Forsyth while((c=Bgetrune(faction)) != Beof)
487*18eb7a2dSCharles.Forsyth Bputrune(ftable, c);
488*18eb7a2dSCharles.Forsyth Bterm(faction);
489*18eb7a2dSCharles.Forsyth ZAPFILE(actname);
490*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
491*18eb7a2dSCharles.Forsyth }
492*18eb7a2dSCharles.Forsyth }
493*18eb7a2dSCharles.Forsyth Bputrune(ftable, c);
494*18eb7a2dSCharles.Forsyth }
495*18eb7a2dSCharles.Forsyth Bterm(ftable);
496*18eb7a2dSCharles.Forsyth }
497*18eb7a2dSCharles.Forsyth
498*18eb7a2dSCharles.Forsyth /*
499*18eb7a2dSCharles.Forsyth * copies string q into p, returning next free char ptr
500*18eb7a2dSCharles.Forsyth */
501*18eb7a2dSCharles.Forsyth char*
chcopy(char * p,char * q)502*18eb7a2dSCharles.Forsyth chcopy(char* p, char* q)
503*18eb7a2dSCharles.Forsyth {
504*18eb7a2dSCharles.Forsyth int c;
505*18eb7a2dSCharles.Forsyth
506*18eb7a2dSCharles.Forsyth while(c = *q) {
507*18eb7a2dSCharles.Forsyth if(c == '"')
508*18eb7a2dSCharles.Forsyth *p++ = '\\';
509*18eb7a2dSCharles.Forsyth *p++ = c;
510*18eb7a2dSCharles.Forsyth q++;
511*18eb7a2dSCharles.Forsyth }
512*18eb7a2dSCharles.Forsyth *p = 0;
513*18eb7a2dSCharles.Forsyth return p;
514*18eb7a2dSCharles.Forsyth }
515*18eb7a2dSCharles.Forsyth
516*18eb7a2dSCharles.Forsyth /*
517*18eb7a2dSCharles.Forsyth * creates output string for item pointed to by pp
518*18eb7a2dSCharles.Forsyth */
519*18eb7a2dSCharles.Forsyth char*
writem(int * pp)520*18eb7a2dSCharles.Forsyth writem(int *pp)
521*18eb7a2dSCharles.Forsyth {
522*18eb7a2dSCharles.Forsyth int i,*p;
523*18eb7a2dSCharles.Forsyth static char sarr[ISIZE];
524*18eb7a2dSCharles.Forsyth char* q;
525*18eb7a2dSCharles.Forsyth
526*18eb7a2dSCharles.Forsyth for(p=pp; *p>0; p++)
527*18eb7a2dSCharles.Forsyth ;
528*18eb7a2dSCharles.Forsyth p = prdptr[-*p];
529*18eb7a2dSCharles.Forsyth q = chcopy(sarr, nontrst[*p-NTBASE].name);
530*18eb7a2dSCharles.Forsyth q = chcopy(q, ": ");
531*18eb7a2dSCharles.Forsyth for(;;) {
532*18eb7a2dSCharles.Forsyth *q = ' ';
533*18eb7a2dSCharles.Forsyth p++;
534*18eb7a2dSCharles.Forsyth if(p == pp)
535*18eb7a2dSCharles.Forsyth *q = '.';
536*18eb7a2dSCharles.Forsyth q++;
537*18eb7a2dSCharles.Forsyth *q = '\0';
538*18eb7a2dSCharles.Forsyth i = *p;
539*18eb7a2dSCharles.Forsyth if(i <= 0)
540*18eb7a2dSCharles.Forsyth break;
541*18eb7a2dSCharles.Forsyth q = chcopy(q, symnam(i));
542*18eb7a2dSCharles.Forsyth if(q > &sarr[ISIZE-30])
543*18eb7a2dSCharles.Forsyth error("item too big");
544*18eb7a2dSCharles.Forsyth }
545*18eb7a2dSCharles.Forsyth
546*18eb7a2dSCharles.Forsyth /* an item calling for a reduction */
547*18eb7a2dSCharles.Forsyth i = *pp;
548*18eb7a2dSCharles.Forsyth if(i < 0 ) {
549*18eb7a2dSCharles.Forsyth q = chcopy(q, " (");
550*18eb7a2dSCharles.Forsyth sprint(q, "%d)", -i);
551*18eb7a2dSCharles.Forsyth }
552*18eb7a2dSCharles.Forsyth return sarr;
553*18eb7a2dSCharles.Forsyth }
554*18eb7a2dSCharles.Forsyth
555*18eb7a2dSCharles.Forsyth /*
556*18eb7a2dSCharles.Forsyth * return a pointer to the name of symbol i
557*18eb7a2dSCharles.Forsyth */
558*18eb7a2dSCharles.Forsyth char*
symnam(int i)559*18eb7a2dSCharles.Forsyth symnam(int i)
560*18eb7a2dSCharles.Forsyth {
561*18eb7a2dSCharles.Forsyth char* cp;
562*18eb7a2dSCharles.Forsyth
563*18eb7a2dSCharles.Forsyth cp = (i >= NTBASE)? nontrst[i-NTBASE].name: tokset[i].name;
564*18eb7a2dSCharles.Forsyth if(*cp == ' ')
565*18eb7a2dSCharles.Forsyth cp++;
566*18eb7a2dSCharles.Forsyth return cp;
567*18eb7a2dSCharles.Forsyth }
568*18eb7a2dSCharles.Forsyth
569*18eb7a2dSCharles.Forsyth /*
570*18eb7a2dSCharles.Forsyth * output the summary on y.output
571*18eb7a2dSCharles.Forsyth */
572*18eb7a2dSCharles.Forsyth void
summary(void)573*18eb7a2dSCharles.Forsyth summary(void)
574*18eb7a2dSCharles.Forsyth {
575*18eb7a2dSCharles.Forsyth
576*18eb7a2dSCharles.Forsyth if(foutput != 0) {
577*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n%d/%d terminals, %d/%d nonterminals\n",
578*18eb7a2dSCharles.Forsyth ntokens, NTERMS, nnonter, NNONTERM);
579*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d/%d grammar rules, %d/%d states\n",
580*18eb7a2dSCharles.Forsyth nprod, NPROD, nstate, NSTATES);
581*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n",
582*18eb7a2dSCharles.Forsyth zzsrconf, zzrrconf);
583*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d/%d working sets used\n",
584*18eb7a2dSCharles.Forsyth (int)(zzcwp-wsets), WSETSIZE);
585*18eb7a2dSCharles.Forsyth Bprint(foutput, "memory: states,etc. %d/%d, parser %d/%d\n",
586*18eb7a2dSCharles.Forsyth (int)(zzmemsz-mem0), MEMSIZE, (int)(memp-amem), ACTSIZE);
587*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE);
588*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d extra closures\n", zzclose - 2*nstate);
589*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp);
590*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d goto entries\n", zzgoent);
591*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d entries saved by goto default\n", zzgobest);
592*18eb7a2dSCharles.Forsyth }
593*18eb7a2dSCharles.Forsyth if(zzsrconf != 0 || zzrrconf != 0) {
594*18eb7a2dSCharles.Forsyth print("\nconflicts: ");
595*18eb7a2dSCharles.Forsyth if(zzsrconf)
596*18eb7a2dSCharles.Forsyth print("%d shift/reduce", zzsrconf);
597*18eb7a2dSCharles.Forsyth if(zzsrconf && zzrrconf)
598*18eb7a2dSCharles.Forsyth print(", ");
599*18eb7a2dSCharles.Forsyth if(zzrrconf)
600*18eb7a2dSCharles.Forsyth print("%d reduce/reduce", zzrrconf);
601*18eb7a2dSCharles.Forsyth print("\n");
602*18eb7a2dSCharles.Forsyth }
603*18eb7a2dSCharles.Forsyth if(ftemp != 0) {
604*18eb7a2dSCharles.Forsyth Bterm(ftemp);
605*18eb7a2dSCharles.Forsyth ftemp = 0;
606*18eb7a2dSCharles.Forsyth }
607*18eb7a2dSCharles.Forsyth if(fdefine != 0) {
608*18eb7a2dSCharles.Forsyth Bterm(fdefine);
609*18eb7a2dSCharles.Forsyth fdefine = 0;
610*18eb7a2dSCharles.Forsyth }
611*18eb7a2dSCharles.Forsyth }
612*18eb7a2dSCharles.Forsyth
613*18eb7a2dSCharles.Forsyth /*
614*18eb7a2dSCharles.Forsyth * write out error comment -- NEEDS WORK
615*18eb7a2dSCharles.Forsyth */
616*18eb7a2dSCharles.Forsyth void
error(char * s,...)617*18eb7a2dSCharles.Forsyth error(char *s, ...)
618*18eb7a2dSCharles.Forsyth {
619*18eb7a2dSCharles.Forsyth
620*18eb7a2dSCharles.Forsyth nerrors++;
621*18eb7a2dSCharles.Forsyth fprint(2, "\n fatal error:");
622*18eb7a2dSCharles.Forsyth fprint(2, s, (&s)[1]);
623*18eb7a2dSCharles.Forsyth fprint(2, ", %s:%d\n", infile, lineno);
624*18eb7a2dSCharles.Forsyth if(!fatfl)
625*18eb7a2dSCharles.Forsyth return;
626*18eb7a2dSCharles.Forsyth summary();
627*18eb7a2dSCharles.Forsyth cleantmp();
628*18eb7a2dSCharles.Forsyth exits("error");
629*18eb7a2dSCharles.Forsyth }
630*18eb7a2dSCharles.Forsyth
631*18eb7a2dSCharles.Forsyth /*
632*18eb7a2dSCharles.Forsyth * set elements 0 through n-1 to c
633*18eb7a2dSCharles.Forsyth */
634*18eb7a2dSCharles.Forsyth void
aryfil(int * v,int n,int c)635*18eb7a2dSCharles.Forsyth aryfil(int *v, int n, int c)
636*18eb7a2dSCharles.Forsyth {
637*18eb7a2dSCharles.Forsyth int i;
638*18eb7a2dSCharles.Forsyth
639*18eb7a2dSCharles.Forsyth for(i=0; i<n; i++)
640*18eb7a2dSCharles.Forsyth v[i] = c;
641*18eb7a2dSCharles.Forsyth }
642*18eb7a2dSCharles.Forsyth
643*18eb7a2dSCharles.Forsyth /*
644*18eb7a2dSCharles.Forsyth * set a to the union of a and b
645*18eb7a2dSCharles.Forsyth * return 1 if b is not a subset of a, 0 otherwise
646*18eb7a2dSCharles.Forsyth */
647*18eb7a2dSCharles.Forsyth int
setunion(int * a,int * b)648*18eb7a2dSCharles.Forsyth setunion(int *a, int *b)
649*18eb7a2dSCharles.Forsyth {
650*18eb7a2dSCharles.Forsyth int i, x, sub;
651*18eb7a2dSCharles.Forsyth
652*18eb7a2dSCharles.Forsyth sub = 0;
653*18eb7a2dSCharles.Forsyth SETLOOP(i) {
654*18eb7a2dSCharles.Forsyth x = *a;
655*18eb7a2dSCharles.Forsyth *a |= *b;
656*18eb7a2dSCharles.Forsyth if(*a != x)
657*18eb7a2dSCharles.Forsyth sub = 1;
658*18eb7a2dSCharles.Forsyth a++;
659*18eb7a2dSCharles.Forsyth b++;
660*18eb7a2dSCharles.Forsyth }
661*18eb7a2dSCharles.Forsyth return sub;
662*18eb7a2dSCharles.Forsyth }
663*18eb7a2dSCharles.Forsyth
664*18eb7a2dSCharles.Forsyth void
prlook(Lkset * p)665*18eb7a2dSCharles.Forsyth prlook(Lkset* p)
666*18eb7a2dSCharles.Forsyth {
667*18eb7a2dSCharles.Forsyth int j, *pp;
668*18eb7a2dSCharles.Forsyth
669*18eb7a2dSCharles.Forsyth pp = p->lset;
670*18eb7a2dSCharles.Forsyth if(pp == 0)
671*18eb7a2dSCharles.Forsyth Bprint(foutput, "\tNULL");
672*18eb7a2dSCharles.Forsyth else {
673*18eb7a2dSCharles.Forsyth Bprint(foutput, " { ");
674*18eb7a2dSCharles.Forsyth TLOOP(j)
675*18eb7a2dSCharles.Forsyth if(BIT(pp,j))
676*18eb7a2dSCharles.Forsyth Bprint(foutput, "%s ", symnam(j));
677*18eb7a2dSCharles.Forsyth Bprint(foutput, "}");
678*18eb7a2dSCharles.Forsyth }
679*18eb7a2dSCharles.Forsyth }
680*18eb7a2dSCharles.Forsyth
681*18eb7a2dSCharles.Forsyth /*
682*18eb7a2dSCharles.Forsyth * compute an array with the beginnings of productions yielding given nonterminals
683*18eb7a2dSCharles.Forsyth * The array pres points to these lists
684*18eb7a2dSCharles.Forsyth * the array pyield has the lists: the total size is only NPROD+1
685*18eb7a2dSCharles.Forsyth */
686*18eb7a2dSCharles.Forsyth void
cpres(void)687*18eb7a2dSCharles.Forsyth cpres(void)
688*18eb7a2dSCharles.Forsyth {
689*18eb7a2dSCharles.Forsyth int c, j, i, **pmem;
690*18eb7a2dSCharles.Forsyth static int *pyield[NPROD];
691*18eb7a2dSCharles.Forsyth
692*18eb7a2dSCharles.Forsyth pmem = pyield;
693*18eb7a2dSCharles.Forsyth NTLOOP(i) {
694*18eb7a2dSCharles.Forsyth c = i+NTBASE;
695*18eb7a2dSCharles.Forsyth pres[i] = pmem;
696*18eb7a2dSCharles.Forsyth fatfl = 0; /* make undefined symbols nonfatal */
697*18eb7a2dSCharles.Forsyth PLOOP(0, j)
698*18eb7a2dSCharles.Forsyth if(*prdptr[j] == c)
699*18eb7a2dSCharles.Forsyth *pmem++ = prdptr[j]+1;
700*18eb7a2dSCharles.Forsyth if(pres[i] == pmem)
701*18eb7a2dSCharles.Forsyth error("nonterminal %s not defined!", nontrst[i].name);
702*18eb7a2dSCharles.Forsyth }
703*18eb7a2dSCharles.Forsyth pres[i] = pmem;
704*18eb7a2dSCharles.Forsyth fatfl = 1;
705*18eb7a2dSCharles.Forsyth if(nerrors) {
706*18eb7a2dSCharles.Forsyth summary();
707*18eb7a2dSCharles.Forsyth cleantmp();
708*18eb7a2dSCharles.Forsyth exits("error");
709*18eb7a2dSCharles.Forsyth }
710*18eb7a2dSCharles.Forsyth if(pmem != &pyield[nprod])
711*18eb7a2dSCharles.Forsyth error("internal Yacc error: pyield %d", pmem-&pyield[nprod]);
712*18eb7a2dSCharles.Forsyth }
713*18eb7a2dSCharles.Forsyth
714*18eb7a2dSCharles.Forsyth /*
715*18eb7a2dSCharles.Forsyth * compute an array with the first of nonterminals
716*18eb7a2dSCharles.Forsyth */
717*18eb7a2dSCharles.Forsyth void
cpfir(void)718*18eb7a2dSCharles.Forsyth cpfir(void)
719*18eb7a2dSCharles.Forsyth {
720*18eb7a2dSCharles.Forsyth int *p, **s, i, **t, ch, changes;
721*18eb7a2dSCharles.Forsyth
722*18eb7a2dSCharles.Forsyth zzcwp = &wsets[nnonter];
723*18eb7a2dSCharles.Forsyth NTLOOP(i) {
724*18eb7a2dSCharles.Forsyth aryfil(wsets[i].ws.lset, tbitset, 0);
725*18eb7a2dSCharles.Forsyth t = pres[i+1];
726*18eb7a2dSCharles.Forsyth /* initially fill the sets */
727*18eb7a2dSCharles.Forsyth for(s=pres[i]; s<t; ++s)
728*18eb7a2dSCharles.Forsyth for(p = *s; (ch = *p) > 0; ++p) {
729*18eb7a2dSCharles.Forsyth if(ch < NTBASE) {
730*18eb7a2dSCharles.Forsyth SETBIT(wsets[i].ws.lset, ch);
731*18eb7a2dSCharles.Forsyth break;
732*18eb7a2dSCharles.Forsyth }
733*18eb7a2dSCharles.Forsyth if(!pempty[ch-NTBASE])
734*18eb7a2dSCharles.Forsyth break;
735*18eb7a2dSCharles.Forsyth }
736*18eb7a2dSCharles.Forsyth }
737*18eb7a2dSCharles.Forsyth
738*18eb7a2dSCharles.Forsyth /* now, reflect transitivity */
739*18eb7a2dSCharles.Forsyth changes = 1;
740*18eb7a2dSCharles.Forsyth while(changes) {
741*18eb7a2dSCharles.Forsyth changes = 0;
742*18eb7a2dSCharles.Forsyth NTLOOP(i) {
743*18eb7a2dSCharles.Forsyth t = pres[i+1];
744*18eb7a2dSCharles.Forsyth for(s = pres[i]; s < t; ++s)
745*18eb7a2dSCharles.Forsyth for(p = *s; (ch = (*p-NTBASE)) >= 0; ++p) {
746*18eb7a2dSCharles.Forsyth changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset);
747*18eb7a2dSCharles.Forsyth if(!pempty[ch])
748*18eb7a2dSCharles.Forsyth break;
749*18eb7a2dSCharles.Forsyth }
750*18eb7a2dSCharles.Forsyth }
751*18eb7a2dSCharles.Forsyth }
752*18eb7a2dSCharles.Forsyth
753*18eb7a2dSCharles.Forsyth NTLOOP(i)
754*18eb7a2dSCharles.Forsyth pfirst[i] = flset(&wsets[i].ws);
755*18eb7a2dSCharles.Forsyth if(!indebug)
756*18eb7a2dSCharles.Forsyth return;
757*18eb7a2dSCharles.Forsyth if(foutput != 0)
758*18eb7a2dSCharles.Forsyth NTLOOP(i) {
759*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n%s: ", nontrst[i].name);
760*18eb7a2dSCharles.Forsyth prlook(pfirst[i]);
761*18eb7a2dSCharles.Forsyth Bprint(foutput, " %d\n", pempty[i]);
762*18eb7a2dSCharles.Forsyth }
763*18eb7a2dSCharles.Forsyth }
764*18eb7a2dSCharles.Forsyth
765*18eb7a2dSCharles.Forsyth /*
766*18eb7a2dSCharles.Forsyth * sorts last state,and sees if it equals earlier ones. returns state number
767*18eb7a2dSCharles.Forsyth */
768*18eb7a2dSCharles.Forsyth int
state(int c)769*18eb7a2dSCharles.Forsyth state(int c)
770*18eb7a2dSCharles.Forsyth {
771*18eb7a2dSCharles.Forsyth Item *p1, *p2, *k, *l, *q1, *q2;
772*18eb7a2dSCharles.Forsyth int size1, size2, i;
773*18eb7a2dSCharles.Forsyth
774*18eb7a2dSCharles.Forsyth p1 = pstate[nstate];
775*18eb7a2dSCharles.Forsyth p2 = pstate[nstate+1];
776*18eb7a2dSCharles.Forsyth if(p1 == p2)
777*18eb7a2dSCharles.Forsyth return 0; /* null state */
778*18eb7a2dSCharles.Forsyth /* sort the items */
779*18eb7a2dSCharles.Forsyth for(k = p2-1; k > p1; k--) /* make k the biggest */
780*18eb7a2dSCharles.Forsyth for(l = k-1; l >= p1; --l)
781*18eb7a2dSCharles.Forsyth if(l->pitem > k->pitem) {
782*18eb7a2dSCharles.Forsyth int *s;
783*18eb7a2dSCharles.Forsyth Lkset *ss;
784*18eb7a2dSCharles.Forsyth
785*18eb7a2dSCharles.Forsyth s = k->pitem;
786*18eb7a2dSCharles.Forsyth k->pitem = l->pitem;
787*18eb7a2dSCharles.Forsyth l->pitem = s;
788*18eb7a2dSCharles.Forsyth ss = k->look;
789*18eb7a2dSCharles.Forsyth k->look = l->look;
790*18eb7a2dSCharles.Forsyth l->look = ss;
791*18eb7a2dSCharles.Forsyth }
792*18eb7a2dSCharles.Forsyth size1 = p2 - p1; /* size of state */
793*18eb7a2dSCharles.Forsyth
794*18eb7a2dSCharles.Forsyth for(i = (c>=NTBASE)? ntstates[c-NTBASE]: tstates[c]; i != 0; i = mstates[i]) {
795*18eb7a2dSCharles.Forsyth /* get ith state */
796*18eb7a2dSCharles.Forsyth q1 = pstate[i];
797*18eb7a2dSCharles.Forsyth q2 = pstate[i+1];
798*18eb7a2dSCharles.Forsyth size2 = q2 - q1;
799*18eb7a2dSCharles.Forsyth if(size1 != size2)
800*18eb7a2dSCharles.Forsyth continue;
801*18eb7a2dSCharles.Forsyth k = p1;
802*18eb7a2dSCharles.Forsyth for(l = q1; l < q2; l++) {
803*18eb7a2dSCharles.Forsyth if(l->pitem != k->pitem)
804*18eb7a2dSCharles.Forsyth break;
805*18eb7a2dSCharles.Forsyth k++;
806*18eb7a2dSCharles.Forsyth }
807*18eb7a2dSCharles.Forsyth if(l != q2)
808*18eb7a2dSCharles.Forsyth continue;
809*18eb7a2dSCharles.Forsyth /* found it */
810*18eb7a2dSCharles.Forsyth pstate[nstate+1] = pstate[nstate]; /* delete last state */
811*18eb7a2dSCharles.Forsyth /* fix up lookaheads */
812*18eb7a2dSCharles.Forsyth if(nolook)
813*18eb7a2dSCharles.Forsyth return i;
814*18eb7a2dSCharles.Forsyth for(l = q1, k = p1; l < q2; ++l, ++k ) {
815*18eb7a2dSCharles.Forsyth int s;
816*18eb7a2dSCharles.Forsyth
817*18eb7a2dSCharles.Forsyth SETLOOP(s)
818*18eb7a2dSCharles.Forsyth clset.lset[s] = l->look->lset[s];
819*18eb7a2dSCharles.Forsyth if(setunion(clset.lset, k->look->lset)) {
820*18eb7a2dSCharles.Forsyth tystate[i] = MUSTDO;
821*18eb7a2dSCharles.Forsyth /* register the new set */
822*18eb7a2dSCharles.Forsyth l->look = flset( &clset );
823*18eb7a2dSCharles.Forsyth }
824*18eb7a2dSCharles.Forsyth }
825*18eb7a2dSCharles.Forsyth return i;
826*18eb7a2dSCharles.Forsyth }
827*18eb7a2dSCharles.Forsyth /* state is new */
828*18eb7a2dSCharles.Forsyth if(nolook)
829*18eb7a2dSCharles.Forsyth error("yacc state/nolook error");
830*18eb7a2dSCharles.Forsyth pstate[nstate+2] = p2;
831*18eb7a2dSCharles.Forsyth if(nstate+1 >= NSTATES)
832*18eb7a2dSCharles.Forsyth error("too many states");
833*18eb7a2dSCharles.Forsyth if(c >= NTBASE) {
834*18eb7a2dSCharles.Forsyth mstates[nstate] = ntstates[c-NTBASE];
835*18eb7a2dSCharles.Forsyth ntstates[c-NTBASE] = nstate;
836*18eb7a2dSCharles.Forsyth } else {
837*18eb7a2dSCharles.Forsyth mstates[nstate] = tstates[c];
838*18eb7a2dSCharles.Forsyth tstates[c] = nstate;
839*18eb7a2dSCharles.Forsyth }
840*18eb7a2dSCharles.Forsyth tystate[nstate] = MUSTDO;
841*18eb7a2dSCharles.Forsyth return nstate++;
842*18eb7a2dSCharles.Forsyth }
843*18eb7a2dSCharles.Forsyth
844*18eb7a2dSCharles.Forsyth void
putitem(int * ptr,Lkset * lptr)845*18eb7a2dSCharles.Forsyth putitem(int *ptr, Lkset *lptr)
846*18eb7a2dSCharles.Forsyth {
847*18eb7a2dSCharles.Forsyth Item *j;
848*18eb7a2dSCharles.Forsyth
849*18eb7a2dSCharles.Forsyth if(pidebug && foutput != 0)
850*18eb7a2dSCharles.Forsyth Bprint(foutput, "putitem(%s), state %d\n", writem(ptr), nstate);
851*18eb7a2dSCharles.Forsyth j = pstate[nstate+1];
852*18eb7a2dSCharles.Forsyth j->pitem = ptr;
853*18eb7a2dSCharles.Forsyth if(!nolook)
854*18eb7a2dSCharles.Forsyth j->look = flset(lptr);
855*18eb7a2dSCharles.Forsyth pstate[nstate+1] = ++j;
856*18eb7a2dSCharles.Forsyth if((int*)j > zzmemsz) {
857*18eb7a2dSCharles.Forsyth zzmemsz = (int*)j;
858*18eb7a2dSCharles.Forsyth if(zzmemsz >= &mem0[MEMSIZE])
859*18eb7a2dSCharles.Forsyth error("out of state space");
860*18eb7a2dSCharles.Forsyth }
861*18eb7a2dSCharles.Forsyth }
862*18eb7a2dSCharles.Forsyth
863*18eb7a2dSCharles.Forsyth /*
864*18eb7a2dSCharles.Forsyth * mark nonterminals which derive the empty string
865*18eb7a2dSCharles.Forsyth * also, look for nonterminals which don't derive any token strings
866*18eb7a2dSCharles.Forsyth */
867*18eb7a2dSCharles.Forsyth void
cempty(void)868*18eb7a2dSCharles.Forsyth cempty(void)
869*18eb7a2dSCharles.Forsyth {
870*18eb7a2dSCharles.Forsyth
871*18eb7a2dSCharles.Forsyth int i, *p;
872*18eb7a2dSCharles.Forsyth
873*18eb7a2dSCharles.Forsyth /* first, use the array pempty to detect productions that can never be reduced */
874*18eb7a2dSCharles.Forsyth /* set pempty to WHONOWS */
875*18eb7a2dSCharles.Forsyth aryfil(pempty, nnonter+1, WHOKNOWS);
876*18eb7a2dSCharles.Forsyth
877*18eb7a2dSCharles.Forsyth /* now, look at productions, marking nonterminals which derive something */
878*18eb7a2dSCharles.Forsyth more:
879*18eb7a2dSCharles.Forsyth PLOOP(0, i) {
880*18eb7a2dSCharles.Forsyth if(pempty[*prdptr[i] - NTBASE])
881*18eb7a2dSCharles.Forsyth continue;
882*18eb7a2dSCharles.Forsyth for(p = prdptr[i]+1; *p >= 0; ++p)
883*18eb7a2dSCharles.Forsyth if(*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS)
884*18eb7a2dSCharles.Forsyth break;
885*18eb7a2dSCharles.Forsyth /* production can be derived */
886*18eb7a2dSCharles.Forsyth if(*p < 0) {
887*18eb7a2dSCharles.Forsyth pempty[*prdptr[i]-NTBASE] = OK;
888*18eb7a2dSCharles.Forsyth goto more;
889*18eb7a2dSCharles.Forsyth }
890*18eb7a2dSCharles.Forsyth }
891*18eb7a2dSCharles.Forsyth
892*18eb7a2dSCharles.Forsyth /* now, look at the nonterminals, to see if they are all OK */
893*18eb7a2dSCharles.Forsyth NTLOOP(i) {
894*18eb7a2dSCharles.Forsyth /* the added production rises or falls as the start symbol ... */
895*18eb7a2dSCharles.Forsyth if(i == 0)
896*18eb7a2dSCharles.Forsyth continue;
897*18eb7a2dSCharles.Forsyth if(pempty[i] != OK) {
898*18eb7a2dSCharles.Forsyth fatfl = 0;
899*18eb7a2dSCharles.Forsyth error("nonterminal %s never derives any token string", nontrst[i].name);
900*18eb7a2dSCharles.Forsyth }
901*18eb7a2dSCharles.Forsyth }
902*18eb7a2dSCharles.Forsyth
903*18eb7a2dSCharles.Forsyth if(nerrors) {
904*18eb7a2dSCharles.Forsyth summary();
905*18eb7a2dSCharles.Forsyth cleantmp();
906*18eb7a2dSCharles.Forsyth exits("error");
907*18eb7a2dSCharles.Forsyth }
908*18eb7a2dSCharles.Forsyth
909*18eb7a2dSCharles.Forsyth /* now, compute the pempty array, to see which nonterminals derive the empty string */
910*18eb7a2dSCharles.Forsyth /* set pempty to WHOKNOWS */
911*18eb7a2dSCharles.Forsyth aryfil( pempty, nnonter+1, WHOKNOWS);
912*18eb7a2dSCharles.Forsyth
913*18eb7a2dSCharles.Forsyth /* loop as long as we keep finding empty nonterminals */
914*18eb7a2dSCharles.Forsyth
915*18eb7a2dSCharles.Forsyth again:
916*18eb7a2dSCharles.Forsyth PLOOP(1, i) {
917*18eb7a2dSCharles.Forsyth /* not known to be empty */
918*18eb7a2dSCharles.Forsyth if(pempty[*prdptr[i]-NTBASE] == WHOKNOWS) {
919*18eb7a2dSCharles.Forsyth for(p = prdptr[i]+1; *p >= NTBASE && pempty[*p-NTBASE] == EMPTY ; ++p)
920*18eb7a2dSCharles.Forsyth ;
921*18eb7a2dSCharles.Forsyth /* we have a nontrivially empty nonterminal */
922*18eb7a2dSCharles.Forsyth if(*p < 0) {
923*18eb7a2dSCharles.Forsyth pempty[*prdptr[i]-NTBASE] = EMPTY;
924*18eb7a2dSCharles.Forsyth /* got one ... try for another */
925*18eb7a2dSCharles.Forsyth goto again;
926*18eb7a2dSCharles.Forsyth }
927*18eb7a2dSCharles.Forsyth }
928*18eb7a2dSCharles.Forsyth }
929*18eb7a2dSCharles.Forsyth }
930*18eb7a2dSCharles.Forsyth
931*18eb7a2dSCharles.Forsyth /*
932*18eb7a2dSCharles.Forsyth * generate the states
933*18eb7a2dSCharles.Forsyth */
934*18eb7a2dSCharles.Forsyth void
stagen(void)935*18eb7a2dSCharles.Forsyth stagen(void)
936*18eb7a2dSCharles.Forsyth {
937*18eb7a2dSCharles.Forsyth
938*18eb7a2dSCharles.Forsyth int c, i, j, more;
939*18eb7a2dSCharles.Forsyth Wset *p, *q;
940*18eb7a2dSCharles.Forsyth
941*18eb7a2dSCharles.Forsyth /* initialize */
942*18eb7a2dSCharles.Forsyth nstate = 0;
943*18eb7a2dSCharles.Forsyth
944*18eb7a2dSCharles.Forsyth /* THIS IS FUNNY from the standpoint of portability
945*18eb7a2dSCharles.Forsyth * it represents the magic moment when the mem0 array, which has
946*18eb7a2dSCharles.Forsyth * been holding the productions, starts to hold item pointers, of a
947*18eb7a2dSCharles.Forsyth * different type...
948*18eb7a2dSCharles.Forsyth * someday, alloc should be used to allocate all this stuff... for now, we
949*18eb7a2dSCharles.Forsyth * accept that if pointers don't fit in integers, there is a problem...
950*18eb7a2dSCharles.Forsyth */
951*18eb7a2dSCharles.Forsyth
952*18eb7a2dSCharles.Forsyth pstate[0] = pstate[1] = (Item*)mem;
953*18eb7a2dSCharles.Forsyth aryfil(clset.lset, tbitset, 0);
954*18eb7a2dSCharles.Forsyth putitem(prdptr[0]+1, &clset);
955*18eb7a2dSCharles.Forsyth tystate[0] = MUSTDO;
956*18eb7a2dSCharles.Forsyth nstate = 1;
957*18eb7a2dSCharles.Forsyth pstate[2] = pstate[1];
958*18eb7a2dSCharles.Forsyth
959*18eb7a2dSCharles.Forsyth aryfil(amem, ACTSIZE, 0);
960*18eb7a2dSCharles.Forsyth
961*18eb7a2dSCharles.Forsyth /* now, the main state generation loop */
962*18eb7a2dSCharles.Forsyth for(more=1; more;) {
963*18eb7a2dSCharles.Forsyth more = 0;
964*18eb7a2dSCharles.Forsyth SLOOP(i) {
965*18eb7a2dSCharles.Forsyth if(tystate[i] != MUSTDO)
966*18eb7a2dSCharles.Forsyth continue;
967*18eb7a2dSCharles.Forsyth tystate[i] = DONE;
968*18eb7a2dSCharles.Forsyth aryfil(temp1, nnonter+1, 0);
969*18eb7a2dSCharles.Forsyth /* take state i, close it, and do gotos */
970*18eb7a2dSCharles.Forsyth closure(i);
971*18eb7a2dSCharles.Forsyth /* generate goto's */
972*18eb7a2dSCharles.Forsyth WSLOOP(wsets, p) {
973*18eb7a2dSCharles.Forsyth if(p->flag)
974*18eb7a2dSCharles.Forsyth continue;
975*18eb7a2dSCharles.Forsyth p->flag = 1;
976*18eb7a2dSCharles.Forsyth c = *(p->pitem);
977*18eb7a2dSCharles.Forsyth if(c <= 1) {
978*18eb7a2dSCharles.Forsyth if(pstate[i+1]-pstate[i] <= p-wsets)
979*18eb7a2dSCharles.Forsyth tystate[i] = MUSTLOOKAHEAD;
980*18eb7a2dSCharles.Forsyth continue;
981*18eb7a2dSCharles.Forsyth }
982*18eb7a2dSCharles.Forsyth /* do a goto on c */
983*18eb7a2dSCharles.Forsyth WSLOOP(p, q)
984*18eb7a2dSCharles.Forsyth /* this item contributes to the goto */
985*18eb7a2dSCharles.Forsyth if(c == *(q->pitem)) {
986*18eb7a2dSCharles.Forsyth putitem(q->pitem+1, &q->ws);
987*18eb7a2dSCharles.Forsyth q->flag = 1;
988*18eb7a2dSCharles.Forsyth }
989*18eb7a2dSCharles.Forsyth if(c < NTBASE)
990*18eb7a2dSCharles.Forsyth state(c); /* register new state */
991*18eb7a2dSCharles.Forsyth else
992*18eb7a2dSCharles.Forsyth temp1[c-NTBASE] = state(c);
993*18eb7a2dSCharles.Forsyth }
994*18eb7a2dSCharles.Forsyth if(gsdebug && foutput != 0) {
995*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d: ", i);
996*18eb7a2dSCharles.Forsyth NTLOOP(j)
997*18eb7a2dSCharles.Forsyth if(temp1[j])
998*18eb7a2dSCharles.Forsyth Bprint(foutput, "%s %d, ",
999*18eb7a2dSCharles.Forsyth nontrst[j].name, temp1[j]);
1000*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n");
1001*18eb7a2dSCharles.Forsyth }
1002*18eb7a2dSCharles.Forsyth indgo[i] = apack(&temp1[1], nnonter-1) - 1;
1003*18eb7a2dSCharles.Forsyth /* do some more */
1004*18eb7a2dSCharles.Forsyth more = 1;
1005*18eb7a2dSCharles.Forsyth }
1006*18eb7a2dSCharles.Forsyth }
1007*18eb7a2dSCharles.Forsyth }
1008*18eb7a2dSCharles.Forsyth
1009*18eb7a2dSCharles.Forsyth /*
1010*18eb7a2dSCharles.Forsyth * generate the closure of state i
1011*18eb7a2dSCharles.Forsyth */
1012*18eb7a2dSCharles.Forsyth void
closure(int i)1013*18eb7a2dSCharles.Forsyth closure(int i)
1014*18eb7a2dSCharles.Forsyth {
1015*18eb7a2dSCharles.Forsyth
1016*18eb7a2dSCharles.Forsyth Wset *u, *v;
1017*18eb7a2dSCharles.Forsyth Item *p, *q;
1018*18eb7a2dSCharles.Forsyth int c, ch, work, k, *pi, **s, **t;
1019*18eb7a2dSCharles.Forsyth
1020*18eb7a2dSCharles.Forsyth zzclose++;
1021*18eb7a2dSCharles.Forsyth
1022*18eb7a2dSCharles.Forsyth /* first, copy kernel of state i to wsets */
1023*18eb7a2dSCharles.Forsyth cwp = wsets;
1024*18eb7a2dSCharles.Forsyth ITMLOOP(i, p, q) {
1025*18eb7a2dSCharles.Forsyth cwp->pitem = p->pitem;
1026*18eb7a2dSCharles.Forsyth cwp->flag = 1; /* this item must get closed */
1027*18eb7a2dSCharles.Forsyth SETLOOP(k)
1028*18eb7a2dSCharles.Forsyth cwp->ws.lset[k] = p->look->lset[k];
1029*18eb7a2dSCharles.Forsyth WSBUMP(cwp);
1030*18eb7a2dSCharles.Forsyth }
1031*18eb7a2dSCharles.Forsyth
1032*18eb7a2dSCharles.Forsyth /* now, go through the loop, closing each item */
1033*18eb7a2dSCharles.Forsyth work = 1;
1034*18eb7a2dSCharles.Forsyth while(work) {
1035*18eb7a2dSCharles.Forsyth work = 0;
1036*18eb7a2dSCharles.Forsyth WSLOOP(wsets, u) {
1037*18eb7a2dSCharles.Forsyth if(u->flag == 0)
1038*18eb7a2dSCharles.Forsyth continue;
1039*18eb7a2dSCharles.Forsyth /* dot is before c */
1040*18eb7a2dSCharles.Forsyth c = *(u->pitem);
1041*18eb7a2dSCharles.Forsyth if(c < NTBASE) {
1042*18eb7a2dSCharles.Forsyth u->flag = 0;
1043*18eb7a2dSCharles.Forsyth /* only interesting case is where . is before nonterminal */
1044*18eb7a2dSCharles.Forsyth continue;
1045*18eb7a2dSCharles.Forsyth }
1046*18eb7a2dSCharles.Forsyth
1047*18eb7a2dSCharles.Forsyth /* compute the lookahead */
1048*18eb7a2dSCharles.Forsyth aryfil(clset.lset, tbitset, 0);
1049*18eb7a2dSCharles.Forsyth
1050*18eb7a2dSCharles.Forsyth /* find items involving c */
1051*18eb7a2dSCharles.Forsyth WSLOOP(u, v)
1052*18eb7a2dSCharles.Forsyth if(v->flag == 1 && *(pi=v->pitem) == c) {
1053*18eb7a2dSCharles.Forsyth v->flag = 0;
1054*18eb7a2dSCharles.Forsyth if(nolook)
1055*18eb7a2dSCharles.Forsyth continue;
1056*18eb7a2dSCharles.Forsyth while((ch = *++pi) > 0) {
1057*18eb7a2dSCharles.Forsyth /* terminal symbol */
1058*18eb7a2dSCharles.Forsyth if(ch < NTBASE) {
1059*18eb7a2dSCharles.Forsyth SETBIT(clset.lset, ch);
1060*18eb7a2dSCharles.Forsyth break;
1061*18eb7a2dSCharles.Forsyth }
1062*18eb7a2dSCharles.Forsyth /* nonterminal symbol */
1063*18eb7a2dSCharles.Forsyth setunion(clset.lset, pfirst[ch-NTBASE]->lset);
1064*18eb7a2dSCharles.Forsyth if(!pempty[ch-NTBASE])
1065*18eb7a2dSCharles.Forsyth break;
1066*18eb7a2dSCharles.Forsyth }
1067*18eb7a2dSCharles.Forsyth if(ch <= 0)
1068*18eb7a2dSCharles.Forsyth setunion(clset.lset, v->ws.lset);
1069*18eb7a2dSCharles.Forsyth }
1070*18eb7a2dSCharles.Forsyth
1071*18eb7a2dSCharles.Forsyth /*
1072*18eb7a2dSCharles.Forsyth * now loop over productions derived from c
1073*18eb7a2dSCharles.Forsyth * c is now nonterminal number
1074*18eb7a2dSCharles.Forsyth */
1075*18eb7a2dSCharles.Forsyth c -= NTBASE;
1076*18eb7a2dSCharles.Forsyth t = pres[c+1];
1077*18eb7a2dSCharles.Forsyth for(s = pres[c]; s < t; ++s) {
1078*18eb7a2dSCharles.Forsyth /*
1079*18eb7a2dSCharles.Forsyth * put these items into the closure
1080*18eb7a2dSCharles.Forsyth * is the item there
1081*18eb7a2dSCharles.Forsyth */
1082*18eb7a2dSCharles.Forsyth WSLOOP(wsets, v)
1083*18eb7a2dSCharles.Forsyth /* yes, it is there */
1084*18eb7a2dSCharles.Forsyth if(v->pitem == *s) {
1085*18eb7a2dSCharles.Forsyth if(nolook)
1086*18eb7a2dSCharles.Forsyth goto nexts;
1087*18eb7a2dSCharles.Forsyth if(setunion(v->ws.lset, clset.lset))
1088*18eb7a2dSCharles.Forsyth v->flag = work = 1;
1089*18eb7a2dSCharles.Forsyth goto nexts;
1090*18eb7a2dSCharles.Forsyth }
1091*18eb7a2dSCharles.Forsyth
1092*18eb7a2dSCharles.Forsyth /* not there; make a new entry */
1093*18eb7a2dSCharles.Forsyth if(cwp-wsets+1 >= WSETSIZE)
1094*18eb7a2dSCharles.Forsyth error( "working set overflow");
1095*18eb7a2dSCharles.Forsyth cwp->pitem = *s;
1096*18eb7a2dSCharles.Forsyth cwp->flag = 1;
1097*18eb7a2dSCharles.Forsyth if(!nolook) {
1098*18eb7a2dSCharles.Forsyth work = 1;
1099*18eb7a2dSCharles.Forsyth SETLOOP(k) cwp->ws.lset[k] = clset.lset[k];
1100*18eb7a2dSCharles.Forsyth }
1101*18eb7a2dSCharles.Forsyth WSBUMP(cwp);
1102*18eb7a2dSCharles.Forsyth
1103*18eb7a2dSCharles.Forsyth nexts:;
1104*18eb7a2dSCharles.Forsyth }
1105*18eb7a2dSCharles.Forsyth }
1106*18eb7a2dSCharles.Forsyth }
1107*18eb7a2dSCharles.Forsyth
1108*18eb7a2dSCharles.Forsyth /* have computed closure; flags are reset; return */
1109*18eb7a2dSCharles.Forsyth if(cwp > zzcwp)
1110*18eb7a2dSCharles.Forsyth zzcwp = cwp;
1111*18eb7a2dSCharles.Forsyth if(cldebug && foutput != 0) {
1112*18eb7a2dSCharles.Forsyth Bprint(foutput, "\nState %d, nolook = %d\n", i, nolook);
1113*18eb7a2dSCharles.Forsyth WSLOOP(wsets, u) {
1114*18eb7a2dSCharles.Forsyth if(u->flag)
1115*18eb7a2dSCharles.Forsyth Bprint(foutput, "flag set!\n");
1116*18eb7a2dSCharles.Forsyth u->flag = 0;
1117*18eb7a2dSCharles.Forsyth Bprint(foutput, "\t%s", writem(u->pitem));
1118*18eb7a2dSCharles.Forsyth prlook(&u->ws);
1119*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n");
1120*18eb7a2dSCharles.Forsyth }
1121*18eb7a2dSCharles.Forsyth }
1122*18eb7a2dSCharles.Forsyth }
1123*18eb7a2dSCharles.Forsyth
1124*18eb7a2dSCharles.Forsyth /*
1125*18eb7a2dSCharles.Forsyth * decide if the lookahead set pointed to by p is known
1126*18eb7a2dSCharles.Forsyth * return pointer to a perminent location for the set
1127*18eb7a2dSCharles.Forsyth */
1128*18eb7a2dSCharles.Forsyth Lkset*
flset(Lkset * p)1129*18eb7a2dSCharles.Forsyth flset(Lkset *p)
1130*18eb7a2dSCharles.Forsyth {
1131*18eb7a2dSCharles.Forsyth Lkset *q;
1132*18eb7a2dSCharles.Forsyth int *u, *v, *w, j;
1133*18eb7a2dSCharles.Forsyth
1134*18eb7a2dSCharles.Forsyth for(q = &lkst[nlset]; q-- > lkst;) {
1135*18eb7a2dSCharles.Forsyth u = p->lset;
1136*18eb7a2dSCharles.Forsyth v = q->lset;
1137*18eb7a2dSCharles.Forsyth w = &v[tbitset];
1138*18eb7a2dSCharles.Forsyth while(v < w)
1139*18eb7a2dSCharles.Forsyth if(*u++ != *v++)
1140*18eb7a2dSCharles.Forsyth goto more;
1141*18eb7a2dSCharles.Forsyth /* we have matched */
1142*18eb7a2dSCharles.Forsyth return q;
1143*18eb7a2dSCharles.Forsyth more:;
1144*18eb7a2dSCharles.Forsyth }
1145*18eb7a2dSCharles.Forsyth /* add a new one */
1146*18eb7a2dSCharles.Forsyth q = &lkst[nlset++];
1147*18eb7a2dSCharles.Forsyth if(nlset >= LSETSIZE)
1148*18eb7a2dSCharles.Forsyth error("too many lookahead sets");
1149*18eb7a2dSCharles.Forsyth SETLOOP(j)
1150*18eb7a2dSCharles.Forsyth q->lset[j] = p->lset[j];
1151*18eb7a2dSCharles.Forsyth return q;
1152*18eb7a2dSCharles.Forsyth }
1153*18eb7a2dSCharles.Forsyth
1154*18eb7a2dSCharles.Forsyth void
cleantmp(void)1155*18eb7a2dSCharles.Forsyth cleantmp(void)
1156*18eb7a2dSCharles.Forsyth {
1157*18eb7a2dSCharles.Forsyth ZAPFILE(actname);
1158*18eb7a2dSCharles.Forsyth ZAPFILE(tempname);
1159*18eb7a2dSCharles.Forsyth }
1160*18eb7a2dSCharles.Forsyth
1161*18eb7a2dSCharles.Forsyth void
intr(void)1162*18eb7a2dSCharles.Forsyth intr(void)
1163*18eb7a2dSCharles.Forsyth {
1164*18eb7a2dSCharles.Forsyth cleantmp();
1165*18eb7a2dSCharles.Forsyth exits("interrupted");
1166*18eb7a2dSCharles.Forsyth }
1167*18eb7a2dSCharles.Forsyth
1168*18eb7a2dSCharles.Forsyth void
setup(int argc,char * argv[])1169*18eb7a2dSCharles.Forsyth setup(int argc, char *argv[])
1170*18eb7a2dSCharles.Forsyth {
1171*18eb7a2dSCharles.Forsyth long c, t;
1172*18eb7a2dSCharles.Forsyth int i, j, lev, ty, ytab, *p;
1173*18eb7a2dSCharles.Forsyth int vflag, dflag, stem;
1174*18eb7a2dSCharles.Forsyth char actnm[8], *stemc, *cp;
1175*18eb7a2dSCharles.Forsyth
1176*18eb7a2dSCharles.Forsyth ytab = 0;
1177*18eb7a2dSCharles.Forsyth vflag = 0;
1178*18eb7a2dSCharles.Forsyth dflag = 0;
1179*18eb7a2dSCharles.Forsyth stem = 0;
1180*18eb7a2dSCharles.Forsyth stemc = "y";
1181*18eb7a2dSCharles.Forsyth foutput = 0;
1182*18eb7a2dSCharles.Forsyth fdefine = 0;
1183*18eb7a2dSCharles.Forsyth fdebug = 0;
1184*18eb7a2dSCharles.Forsyth ARGBEGIN{
1185*18eb7a2dSCharles.Forsyth case 'v':
1186*18eb7a2dSCharles.Forsyth case 'V':
1187*18eb7a2dSCharles.Forsyth vflag++;
1188*18eb7a2dSCharles.Forsyth break;
1189*18eb7a2dSCharles.Forsyth case 'D':
1190*18eb7a2dSCharles.Forsyth yydebug = ARGF();
1191*18eb7a2dSCharles.Forsyth break;
1192*18eb7a2dSCharles.Forsyth case 'd':
1193*18eb7a2dSCharles.Forsyth dflag++;
1194*18eb7a2dSCharles.Forsyth break;
1195*18eb7a2dSCharles.Forsyth case 'o':
1196*18eb7a2dSCharles.Forsyth ytab++;
1197*18eb7a2dSCharles.Forsyth ytabc = ARGF();
1198*18eb7a2dSCharles.Forsyth break;
1199*18eb7a2dSCharles.Forsyth case 's':
1200*18eb7a2dSCharles.Forsyth stem++;
1201*18eb7a2dSCharles.Forsyth stemc = ARGF();
1202*18eb7a2dSCharles.Forsyth break;
1203*18eb7a2dSCharles.Forsyth case 'S':
1204*18eb7a2dSCharles.Forsyth parser = PARSERS;
1205*18eb7a2dSCharles.Forsyth break;
1206*18eb7a2dSCharles.Forsyth default:
1207*18eb7a2dSCharles.Forsyth error("illegal option: %c", ARGC());
1208*18eb7a2dSCharles.Forsyth }ARGEND
1209*18eb7a2dSCharles.Forsyth
1210*18eb7a2dSCharles.Forsyth cp = getenv("ROOT");
1211*18eb7a2dSCharles.Forsyth if(cp == 0)
1212*18eb7a2dSCharles.Forsyth cp = ROOT;
1213*18eb7a2dSCharles.Forsyth snprint(par, sizeof(par), "%s/utils/lib/%s", cp, parser);
1214*18eb7a2dSCharles.Forsyth parser = par;
1215*18eb7a2dSCharles.Forsyth
1216*18eb7a2dSCharles.Forsyth openup(stemc, dflag, vflag, ytab, ytabc);
1217*18eb7a2dSCharles.Forsyth
1218*18eb7a2dSCharles.Forsyth ftemp = Bopen(tempname = mktemp(ttempname), OWRITE);
1219*18eb7a2dSCharles.Forsyth faction = Bopen(actname = mktemp(tactname), OWRITE);
1220*18eb7a2dSCharles.Forsyth if(ftemp == 0 || faction == 0)
1221*18eb7a2dSCharles.Forsyth error("cannot open temp file");
1222*18eb7a2dSCharles.Forsyth if(argc < 1)
1223*18eb7a2dSCharles.Forsyth error("no input file");
1224*18eb7a2dSCharles.Forsyth infile = argv[0];
1225*18eb7a2dSCharles.Forsyth finput = Bopen(infile, OREAD);
1226*18eb7a2dSCharles.Forsyth if(finput == 0)
1227*18eb7a2dSCharles.Forsyth error("cannot open '%s'", argv[0]);
1228*18eb7a2dSCharles.Forsyth cnamp = cnames;
1229*18eb7a2dSCharles.Forsyth
1230*18eb7a2dSCharles.Forsyth defin(0, "$end");
1231*18eb7a2dSCharles.Forsyth extval = PRIVATE; /* tokens start in unicode 'private use' */
1232*18eb7a2dSCharles.Forsyth defin(0, "error");
1233*18eb7a2dSCharles.Forsyth defin(1, "$accept");
1234*18eb7a2dSCharles.Forsyth defin(0, "$unk");
1235*18eb7a2dSCharles.Forsyth mem = mem0;
1236*18eb7a2dSCharles.Forsyth i = 0;
1237*18eb7a2dSCharles.Forsyth
1238*18eb7a2dSCharles.Forsyth for(t = gettok(); t != MARK && t != ENDFILE;)
1239*18eb7a2dSCharles.Forsyth switch(t) {
1240*18eb7a2dSCharles.Forsyth case ';':
1241*18eb7a2dSCharles.Forsyth t = gettok();
1242*18eb7a2dSCharles.Forsyth break;
1243*18eb7a2dSCharles.Forsyth
1244*18eb7a2dSCharles.Forsyth case START:
1245*18eb7a2dSCharles.Forsyth if(gettok() != IDENTIFIER)
1246*18eb7a2dSCharles.Forsyth error("bad %%start construction");
1247*18eb7a2dSCharles.Forsyth start = chfind(1, tokname);
1248*18eb7a2dSCharles.Forsyth t = gettok();
1249*18eb7a2dSCharles.Forsyth continue;
1250*18eb7a2dSCharles.Forsyth
1251*18eb7a2dSCharles.Forsyth case TYPEDEF:
1252*18eb7a2dSCharles.Forsyth if(gettok() != TYPENAME)
1253*18eb7a2dSCharles.Forsyth error("bad syntax in %%type");
1254*18eb7a2dSCharles.Forsyth ty = numbval;
1255*18eb7a2dSCharles.Forsyth for(;;) {
1256*18eb7a2dSCharles.Forsyth t = gettok();
1257*18eb7a2dSCharles.Forsyth switch(t) {
1258*18eb7a2dSCharles.Forsyth case IDENTIFIER:
1259*18eb7a2dSCharles.Forsyth if((t=chfind(1, tokname)) < NTBASE) {
1260*18eb7a2dSCharles.Forsyth j = TYPE(toklev[t]);
1261*18eb7a2dSCharles.Forsyth if(j != 0 && j != ty)
1262*18eb7a2dSCharles.Forsyth error("type redeclaration of token %s",
1263*18eb7a2dSCharles.Forsyth tokset[t].name);
1264*18eb7a2dSCharles.Forsyth else
1265*18eb7a2dSCharles.Forsyth SETTYPE(toklev[t], ty);
1266*18eb7a2dSCharles.Forsyth } else {
1267*18eb7a2dSCharles.Forsyth j = nontrst[t-NTBASE].value;
1268*18eb7a2dSCharles.Forsyth if(j != 0 && j != ty)
1269*18eb7a2dSCharles.Forsyth error("type redeclaration of nonterminal %s",
1270*18eb7a2dSCharles.Forsyth nontrst[t-NTBASE].name );
1271*18eb7a2dSCharles.Forsyth else
1272*18eb7a2dSCharles.Forsyth nontrst[t-NTBASE].value = ty;
1273*18eb7a2dSCharles.Forsyth }
1274*18eb7a2dSCharles.Forsyth case ',':
1275*18eb7a2dSCharles.Forsyth continue;
1276*18eb7a2dSCharles.Forsyth case ';':
1277*18eb7a2dSCharles.Forsyth t = gettok();
1278*18eb7a2dSCharles.Forsyth default:
1279*18eb7a2dSCharles.Forsyth break;
1280*18eb7a2dSCharles.Forsyth }
1281*18eb7a2dSCharles.Forsyth break;
1282*18eb7a2dSCharles.Forsyth }
1283*18eb7a2dSCharles.Forsyth continue;
1284*18eb7a2dSCharles.Forsyth
1285*18eb7a2dSCharles.Forsyth case UNION:
1286*18eb7a2dSCharles.Forsyth /* copy the union declaration to the output */
1287*18eb7a2dSCharles.Forsyth cpyunion();
1288*18eb7a2dSCharles.Forsyth t = gettok();
1289*18eb7a2dSCharles.Forsyth continue;
1290*18eb7a2dSCharles.Forsyth
1291*18eb7a2dSCharles.Forsyth case LEFT:
1292*18eb7a2dSCharles.Forsyth case BINARY:
1293*18eb7a2dSCharles.Forsyth case RIGHT:
1294*18eb7a2dSCharles.Forsyth i++;
1295*18eb7a2dSCharles.Forsyth
1296*18eb7a2dSCharles.Forsyth case TERM:
1297*18eb7a2dSCharles.Forsyth /* nonzero means new prec. and assoc. */
1298*18eb7a2dSCharles.Forsyth lev = t-TERM;
1299*18eb7a2dSCharles.Forsyth ty = 0;
1300*18eb7a2dSCharles.Forsyth
1301*18eb7a2dSCharles.Forsyth /* get identifiers so defined */
1302*18eb7a2dSCharles.Forsyth t = gettok();
1303*18eb7a2dSCharles.Forsyth
1304*18eb7a2dSCharles.Forsyth /* there is a type defined */
1305*18eb7a2dSCharles.Forsyth if(t == TYPENAME) {
1306*18eb7a2dSCharles.Forsyth ty = numbval;
1307*18eb7a2dSCharles.Forsyth t = gettok();
1308*18eb7a2dSCharles.Forsyth }
1309*18eb7a2dSCharles.Forsyth for(;;) {
1310*18eb7a2dSCharles.Forsyth switch(t) {
1311*18eb7a2dSCharles.Forsyth case ',':
1312*18eb7a2dSCharles.Forsyth t = gettok();
1313*18eb7a2dSCharles.Forsyth continue;
1314*18eb7a2dSCharles.Forsyth
1315*18eb7a2dSCharles.Forsyth case ';':
1316*18eb7a2dSCharles.Forsyth break;
1317*18eb7a2dSCharles.Forsyth
1318*18eb7a2dSCharles.Forsyth case IDENTIFIER:
1319*18eb7a2dSCharles.Forsyth j = chfind(0, tokname);
1320*18eb7a2dSCharles.Forsyth if(j >= NTBASE)
1321*18eb7a2dSCharles.Forsyth error("%s defined earlier as nonterminal", tokname);
1322*18eb7a2dSCharles.Forsyth if(lev) {
1323*18eb7a2dSCharles.Forsyth if(ASSOC(toklev[j]))
1324*18eb7a2dSCharles.Forsyth error("redeclaration of precedence of %s", tokname);
1325*18eb7a2dSCharles.Forsyth SETASC(toklev[j], lev);
1326*18eb7a2dSCharles.Forsyth SETPLEV(toklev[j], i);
1327*18eb7a2dSCharles.Forsyth }
1328*18eb7a2dSCharles.Forsyth if(ty) {
1329*18eb7a2dSCharles.Forsyth if(TYPE(toklev[j]))
1330*18eb7a2dSCharles.Forsyth error("redeclaration of type of %s", tokname);
1331*18eb7a2dSCharles.Forsyth SETTYPE(toklev[j],ty);
1332*18eb7a2dSCharles.Forsyth }
1333*18eb7a2dSCharles.Forsyth t = gettok();
1334*18eb7a2dSCharles.Forsyth if(t == NUMBER) {
1335*18eb7a2dSCharles.Forsyth tokset[j].value = numbval;
1336*18eb7a2dSCharles.Forsyth if(j < ndefout && j > 3)
1337*18eb7a2dSCharles.Forsyth error("please define type number of %s earlier",
1338*18eb7a2dSCharles.Forsyth tokset[j].name);
1339*18eb7a2dSCharles.Forsyth t = gettok();
1340*18eb7a2dSCharles.Forsyth }
1341*18eb7a2dSCharles.Forsyth continue;
1342*18eb7a2dSCharles.Forsyth }
1343*18eb7a2dSCharles.Forsyth break;
1344*18eb7a2dSCharles.Forsyth }
1345*18eb7a2dSCharles.Forsyth continue;
1346*18eb7a2dSCharles.Forsyth
1347*18eb7a2dSCharles.Forsyth case LCURLY:
1348*18eb7a2dSCharles.Forsyth defout(0);
1349*18eb7a2dSCharles.Forsyth cpycode();
1350*18eb7a2dSCharles.Forsyth t = gettok();
1351*18eb7a2dSCharles.Forsyth continue;
1352*18eb7a2dSCharles.Forsyth
1353*18eb7a2dSCharles.Forsyth default:
1354*18eb7a2dSCharles.Forsyth error("syntax error");
1355*18eb7a2dSCharles.Forsyth }
1356*18eb7a2dSCharles.Forsyth if(t == ENDFILE)
1357*18eb7a2dSCharles.Forsyth error("unexpected EOF before %%");
1358*18eb7a2dSCharles.Forsyth
1359*18eb7a2dSCharles.Forsyth /* t is MARK */
1360*18eb7a2dSCharles.Forsyth Bprint(ftable, "extern int yyerrflag;\n");
1361*18eb7a2dSCharles.Forsyth Bprint(ftable, "#ifndef YYMAXDEPTH\n");
1362*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define YYMAXDEPTH 150\n");
1363*18eb7a2dSCharles.Forsyth Bprint(ftable, "#endif\n" );
1364*18eb7a2dSCharles.Forsyth if(!ntypes) {
1365*18eb7a2dSCharles.Forsyth Bprint(ftable, "#ifndef YYSTYPE\n");
1366*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define YYSTYPE int\n");
1367*18eb7a2dSCharles.Forsyth Bprint(ftable, "#endif\n");
1368*18eb7a2dSCharles.Forsyth }
1369*18eb7a2dSCharles.Forsyth Bprint(ftable, "YYSTYPE yylval;\n");
1370*18eb7a2dSCharles.Forsyth Bprint(ftable, "YYSTYPE yyval;\n");
1371*18eb7a2dSCharles.Forsyth
1372*18eb7a2dSCharles.Forsyth prdptr[0] = mem;
1373*18eb7a2dSCharles.Forsyth
1374*18eb7a2dSCharles.Forsyth /* added production */
1375*18eb7a2dSCharles.Forsyth *mem++ = NTBASE;
1376*18eb7a2dSCharles.Forsyth
1377*18eb7a2dSCharles.Forsyth /* if start is 0, we will overwrite with the lhs of the first rule */
1378*18eb7a2dSCharles.Forsyth *mem++ = start;
1379*18eb7a2dSCharles.Forsyth *mem++ = 1;
1380*18eb7a2dSCharles.Forsyth *mem++ = 0;
1381*18eb7a2dSCharles.Forsyth prdptr[1] = mem;
1382*18eb7a2dSCharles.Forsyth while((t=gettok()) == LCURLY)
1383*18eb7a2dSCharles.Forsyth cpycode();
1384*18eb7a2dSCharles.Forsyth if(t != IDENTCOLON)
1385*18eb7a2dSCharles.Forsyth error("bad syntax on first rule");
1386*18eb7a2dSCharles.Forsyth
1387*18eb7a2dSCharles.Forsyth if(!start)
1388*18eb7a2dSCharles.Forsyth prdptr[0][1] = chfind(1, tokname);
1389*18eb7a2dSCharles.Forsyth
1390*18eb7a2dSCharles.Forsyth /* read rules */
1391*18eb7a2dSCharles.Forsyth while(t != MARK && t != ENDFILE) {
1392*18eb7a2dSCharles.Forsyth /* process a rule */
1393*18eb7a2dSCharles.Forsyth rlines[nprod] = lineno;
1394*18eb7a2dSCharles.Forsyth if(t == '|')
1395*18eb7a2dSCharles.Forsyth *mem++ = *prdptr[nprod-1];
1396*18eb7a2dSCharles.Forsyth else
1397*18eb7a2dSCharles.Forsyth if(t == IDENTCOLON) {
1398*18eb7a2dSCharles.Forsyth *mem = chfind(1, tokname);
1399*18eb7a2dSCharles.Forsyth if(*mem < NTBASE)
1400*18eb7a2dSCharles.Forsyth error("token illegal on LHS of grammar rule");
1401*18eb7a2dSCharles.Forsyth mem++;
1402*18eb7a2dSCharles.Forsyth } else
1403*18eb7a2dSCharles.Forsyth error("illegal rule: missing semicolon or | ?");
1404*18eb7a2dSCharles.Forsyth /* read rule body */
1405*18eb7a2dSCharles.Forsyth t = gettok();
1406*18eb7a2dSCharles.Forsyth
1407*18eb7a2dSCharles.Forsyth more_rule:
1408*18eb7a2dSCharles.Forsyth while(t == IDENTIFIER) {
1409*18eb7a2dSCharles.Forsyth *mem = chfind(1, tokname);
1410*18eb7a2dSCharles.Forsyth if(*mem < NTBASE)
1411*18eb7a2dSCharles.Forsyth levprd[nprod] = toklev[*mem];
1412*18eb7a2dSCharles.Forsyth mem++;
1413*18eb7a2dSCharles.Forsyth t = gettok();
1414*18eb7a2dSCharles.Forsyth }
1415*18eb7a2dSCharles.Forsyth if(t == PREC) {
1416*18eb7a2dSCharles.Forsyth if(gettok() != IDENTIFIER)
1417*18eb7a2dSCharles.Forsyth error("illegal %%prec syntax");
1418*18eb7a2dSCharles.Forsyth j = chfind(2, tokname);
1419*18eb7a2dSCharles.Forsyth if(j >= NTBASE)
1420*18eb7a2dSCharles.Forsyth error("nonterminal %s illegal after %%prec",
1421*18eb7a2dSCharles.Forsyth nontrst[j-NTBASE].name);
1422*18eb7a2dSCharles.Forsyth levprd[nprod] = toklev[j];
1423*18eb7a2dSCharles.Forsyth t = gettok();
1424*18eb7a2dSCharles.Forsyth }
1425*18eb7a2dSCharles.Forsyth if(t == '=') {
1426*18eb7a2dSCharles.Forsyth levprd[nprod] |= ACTFLAG;
1427*18eb7a2dSCharles.Forsyth Bprint(faction, "\ncase %d:", nprod);
1428*18eb7a2dSCharles.Forsyth cpyact(mem-prdptr[nprod]-1);
1429*18eb7a2dSCharles.Forsyth Bprint(faction, " break;");
1430*18eb7a2dSCharles.Forsyth if((t=gettok()) == IDENTIFIER) {
1431*18eb7a2dSCharles.Forsyth
1432*18eb7a2dSCharles.Forsyth /* action within rule... */
1433*18eb7a2dSCharles.Forsyth sprint(actnm, "$$%d", nprod);
1434*18eb7a2dSCharles.Forsyth
1435*18eb7a2dSCharles.Forsyth /* make it a nonterminal */
1436*18eb7a2dSCharles.Forsyth j = chfind(1, actnm);
1437*18eb7a2dSCharles.Forsyth
1438*18eb7a2dSCharles.Forsyth /*
1439*18eb7a2dSCharles.Forsyth * the current rule will become rule number nprod+1
1440*18eb7a2dSCharles.Forsyth * move the contents down, and make room for the null
1441*18eb7a2dSCharles.Forsyth */
1442*18eb7a2dSCharles.Forsyth for(p = mem; p >= prdptr[nprod]; --p)
1443*18eb7a2dSCharles.Forsyth p[2] = *p;
1444*18eb7a2dSCharles.Forsyth mem += 2;
1445*18eb7a2dSCharles.Forsyth
1446*18eb7a2dSCharles.Forsyth /* enter null production for action */
1447*18eb7a2dSCharles.Forsyth p = prdptr[nprod];
1448*18eb7a2dSCharles.Forsyth *p++ = j;
1449*18eb7a2dSCharles.Forsyth *p++ = -nprod;
1450*18eb7a2dSCharles.Forsyth
1451*18eb7a2dSCharles.Forsyth /* update the production information */
1452*18eb7a2dSCharles.Forsyth levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
1453*18eb7a2dSCharles.Forsyth levprd[nprod] = ACTFLAG;
1454*18eb7a2dSCharles.Forsyth if(++nprod >= NPROD)
1455*18eb7a2dSCharles.Forsyth error("more than %d rules", NPROD);
1456*18eb7a2dSCharles.Forsyth prdptr[nprod] = p;
1457*18eb7a2dSCharles.Forsyth
1458*18eb7a2dSCharles.Forsyth /* make the action appear in the original rule */
1459*18eb7a2dSCharles.Forsyth *mem++ = j;
1460*18eb7a2dSCharles.Forsyth
1461*18eb7a2dSCharles.Forsyth /* get some more of the rule */
1462*18eb7a2dSCharles.Forsyth goto more_rule;
1463*18eb7a2dSCharles.Forsyth }
1464*18eb7a2dSCharles.Forsyth }
1465*18eb7a2dSCharles.Forsyth
1466*18eb7a2dSCharles.Forsyth while(t == ';')
1467*18eb7a2dSCharles.Forsyth t = gettok();
1468*18eb7a2dSCharles.Forsyth *mem++ = -nprod;
1469*18eb7a2dSCharles.Forsyth
1470*18eb7a2dSCharles.Forsyth /* check that default action is reasonable */
1471*18eb7a2dSCharles.Forsyth if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
1472*18eb7a2dSCharles.Forsyth
1473*18eb7a2dSCharles.Forsyth /* no explicit action, LHS has value */
1474*18eb7a2dSCharles.Forsyth int tempty;
1475*18eb7a2dSCharles.Forsyth
1476*18eb7a2dSCharles.Forsyth tempty = prdptr[nprod][1];
1477*18eb7a2dSCharles.Forsyth if(tempty < 0)
1478*18eb7a2dSCharles.Forsyth error("must return a value, since LHS has a type");
1479*18eb7a2dSCharles.Forsyth else
1480*18eb7a2dSCharles.Forsyth if(tempty >= NTBASE)
1481*18eb7a2dSCharles.Forsyth tempty = nontrst[tempty-NTBASE].value;
1482*18eb7a2dSCharles.Forsyth else
1483*18eb7a2dSCharles.Forsyth tempty = TYPE(toklev[tempty]);
1484*18eb7a2dSCharles.Forsyth if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
1485*18eb7a2dSCharles.Forsyth error("default action causes potential type clash");
1486*18eb7a2dSCharles.Forsyth }
1487*18eb7a2dSCharles.Forsyth nprod++;
1488*18eb7a2dSCharles.Forsyth if(nprod >= NPROD)
1489*18eb7a2dSCharles.Forsyth error("more than %d rules", NPROD);
1490*18eb7a2dSCharles.Forsyth prdptr[nprod] = mem;
1491*18eb7a2dSCharles.Forsyth levprd[nprod] = 0;
1492*18eb7a2dSCharles.Forsyth }
1493*18eb7a2dSCharles.Forsyth
1494*18eb7a2dSCharles.Forsyth /* end of all rules */
1495*18eb7a2dSCharles.Forsyth defout(1);
1496*18eb7a2dSCharles.Forsyth
1497*18eb7a2dSCharles.Forsyth finact();
1498*18eb7a2dSCharles.Forsyth if(t == MARK) {
1499*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
1500*18eb7a2dSCharles.Forsyth while((c=Bgetrune(finput)) != Beof)
1501*18eb7a2dSCharles.Forsyth Bputrune(ftable, c);
1502*18eb7a2dSCharles.Forsyth }
1503*18eb7a2dSCharles.Forsyth Bterm(finput);
1504*18eb7a2dSCharles.Forsyth }
1505*18eb7a2dSCharles.Forsyth
1506*18eb7a2dSCharles.Forsyth /*
1507*18eb7a2dSCharles.Forsyth * finish action routine
1508*18eb7a2dSCharles.Forsyth */
1509*18eb7a2dSCharles.Forsyth void
finact(void)1510*18eb7a2dSCharles.Forsyth finact(void)
1511*18eb7a2dSCharles.Forsyth {
1512*18eb7a2dSCharles.Forsyth
1513*18eb7a2dSCharles.Forsyth Bterm(faction);
1514*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define YYEOFCODE %d\n", 1);
1515*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define YYERRCODE %d\n", 2);
1516*18eb7a2dSCharles.Forsyth }
1517*18eb7a2dSCharles.Forsyth
1518*18eb7a2dSCharles.Forsyth /*
1519*18eb7a2dSCharles.Forsyth * define s to be a terminal if t=0
1520*18eb7a2dSCharles.Forsyth * or a nonterminal if t=1
1521*18eb7a2dSCharles.Forsyth */
1522*18eb7a2dSCharles.Forsyth int
defin(int nt,char * s)1523*18eb7a2dSCharles.Forsyth defin(int nt, char *s)
1524*18eb7a2dSCharles.Forsyth {
1525*18eb7a2dSCharles.Forsyth int val;
1526*18eb7a2dSCharles.Forsyth Rune rune;
1527*18eb7a2dSCharles.Forsyth
1528*18eb7a2dSCharles.Forsyth val = 0;
1529*18eb7a2dSCharles.Forsyth if(nt) {
1530*18eb7a2dSCharles.Forsyth nnonter++;
1531*18eb7a2dSCharles.Forsyth if(nnonter >= NNONTERM)
1532*18eb7a2dSCharles.Forsyth error("too many nonterminals, limit %d",NNONTERM);
1533*18eb7a2dSCharles.Forsyth nontrst[nnonter].name = cstash(s);
1534*18eb7a2dSCharles.Forsyth return NTBASE + nnonter;
1535*18eb7a2dSCharles.Forsyth }
1536*18eb7a2dSCharles.Forsyth
1537*18eb7a2dSCharles.Forsyth /* must be a token */
1538*18eb7a2dSCharles.Forsyth ntokens++;
1539*18eb7a2dSCharles.Forsyth if(ntokens >= NTERMS)
1540*18eb7a2dSCharles.Forsyth error("too many terminals, limit %d", NTERMS);
1541*18eb7a2dSCharles.Forsyth tokset[ntokens].name = cstash(s);
1542*18eb7a2dSCharles.Forsyth
1543*18eb7a2dSCharles.Forsyth /* establish value for token */
1544*18eb7a2dSCharles.Forsyth /* single character literal */
1545*18eb7a2dSCharles.Forsyth if(s[0] == ' ') {
1546*18eb7a2dSCharles.Forsyth val = chartorune(&rune, &s[1]);
1547*18eb7a2dSCharles.Forsyth if(s[val+1] == 0) {
1548*18eb7a2dSCharles.Forsyth val = rune;
1549*18eb7a2dSCharles.Forsyth goto out;
1550*18eb7a2dSCharles.Forsyth }
1551*18eb7a2dSCharles.Forsyth }
1552*18eb7a2dSCharles.Forsyth
1553*18eb7a2dSCharles.Forsyth /* escape sequence */
1554*18eb7a2dSCharles.Forsyth if(s[0] == ' ' && s[1] == '\\') {
1555*18eb7a2dSCharles.Forsyth if(s[3] == 0) {
1556*18eb7a2dSCharles.Forsyth /* single character escape sequence */
1557*18eb7a2dSCharles.Forsyth switch(s[2]) {
1558*18eb7a2dSCharles.Forsyth case 'n': val = '\n'; break;
1559*18eb7a2dSCharles.Forsyth case 'r': val = '\r'; break;
1560*18eb7a2dSCharles.Forsyth case 'b': val = '\b'; break;
1561*18eb7a2dSCharles.Forsyth case 't': val = '\t'; break;
1562*18eb7a2dSCharles.Forsyth case 'f': val = '\f'; break;
1563*18eb7a2dSCharles.Forsyth case '\'': val = '\''; break;
1564*18eb7a2dSCharles.Forsyth case '"': val = '"'; break;
1565*18eb7a2dSCharles.Forsyth case '\\': val = '\\'; break;
1566*18eb7a2dSCharles.Forsyth default: error("invalid escape");
1567*18eb7a2dSCharles.Forsyth }
1568*18eb7a2dSCharles.Forsyth goto out;
1569*18eb7a2dSCharles.Forsyth }
1570*18eb7a2dSCharles.Forsyth
1571*18eb7a2dSCharles.Forsyth /* \nnn sequence */
1572*18eb7a2dSCharles.Forsyth if(s[2] >= '0' && s[2] <= '7') {
1573*18eb7a2dSCharles.Forsyth if(s[3] < '0' ||
1574*18eb7a2dSCharles.Forsyth s[3] > '7' ||
1575*18eb7a2dSCharles.Forsyth s[4] < '0' ||
1576*18eb7a2dSCharles.Forsyth s[4] > '7' ||
1577*18eb7a2dSCharles.Forsyth s[5] != 0)
1578*18eb7a2dSCharles.Forsyth error("illegal \\nnn construction");
1579*18eb7a2dSCharles.Forsyth val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
1580*18eb7a2dSCharles.Forsyth if(val == 0)
1581*18eb7a2dSCharles.Forsyth error("'\\000' is illegal");
1582*18eb7a2dSCharles.Forsyth goto out;
1583*18eb7a2dSCharles.Forsyth }
1584*18eb7a2dSCharles.Forsyth error("unknown escape");
1585*18eb7a2dSCharles.Forsyth }
1586*18eb7a2dSCharles.Forsyth val = extval++;
1587*18eb7a2dSCharles.Forsyth
1588*18eb7a2dSCharles.Forsyth out:
1589*18eb7a2dSCharles.Forsyth tokset[ntokens].value = val;
1590*18eb7a2dSCharles.Forsyth toklev[ntokens] = 0;
1591*18eb7a2dSCharles.Forsyth return ntokens;
1592*18eb7a2dSCharles.Forsyth }
1593*18eb7a2dSCharles.Forsyth
1594*18eb7a2dSCharles.Forsyth /*
1595*18eb7a2dSCharles.Forsyth * write out the defines (at the end of the declaration section)
1596*18eb7a2dSCharles.Forsyth */
1597*18eb7a2dSCharles.Forsyth void
defout(int last)1598*18eb7a2dSCharles.Forsyth defout(int last)
1599*18eb7a2dSCharles.Forsyth {
1600*18eb7a2dSCharles.Forsyth int i, c;
1601*18eb7a2dSCharles.Forsyth char sar[NAMESIZE+10];
1602*18eb7a2dSCharles.Forsyth
1603*18eb7a2dSCharles.Forsyth for(i=ndefout; i<=ntokens; i++) {
1604*18eb7a2dSCharles.Forsyth /* non-literals */
1605*18eb7a2dSCharles.Forsyth c = tokset[i].name[0];
1606*18eb7a2dSCharles.Forsyth if(c != ' ' && c != '$') {
1607*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define %s %d\n",
1608*18eb7a2dSCharles.Forsyth tokset[i].name, tokset[i].value);
1609*18eb7a2dSCharles.Forsyth if(fdefine)
1610*18eb7a2dSCharles.Forsyth Bprint(fdefine, "#define\t%s\t%d\n",
1611*18eb7a2dSCharles.Forsyth tokset[i].name, tokset[i].value);
1612*18eb7a2dSCharles.Forsyth }
1613*18eb7a2dSCharles.Forsyth }
1614*18eb7a2dSCharles.Forsyth ndefout = ntokens+1;
1615*18eb7a2dSCharles.Forsyth if(last && fdebug) {
1616*18eb7a2dSCharles.Forsyth Bprint(fdebug, "char* yytoknames[] =\n{\n");
1617*18eb7a2dSCharles.Forsyth TLOOP(i) {
1618*18eb7a2dSCharles.Forsyth if(tokset[i].name) {
1619*18eb7a2dSCharles.Forsyth chcopy(sar, tokset[i].name);
1620*18eb7a2dSCharles.Forsyth Bprint(fdebug, "\t\"%s\",\n", sar);
1621*18eb7a2dSCharles.Forsyth continue;
1622*18eb7a2dSCharles.Forsyth }
1623*18eb7a2dSCharles.Forsyth Bprint(fdebug, "\t0,\n");
1624*18eb7a2dSCharles.Forsyth }
1625*18eb7a2dSCharles.Forsyth Bprint(fdebug, "};\n");
1626*18eb7a2dSCharles.Forsyth }
1627*18eb7a2dSCharles.Forsyth }
1628*18eb7a2dSCharles.Forsyth
1629*18eb7a2dSCharles.Forsyth char*
cstash(char * s)1630*18eb7a2dSCharles.Forsyth cstash(char *s)
1631*18eb7a2dSCharles.Forsyth {
1632*18eb7a2dSCharles.Forsyth char *temp;
1633*18eb7a2dSCharles.Forsyth
1634*18eb7a2dSCharles.Forsyth temp = cnamp;
1635*18eb7a2dSCharles.Forsyth do {
1636*18eb7a2dSCharles.Forsyth if(cnamp >= &cnames[cnamsz])
1637*18eb7a2dSCharles.Forsyth error("too many characters in id's and literals");
1638*18eb7a2dSCharles.Forsyth else
1639*18eb7a2dSCharles.Forsyth *cnamp++ = *s;
1640*18eb7a2dSCharles.Forsyth } while(*s++);
1641*18eb7a2dSCharles.Forsyth return temp;
1642*18eb7a2dSCharles.Forsyth }
1643*18eb7a2dSCharles.Forsyth
1644*18eb7a2dSCharles.Forsyth long
gettok(void)1645*18eb7a2dSCharles.Forsyth gettok(void)
1646*18eb7a2dSCharles.Forsyth {
1647*18eb7a2dSCharles.Forsyth long c;
1648*18eb7a2dSCharles.Forsyth Rune rune;
1649*18eb7a2dSCharles.Forsyth int i, base, match, reserve;
1650*18eb7a2dSCharles.Forsyth static int peekline;
1651*18eb7a2dSCharles.Forsyth
1652*18eb7a2dSCharles.Forsyth begin:
1653*18eb7a2dSCharles.Forsyth reserve = 0;
1654*18eb7a2dSCharles.Forsyth lineno += peekline;
1655*18eb7a2dSCharles.Forsyth peekline = 0;
1656*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1657*18eb7a2dSCharles.Forsyth while(c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r') {
1658*18eb7a2dSCharles.Forsyth if(c == '\n')
1659*18eb7a2dSCharles.Forsyth lineno++;
1660*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1661*18eb7a2dSCharles.Forsyth }
1662*18eb7a2dSCharles.Forsyth
1663*18eb7a2dSCharles.Forsyth /* skip comment */
1664*18eb7a2dSCharles.Forsyth if(c == '/') {
1665*18eb7a2dSCharles.Forsyth lineno += skipcom();
1666*18eb7a2dSCharles.Forsyth goto begin;
1667*18eb7a2dSCharles.Forsyth }
1668*18eb7a2dSCharles.Forsyth switch(c) {
1669*18eb7a2dSCharles.Forsyth case Beof:
1670*18eb7a2dSCharles.Forsyth return ENDFILE;
1671*18eb7a2dSCharles.Forsyth
1672*18eb7a2dSCharles.Forsyth case '{':
1673*18eb7a2dSCharles.Forsyth Bungetrune(finput);
1674*18eb7a2dSCharles.Forsyth return '=';
1675*18eb7a2dSCharles.Forsyth
1676*18eb7a2dSCharles.Forsyth case '<':
1677*18eb7a2dSCharles.Forsyth /* get, and look up, a type name (union member name) */
1678*18eb7a2dSCharles.Forsyth i = 0;
1679*18eb7a2dSCharles.Forsyth while((c=Bgetrune(finput)) != '>' && c >= 0 && c != '\n' && c != '\r') {
1680*18eb7a2dSCharles.Forsyth rune = c;
1681*18eb7a2dSCharles.Forsyth c = runetochar(&tokname[i], &rune);
1682*18eb7a2dSCharles.Forsyth if(i < NAMESIZE)
1683*18eb7a2dSCharles.Forsyth i += c;
1684*18eb7a2dSCharles.Forsyth }
1685*18eb7a2dSCharles.Forsyth if(c != '>')
1686*18eb7a2dSCharles.Forsyth error("unterminated < ... > clause");
1687*18eb7a2dSCharles.Forsyth tokname[i] = 0;
1688*18eb7a2dSCharles.Forsyth for(i=1; i<=ntypes; i++)
1689*18eb7a2dSCharles.Forsyth if(!strcmp(typeset[i], tokname)) {
1690*18eb7a2dSCharles.Forsyth numbval = i;
1691*18eb7a2dSCharles.Forsyth return TYPENAME;
1692*18eb7a2dSCharles.Forsyth }
1693*18eb7a2dSCharles.Forsyth ntypes++;
1694*18eb7a2dSCharles.Forsyth numbval = ntypes;
1695*18eb7a2dSCharles.Forsyth typeset[numbval] = cstash(tokname);
1696*18eb7a2dSCharles.Forsyth return TYPENAME;
1697*18eb7a2dSCharles.Forsyth
1698*18eb7a2dSCharles.Forsyth case '"':
1699*18eb7a2dSCharles.Forsyth case '\'':
1700*18eb7a2dSCharles.Forsyth match = c;
1701*18eb7a2dSCharles.Forsyth tokname[0] = ' ';
1702*18eb7a2dSCharles.Forsyth i = 1;
1703*18eb7a2dSCharles.Forsyth for(;;) {
1704*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1705*18eb7a2dSCharles.Forsyth if(c == '\n' || c == '\r' || c <= 0)
1706*18eb7a2dSCharles.Forsyth error("illegal or missing ' or \"" );
1707*18eb7a2dSCharles.Forsyth if(c == '\\') {
1708*18eb7a2dSCharles.Forsyth tokname[i] = '\\';
1709*18eb7a2dSCharles.Forsyth if(i < NAMESIZE)
1710*18eb7a2dSCharles.Forsyth i++;
1711*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1712*18eb7a2dSCharles.Forsyth } else
1713*18eb7a2dSCharles.Forsyth if(c == match)
1714*18eb7a2dSCharles.Forsyth break;
1715*18eb7a2dSCharles.Forsyth rune = c;
1716*18eb7a2dSCharles.Forsyth c = runetochar(&tokname[i], &rune);
1717*18eb7a2dSCharles.Forsyth if(i < NAMESIZE)
1718*18eb7a2dSCharles.Forsyth i += c;
1719*18eb7a2dSCharles.Forsyth }
1720*18eb7a2dSCharles.Forsyth break;
1721*18eb7a2dSCharles.Forsyth
1722*18eb7a2dSCharles.Forsyth case '%':
1723*18eb7a2dSCharles.Forsyth case '\\':
1724*18eb7a2dSCharles.Forsyth switch(c = Bgetrune(finput)) {
1725*18eb7a2dSCharles.Forsyth case '0': return TERM;
1726*18eb7a2dSCharles.Forsyth case '<': return LEFT;
1727*18eb7a2dSCharles.Forsyth case '2': return BINARY;
1728*18eb7a2dSCharles.Forsyth case '>': return RIGHT;
1729*18eb7a2dSCharles.Forsyth case '%':
1730*18eb7a2dSCharles.Forsyth case '\\': return MARK;
1731*18eb7a2dSCharles.Forsyth case '=': return PREC;
1732*18eb7a2dSCharles.Forsyth case '{': return LCURLY;
1733*18eb7a2dSCharles.Forsyth default: reserve = 1;
1734*18eb7a2dSCharles.Forsyth }
1735*18eb7a2dSCharles.Forsyth
1736*18eb7a2dSCharles.Forsyth default:
1737*18eb7a2dSCharles.Forsyth /* number */
1738*18eb7a2dSCharles.Forsyth if(isdigit(c)) {
1739*18eb7a2dSCharles.Forsyth numbval = c-'0';
1740*18eb7a2dSCharles.Forsyth base = (c=='0')? 8: 10;
1741*18eb7a2dSCharles.Forsyth for(c = Bgetrune(finput); isdigit(c); c = Bgetrune(finput))
1742*18eb7a2dSCharles.Forsyth numbval = numbval*base + (c-'0');
1743*18eb7a2dSCharles.Forsyth Bungetrune(finput);
1744*18eb7a2dSCharles.Forsyth return NUMBER;
1745*18eb7a2dSCharles.Forsyth }
1746*18eb7a2dSCharles.Forsyth if(islower(c) || isupper(c) || c=='_' || c=='.' || c=='$') {
1747*18eb7a2dSCharles.Forsyth i = 0;
1748*18eb7a2dSCharles.Forsyth while(islower(c) || isupper(c) || isdigit(c) ||
1749*18eb7a2dSCharles.Forsyth c == '-' || c=='_' || c=='.' || c=='$') {
1750*18eb7a2dSCharles.Forsyth if(reserve && isupper(c))
1751*18eb7a2dSCharles.Forsyth c += 'a'-'A';
1752*18eb7a2dSCharles.Forsyth rune = c;
1753*18eb7a2dSCharles.Forsyth c = runetochar(&tokname[i], &rune);
1754*18eb7a2dSCharles.Forsyth if(i < NAMESIZE)
1755*18eb7a2dSCharles.Forsyth i += c;
1756*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1757*18eb7a2dSCharles.Forsyth }
1758*18eb7a2dSCharles.Forsyth } else
1759*18eb7a2dSCharles.Forsyth return c;
1760*18eb7a2dSCharles.Forsyth Bungetrune(finput);
1761*18eb7a2dSCharles.Forsyth }
1762*18eb7a2dSCharles.Forsyth tokname[i] = 0;
1763*18eb7a2dSCharles.Forsyth
1764*18eb7a2dSCharles.Forsyth /* find a reserved word */
1765*18eb7a2dSCharles.Forsyth if(reserve) {
1766*18eb7a2dSCharles.Forsyth for(c=0; resrv[c].name; c++)
1767*18eb7a2dSCharles.Forsyth if(strcmp(tokname, resrv[c].name) == 0)
1768*18eb7a2dSCharles.Forsyth return resrv[c].value;
1769*18eb7a2dSCharles.Forsyth error("invalid escape, or illegal reserved word: %s", tokname);
1770*18eb7a2dSCharles.Forsyth }
1771*18eb7a2dSCharles.Forsyth
1772*18eb7a2dSCharles.Forsyth /* look ahead to distinguish IDENTIFIER from IDENTCOLON */
1773*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1774*18eb7a2dSCharles.Forsyth while(c == ' ' || c == '\t'|| c == '\n' || c == '\r' || c == '\f' || c == '/') {
1775*18eb7a2dSCharles.Forsyth if(c == '\n')
1776*18eb7a2dSCharles.Forsyth peekline++;
1777*18eb7a2dSCharles.Forsyth /* look for comments */
1778*18eb7a2dSCharles.Forsyth if(c == '/')
1779*18eb7a2dSCharles.Forsyth peekline += skipcom();
1780*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1781*18eb7a2dSCharles.Forsyth }
1782*18eb7a2dSCharles.Forsyth if(c == ':')
1783*18eb7a2dSCharles.Forsyth return IDENTCOLON;
1784*18eb7a2dSCharles.Forsyth Bungetrune(finput);
1785*18eb7a2dSCharles.Forsyth return IDENTIFIER;
1786*18eb7a2dSCharles.Forsyth }
1787*18eb7a2dSCharles.Forsyth
1788*18eb7a2dSCharles.Forsyth /*
1789*18eb7a2dSCharles.Forsyth * determine the type of a symbol
1790*18eb7a2dSCharles.Forsyth */
1791*18eb7a2dSCharles.Forsyth int
fdtype(int t)1792*18eb7a2dSCharles.Forsyth fdtype(int t)
1793*18eb7a2dSCharles.Forsyth {
1794*18eb7a2dSCharles.Forsyth int v;
1795*18eb7a2dSCharles.Forsyth
1796*18eb7a2dSCharles.Forsyth if(t >= NTBASE)
1797*18eb7a2dSCharles.Forsyth v = nontrst[t-NTBASE].value;
1798*18eb7a2dSCharles.Forsyth else
1799*18eb7a2dSCharles.Forsyth v = TYPE(toklev[t]);
1800*18eb7a2dSCharles.Forsyth if(v <= 0)
1801*18eb7a2dSCharles.Forsyth error("must specify type for %s", (t>=NTBASE)?
1802*18eb7a2dSCharles.Forsyth nontrst[t-NTBASE].name: tokset[t].name);
1803*18eb7a2dSCharles.Forsyth return v;
1804*18eb7a2dSCharles.Forsyth }
1805*18eb7a2dSCharles.Forsyth
1806*18eb7a2dSCharles.Forsyth int
chfind(int t,char * s)1807*18eb7a2dSCharles.Forsyth chfind(int t, char *s)
1808*18eb7a2dSCharles.Forsyth {
1809*18eb7a2dSCharles.Forsyth int i;
1810*18eb7a2dSCharles.Forsyth
1811*18eb7a2dSCharles.Forsyth if(s[0] == ' ')
1812*18eb7a2dSCharles.Forsyth t = 0;
1813*18eb7a2dSCharles.Forsyth TLOOP(i)
1814*18eb7a2dSCharles.Forsyth if(!strcmp(s, tokset[i].name))
1815*18eb7a2dSCharles.Forsyth return i;
1816*18eb7a2dSCharles.Forsyth NTLOOP(i)
1817*18eb7a2dSCharles.Forsyth if(!strcmp(s, nontrst[i].name))
1818*18eb7a2dSCharles.Forsyth return NTBASE+i;
1819*18eb7a2dSCharles.Forsyth
1820*18eb7a2dSCharles.Forsyth /* cannot find name */
1821*18eb7a2dSCharles.Forsyth if(t > 1)
1822*18eb7a2dSCharles.Forsyth error("%s should have been defined earlier", s);
1823*18eb7a2dSCharles.Forsyth return defin(t, s);
1824*18eb7a2dSCharles.Forsyth }
1825*18eb7a2dSCharles.Forsyth
1826*18eb7a2dSCharles.Forsyth /*
1827*18eb7a2dSCharles.Forsyth * copy the union declaration to the output, and the define file if present
1828*18eb7a2dSCharles.Forsyth */
1829*18eb7a2dSCharles.Forsyth void
cpyunion(void)1830*18eb7a2dSCharles.Forsyth cpyunion(void)
1831*18eb7a2dSCharles.Forsyth {
1832*18eb7a2dSCharles.Forsyth long c;
1833*18eb7a2dSCharles.Forsyth int level;
1834*18eb7a2dSCharles.Forsyth
1835*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
1836*18eb7a2dSCharles.Forsyth Bprint(ftable, "typedef union ");
1837*18eb7a2dSCharles.Forsyth if(fdefine != 0)
1838*18eb7a2dSCharles.Forsyth Bprint(fdefine, "\ntypedef union ");
1839*18eb7a2dSCharles.Forsyth
1840*18eb7a2dSCharles.Forsyth level = 0;
1841*18eb7a2dSCharles.Forsyth for(;;) {
1842*18eb7a2dSCharles.Forsyth if((c=Bgetrune(finput)) == Beof)
1843*18eb7a2dSCharles.Forsyth error("EOF encountered while processing %%union");
1844*18eb7a2dSCharles.Forsyth Bputrune(ftable, c);
1845*18eb7a2dSCharles.Forsyth if(fdefine != 0)
1846*18eb7a2dSCharles.Forsyth Bputrune(fdefine, c);
1847*18eb7a2dSCharles.Forsyth switch(c) {
1848*18eb7a2dSCharles.Forsyth case '\n':
1849*18eb7a2dSCharles.Forsyth lineno++;
1850*18eb7a2dSCharles.Forsyth break;
1851*18eb7a2dSCharles.Forsyth case '{':
1852*18eb7a2dSCharles.Forsyth level++;
1853*18eb7a2dSCharles.Forsyth break;
1854*18eb7a2dSCharles.Forsyth case '}':
1855*18eb7a2dSCharles.Forsyth level--;
1856*18eb7a2dSCharles.Forsyth
1857*18eb7a2dSCharles.Forsyth /* we are finished copying */
1858*18eb7a2dSCharles.Forsyth if(level == 0) {
1859*18eb7a2dSCharles.Forsyth Bprint(ftable, " YYSTYPE;\n");
1860*18eb7a2dSCharles.Forsyth if(fdefine != 0)
1861*18eb7a2dSCharles.Forsyth Bprint(fdefine, "\tYYSTYPE;\nextern\tYYSTYPE\tyylval;\n");
1862*18eb7a2dSCharles.Forsyth return;
1863*18eb7a2dSCharles.Forsyth }
1864*18eb7a2dSCharles.Forsyth }
1865*18eb7a2dSCharles.Forsyth }
1866*18eb7a2dSCharles.Forsyth }
1867*18eb7a2dSCharles.Forsyth
1868*18eb7a2dSCharles.Forsyth /*
1869*18eb7a2dSCharles.Forsyth * copies code between \{ and \}
1870*18eb7a2dSCharles.Forsyth */
1871*18eb7a2dSCharles.Forsyth void
cpycode(void)1872*18eb7a2dSCharles.Forsyth cpycode(void)
1873*18eb7a2dSCharles.Forsyth {
1874*18eb7a2dSCharles.Forsyth
1875*18eb7a2dSCharles.Forsyth long c;
1876*18eb7a2dSCharles.Forsyth
1877*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1878*18eb7a2dSCharles.Forsyth if(c == '\n') {
1879*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1880*18eb7a2dSCharles.Forsyth lineno++;
1881*18eb7a2dSCharles.Forsyth }
1882*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n#line\t%d\t\"%s\"\n", lineno, infile);
1883*18eb7a2dSCharles.Forsyth while(c != Beof) {
1884*18eb7a2dSCharles.Forsyth if(c == '\\') {
1885*18eb7a2dSCharles.Forsyth if((c=Bgetrune(finput)) == '}')
1886*18eb7a2dSCharles.Forsyth return;
1887*18eb7a2dSCharles.Forsyth Bputc(ftable, '\\');
1888*18eb7a2dSCharles.Forsyth }
1889*18eb7a2dSCharles.Forsyth if(c == '%') {
1890*18eb7a2dSCharles.Forsyth if((c=Bgetrune(finput)) == '}')
1891*18eb7a2dSCharles.Forsyth return;
1892*18eb7a2dSCharles.Forsyth Bputc(ftable, '%');
1893*18eb7a2dSCharles.Forsyth }
1894*18eb7a2dSCharles.Forsyth Bputrune(ftable, c);
1895*18eb7a2dSCharles.Forsyth if(c == '\n')
1896*18eb7a2dSCharles.Forsyth lineno++;
1897*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1898*18eb7a2dSCharles.Forsyth }
1899*18eb7a2dSCharles.Forsyth error("eof before %%}");
1900*18eb7a2dSCharles.Forsyth }
1901*18eb7a2dSCharles.Forsyth
1902*18eb7a2dSCharles.Forsyth /*
1903*18eb7a2dSCharles.Forsyth * skip over comments
1904*18eb7a2dSCharles.Forsyth * skipcom is called after reading a '/'
1905*18eb7a2dSCharles.Forsyth */
1906*18eb7a2dSCharles.Forsyth int
skipcom(void)1907*18eb7a2dSCharles.Forsyth skipcom(void)
1908*18eb7a2dSCharles.Forsyth {
1909*18eb7a2dSCharles.Forsyth long c;
1910*18eb7a2dSCharles.Forsyth int i;
1911*18eb7a2dSCharles.Forsyth
1912*18eb7a2dSCharles.Forsyth /* i is the number of lines skipped */
1913*18eb7a2dSCharles.Forsyth i = 0;
1914*18eb7a2dSCharles.Forsyth if(Bgetrune(finput) != '*')
1915*18eb7a2dSCharles.Forsyth error("illegal comment");
1916*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1917*18eb7a2dSCharles.Forsyth while(c != Beof) {
1918*18eb7a2dSCharles.Forsyth while(c == '*')
1919*18eb7a2dSCharles.Forsyth if((c=Bgetrune(finput)) == '/')
1920*18eb7a2dSCharles.Forsyth return i;
1921*18eb7a2dSCharles.Forsyth if(c == '\n')
1922*18eb7a2dSCharles.Forsyth i++;
1923*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1924*18eb7a2dSCharles.Forsyth }
1925*18eb7a2dSCharles.Forsyth error("EOF inside comment");
1926*18eb7a2dSCharles.Forsyth return 0;
1927*18eb7a2dSCharles.Forsyth }
1928*18eb7a2dSCharles.Forsyth
1929*18eb7a2dSCharles.Forsyth /*
1930*18eb7a2dSCharles.Forsyth * copy C action to the next ; or closing }
1931*18eb7a2dSCharles.Forsyth */
1932*18eb7a2dSCharles.Forsyth void
cpyact(int offset)1933*18eb7a2dSCharles.Forsyth cpyact(int offset)
1934*18eb7a2dSCharles.Forsyth {
1935*18eb7a2dSCharles.Forsyth long c;
1936*18eb7a2dSCharles.Forsyth int brac, match, j, s, fnd, tok;
1937*18eb7a2dSCharles.Forsyth
1938*18eb7a2dSCharles.Forsyth Bprint(faction, "\n#line\t%d\t\"%s\"\n", lineno, infile);
1939*18eb7a2dSCharles.Forsyth brac = 0;
1940*18eb7a2dSCharles.Forsyth
1941*18eb7a2dSCharles.Forsyth loop:
1942*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1943*18eb7a2dSCharles.Forsyth swt:
1944*18eb7a2dSCharles.Forsyth switch(c) {
1945*18eb7a2dSCharles.Forsyth case ';':
1946*18eb7a2dSCharles.Forsyth if(brac == 0) {
1947*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
1948*18eb7a2dSCharles.Forsyth return;
1949*18eb7a2dSCharles.Forsyth }
1950*18eb7a2dSCharles.Forsyth goto lcopy;
1951*18eb7a2dSCharles.Forsyth
1952*18eb7a2dSCharles.Forsyth case '{':
1953*18eb7a2dSCharles.Forsyth brac++;
1954*18eb7a2dSCharles.Forsyth goto lcopy;
1955*18eb7a2dSCharles.Forsyth
1956*18eb7a2dSCharles.Forsyth case '$':
1957*18eb7a2dSCharles.Forsyth s = 1;
1958*18eb7a2dSCharles.Forsyth tok = -1;
1959*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1960*18eb7a2dSCharles.Forsyth
1961*18eb7a2dSCharles.Forsyth /* type description */
1962*18eb7a2dSCharles.Forsyth if(c == '<') {
1963*18eb7a2dSCharles.Forsyth Bungetrune(finput);
1964*18eb7a2dSCharles.Forsyth if(gettok() != TYPENAME)
1965*18eb7a2dSCharles.Forsyth error("bad syntax on $<ident> clause");
1966*18eb7a2dSCharles.Forsyth tok = numbval;
1967*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1968*18eb7a2dSCharles.Forsyth }
1969*18eb7a2dSCharles.Forsyth if(c == '$') {
1970*18eb7a2dSCharles.Forsyth Bprint(faction, "yyval");
1971*18eb7a2dSCharles.Forsyth
1972*18eb7a2dSCharles.Forsyth /* put out the proper tag... */
1973*18eb7a2dSCharles.Forsyth if(ntypes) {
1974*18eb7a2dSCharles.Forsyth if(tok < 0)
1975*18eb7a2dSCharles.Forsyth tok = fdtype(*prdptr[nprod]);
1976*18eb7a2dSCharles.Forsyth Bprint(faction, ".%s", typeset[tok]);
1977*18eb7a2dSCharles.Forsyth }
1978*18eb7a2dSCharles.Forsyth goto loop;
1979*18eb7a2dSCharles.Forsyth }
1980*18eb7a2dSCharles.Forsyth if(c == '-') {
1981*18eb7a2dSCharles.Forsyth s = -s;
1982*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1983*18eb7a2dSCharles.Forsyth }
1984*18eb7a2dSCharles.Forsyth if(isdigit(c)) {
1985*18eb7a2dSCharles.Forsyth j = 0;
1986*18eb7a2dSCharles.Forsyth while(isdigit(c)) {
1987*18eb7a2dSCharles.Forsyth j = j*10 + (c-'0');
1988*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
1989*18eb7a2dSCharles.Forsyth }
1990*18eb7a2dSCharles.Forsyth Bungetrune(finput);
1991*18eb7a2dSCharles.Forsyth j = j*s - offset;
1992*18eb7a2dSCharles.Forsyth if(j > 0)
1993*18eb7a2dSCharles.Forsyth error("Illegal use of $%d", j+offset);
1994*18eb7a2dSCharles.Forsyth
1995*18eb7a2dSCharles.Forsyth dollar:
1996*18eb7a2dSCharles.Forsyth Bprint(faction, "yypt[-%d].yyv", -j);
1997*18eb7a2dSCharles.Forsyth
1998*18eb7a2dSCharles.Forsyth /* put out the proper tag */
1999*18eb7a2dSCharles.Forsyth if(ntypes) {
2000*18eb7a2dSCharles.Forsyth if(j+offset <= 0 && tok < 0)
2001*18eb7a2dSCharles.Forsyth error("must specify type of $%d", j+offset);
2002*18eb7a2dSCharles.Forsyth if(tok < 0)
2003*18eb7a2dSCharles.Forsyth tok = fdtype(prdptr[nprod][j+offset]);
2004*18eb7a2dSCharles.Forsyth Bprint(faction, ".%s", typeset[tok]);
2005*18eb7a2dSCharles.Forsyth }
2006*18eb7a2dSCharles.Forsyth goto loop;
2007*18eb7a2dSCharles.Forsyth }
2008*18eb7a2dSCharles.Forsyth if(isupper(c) || islower(c) || c == '_' || c == '.') {
2009*18eb7a2dSCharles.Forsyth int tok; /* tok used oustide for type info */
2010*18eb7a2dSCharles.Forsyth
2011*18eb7a2dSCharles.Forsyth /* look for $name */
2012*18eb7a2dSCharles.Forsyth Bungetrune(finput);
2013*18eb7a2dSCharles.Forsyth if(gettok() != IDENTIFIER)
2014*18eb7a2dSCharles.Forsyth error("$ must be followed by an identifier");
2015*18eb7a2dSCharles.Forsyth tok = chfind(2, tokname);
2016*18eb7a2dSCharles.Forsyth if((c = Bgetrune(finput)) != '#') {
2017*18eb7a2dSCharles.Forsyth Bungetrune(finput);
2018*18eb7a2dSCharles.Forsyth fnd = -1;
2019*18eb7a2dSCharles.Forsyth } else
2020*18eb7a2dSCharles.Forsyth if(gettok() != NUMBER) {
2021*18eb7a2dSCharles.Forsyth error("# must be followed by number");
2022*18eb7a2dSCharles.Forsyth fnd = -1;
2023*18eb7a2dSCharles.Forsyth } else
2024*18eb7a2dSCharles.Forsyth fnd = numbval;
2025*18eb7a2dSCharles.Forsyth for(j=1; j<=offset; ++j)
2026*18eb7a2dSCharles.Forsyth if(tok == prdptr[nprod][j]) {
2027*18eb7a2dSCharles.Forsyth if(--fnd <= 0) {
2028*18eb7a2dSCharles.Forsyth j -= offset;
2029*18eb7a2dSCharles.Forsyth goto dollar;
2030*18eb7a2dSCharles.Forsyth }
2031*18eb7a2dSCharles.Forsyth }
2032*18eb7a2dSCharles.Forsyth error("$name or $name#number not found");
2033*18eb7a2dSCharles.Forsyth }
2034*18eb7a2dSCharles.Forsyth Bputc(faction, '$');
2035*18eb7a2dSCharles.Forsyth if(s < 0 )
2036*18eb7a2dSCharles.Forsyth Bputc(faction, '-');
2037*18eb7a2dSCharles.Forsyth goto swt;
2038*18eb7a2dSCharles.Forsyth
2039*18eb7a2dSCharles.Forsyth case '}':
2040*18eb7a2dSCharles.Forsyth brac--;
2041*18eb7a2dSCharles.Forsyth if(brac)
2042*18eb7a2dSCharles.Forsyth goto lcopy;
2043*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2044*18eb7a2dSCharles.Forsyth return;
2045*18eb7a2dSCharles.Forsyth
2046*18eb7a2dSCharles.Forsyth case '/':
2047*18eb7a2dSCharles.Forsyth /* look for comments */
2048*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2049*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
2050*18eb7a2dSCharles.Forsyth if(c != '*')
2051*18eb7a2dSCharles.Forsyth goto swt;
2052*18eb7a2dSCharles.Forsyth
2053*18eb7a2dSCharles.Forsyth /* it really is a comment */
2054*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2055*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
2056*18eb7a2dSCharles.Forsyth while(c >= 0) {
2057*18eb7a2dSCharles.Forsyth while(c == '*') {
2058*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2059*18eb7a2dSCharles.Forsyth if((c=Bgetrune(finput)) == '/')
2060*18eb7a2dSCharles.Forsyth goto lcopy;
2061*18eb7a2dSCharles.Forsyth }
2062*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2063*18eb7a2dSCharles.Forsyth if(c == '\n')
2064*18eb7a2dSCharles.Forsyth lineno++;
2065*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
2066*18eb7a2dSCharles.Forsyth }
2067*18eb7a2dSCharles.Forsyth error("EOF inside comment");
2068*18eb7a2dSCharles.Forsyth
2069*18eb7a2dSCharles.Forsyth case '\'':
2070*18eb7a2dSCharles.Forsyth /* character constant */
2071*18eb7a2dSCharles.Forsyth match = '\'';
2072*18eb7a2dSCharles.Forsyth goto string;
2073*18eb7a2dSCharles.Forsyth
2074*18eb7a2dSCharles.Forsyth case '"':
2075*18eb7a2dSCharles.Forsyth /* character string */
2076*18eb7a2dSCharles.Forsyth match = '"';
2077*18eb7a2dSCharles.Forsyth
2078*18eb7a2dSCharles.Forsyth string:
2079*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2080*18eb7a2dSCharles.Forsyth while(c = Bgetrune(finput)) {
2081*18eb7a2dSCharles.Forsyth if(c == '\\') {
2082*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2083*18eb7a2dSCharles.Forsyth c = Bgetrune(finput);
2084*18eb7a2dSCharles.Forsyth if(c == '\n')
2085*18eb7a2dSCharles.Forsyth lineno++;
2086*18eb7a2dSCharles.Forsyth } else
2087*18eb7a2dSCharles.Forsyth if(c == match)
2088*18eb7a2dSCharles.Forsyth goto lcopy;
2089*18eb7a2dSCharles.Forsyth if(c == '\n')
2090*18eb7a2dSCharles.Forsyth error("newline in string or char. const.");
2091*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2092*18eb7a2dSCharles.Forsyth }
2093*18eb7a2dSCharles.Forsyth error("EOF in string or character constant");
2094*18eb7a2dSCharles.Forsyth
2095*18eb7a2dSCharles.Forsyth case Beof:
2096*18eb7a2dSCharles.Forsyth error("action does not terminate");
2097*18eb7a2dSCharles.Forsyth
2098*18eb7a2dSCharles.Forsyth case '\n':
2099*18eb7a2dSCharles.Forsyth lineno++;
2100*18eb7a2dSCharles.Forsyth goto lcopy;
2101*18eb7a2dSCharles.Forsyth }
2102*18eb7a2dSCharles.Forsyth
2103*18eb7a2dSCharles.Forsyth lcopy:
2104*18eb7a2dSCharles.Forsyth Bputrune(faction, c);
2105*18eb7a2dSCharles.Forsyth goto loop;
2106*18eb7a2dSCharles.Forsyth }
2107*18eb7a2dSCharles.Forsyth
2108*18eb7a2dSCharles.Forsyth void
openup(char * stem,int dflag,int vflag,int ytab,char * ytabc)2109*18eb7a2dSCharles.Forsyth openup(char *stem, int dflag, int vflag, int ytab, char *ytabc)
2110*18eb7a2dSCharles.Forsyth {
2111*18eb7a2dSCharles.Forsyth char buf[256];
2112*18eb7a2dSCharles.Forsyth
2113*18eb7a2dSCharles.Forsyth if(vflag) {
2114*18eb7a2dSCharles.Forsyth sprint(buf, "%s.%s", stem, FILEU);
2115*18eb7a2dSCharles.Forsyth foutput = Bopen(buf, OWRITE);
2116*18eb7a2dSCharles.Forsyth if(foutput == 0)
2117*18eb7a2dSCharles.Forsyth error("cannot open %s", buf);
2118*18eb7a2dSCharles.Forsyth }
2119*18eb7a2dSCharles.Forsyth if(yydebug) {
2120*18eb7a2dSCharles.Forsyth sprint(buf, "%s.%s", stem, FILEDEBUG);
2121*18eb7a2dSCharles.Forsyth if((fdebug = Bopen(buf, OWRITE)) == 0)
2122*18eb7a2dSCharles.Forsyth error("can't open %s", buf);
2123*18eb7a2dSCharles.Forsyth }
2124*18eb7a2dSCharles.Forsyth if(dflag) {
2125*18eb7a2dSCharles.Forsyth sprint(buf, "%s.%s", stem, FILED);
2126*18eb7a2dSCharles.Forsyth fdefine = Bopen(buf, OWRITE);
2127*18eb7a2dSCharles.Forsyth if(fdefine == 0)
2128*18eb7a2dSCharles.Forsyth error("can't create %s", buf);
2129*18eb7a2dSCharles.Forsyth }
2130*18eb7a2dSCharles.Forsyth if(ytab == 0)
2131*18eb7a2dSCharles.Forsyth sprint(buf, "%s.%s", stem, OFILE);
2132*18eb7a2dSCharles.Forsyth else
2133*18eb7a2dSCharles.Forsyth strcpy(buf, ytabc);
2134*18eb7a2dSCharles.Forsyth ftable = Bopen(buf, OWRITE);
2135*18eb7a2dSCharles.Forsyth if(ftable == 0)
2136*18eb7a2dSCharles.Forsyth error("cannot open table file %s", buf);
2137*18eb7a2dSCharles.Forsyth }
2138*18eb7a2dSCharles.Forsyth
2139*18eb7a2dSCharles.Forsyth /*
2140*18eb7a2dSCharles.Forsyth * print the output for the states
2141*18eb7a2dSCharles.Forsyth */
2142*18eb7a2dSCharles.Forsyth void
output(void)2143*18eb7a2dSCharles.Forsyth output(void)
2144*18eb7a2dSCharles.Forsyth {
2145*18eb7a2dSCharles.Forsyth int i, k, c;
2146*18eb7a2dSCharles.Forsyth Wset *u, *v;
2147*18eb7a2dSCharles.Forsyth
2148*18eb7a2dSCharles.Forsyth Bprint(ftable, "short yyexca[] =\n{");
2149*18eb7a2dSCharles.Forsyth if(fdebug)
2150*18eb7a2dSCharles.Forsyth Bprint(fdebug, "char* yystates[] =\n{\n");
2151*18eb7a2dSCharles.Forsyth
2152*18eb7a2dSCharles.Forsyth /* output the stuff for state i */
2153*18eb7a2dSCharles.Forsyth SLOOP(i) {
2154*18eb7a2dSCharles.Forsyth nolook = tystate[i]!=MUSTLOOKAHEAD;
2155*18eb7a2dSCharles.Forsyth closure(i);
2156*18eb7a2dSCharles.Forsyth
2157*18eb7a2dSCharles.Forsyth /* output actions */
2158*18eb7a2dSCharles.Forsyth nolook = 1;
2159*18eb7a2dSCharles.Forsyth aryfil(temp1, ntokens+nnonter+1, 0);
2160*18eb7a2dSCharles.Forsyth WSLOOP(wsets, u) {
2161*18eb7a2dSCharles.Forsyth c = *(u->pitem);
2162*18eb7a2dSCharles.Forsyth if(c > 1 && c < NTBASE && temp1[c] == 0) {
2163*18eb7a2dSCharles.Forsyth WSLOOP(u, v)
2164*18eb7a2dSCharles.Forsyth if(c == *(v->pitem))
2165*18eb7a2dSCharles.Forsyth putitem(v->pitem+1, (Lkset*)0);
2166*18eb7a2dSCharles.Forsyth temp1[c] = state(c);
2167*18eb7a2dSCharles.Forsyth } else
2168*18eb7a2dSCharles.Forsyth if(c > NTBASE && temp1[(c -= NTBASE) + ntokens] == 0)
2169*18eb7a2dSCharles.Forsyth temp1[c+ntokens] = amem[indgo[i]+c];
2170*18eb7a2dSCharles.Forsyth }
2171*18eb7a2dSCharles.Forsyth if(i == 1)
2172*18eb7a2dSCharles.Forsyth temp1[1] = ACCEPTCODE;
2173*18eb7a2dSCharles.Forsyth
2174*18eb7a2dSCharles.Forsyth /* now, we have the shifts; look at the reductions */
2175*18eb7a2dSCharles.Forsyth lastred = 0;
2176*18eb7a2dSCharles.Forsyth WSLOOP(wsets, u) {
2177*18eb7a2dSCharles.Forsyth c = *u->pitem;
2178*18eb7a2dSCharles.Forsyth
2179*18eb7a2dSCharles.Forsyth /* reduction */
2180*18eb7a2dSCharles.Forsyth if(c <= 0) {
2181*18eb7a2dSCharles.Forsyth lastred = -c;
2182*18eb7a2dSCharles.Forsyth TLOOP(k)
2183*18eb7a2dSCharles.Forsyth if(BIT(u->ws.lset, k)) {
2184*18eb7a2dSCharles.Forsyth if(temp1[k] == 0)
2185*18eb7a2dSCharles.Forsyth temp1[k] = c;
2186*18eb7a2dSCharles.Forsyth else
2187*18eb7a2dSCharles.Forsyth if(temp1[k] < 0) { /* reduce/reduce conflict */
2188*18eb7a2dSCharles.Forsyth if(foutput)
2189*18eb7a2dSCharles.Forsyth Bprint(foutput,
2190*18eb7a2dSCharles.Forsyth "\n%d: reduce/reduce conflict"
2191*18eb7a2dSCharles.Forsyth " (red'ns %d and %d ) on %s",
2192*18eb7a2dSCharles.Forsyth i, -temp1[k], lastred,
2193*18eb7a2dSCharles.Forsyth symnam(k));
2194*18eb7a2dSCharles.Forsyth if(-temp1[k] > lastred)
2195*18eb7a2dSCharles.Forsyth temp1[k] = -lastred;
2196*18eb7a2dSCharles.Forsyth zzrrconf++;
2197*18eb7a2dSCharles.Forsyth } else
2198*18eb7a2dSCharles.Forsyth /* potential shift/reduce conflict */
2199*18eb7a2dSCharles.Forsyth precftn( lastred, k, i );
2200*18eb7a2dSCharles.Forsyth }
2201*18eb7a2dSCharles.Forsyth }
2202*18eb7a2dSCharles.Forsyth }
2203*18eb7a2dSCharles.Forsyth wract(i);
2204*18eb7a2dSCharles.Forsyth }
2205*18eb7a2dSCharles.Forsyth
2206*18eb7a2dSCharles.Forsyth if(fdebug)
2207*18eb7a2dSCharles.Forsyth Bprint(fdebug, "};\n");
2208*18eb7a2dSCharles.Forsyth Bprint(ftable, "};\n");
2209*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define YYNPROD %d\n", nprod);
2210*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define YYPRIVATE %d\n", PRIVATE);
2211*18eb7a2dSCharles.Forsyth if(yydebug)
2212*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define yydebug %s\n", yydebug);
2213*18eb7a2dSCharles.Forsyth }
2214*18eb7a2dSCharles.Forsyth
2215*18eb7a2dSCharles.Forsyth /*
2216*18eb7a2dSCharles.Forsyth * pack state i from temp1 into amem
2217*18eb7a2dSCharles.Forsyth */
2218*18eb7a2dSCharles.Forsyth int
apack(int * p,int n)2219*18eb7a2dSCharles.Forsyth apack(int *p, int n)
2220*18eb7a2dSCharles.Forsyth {
2221*18eb7a2dSCharles.Forsyth int *pp, *qq, *rr, off, *q, *r;
2222*18eb7a2dSCharles.Forsyth
2223*18eb7a2dSCharles.Forsyth /* we don't need to worry about checking because
2224*18eb7a2dSCharles.Forsyth * we will only look at entries known to be there...
2225*18eb7a2dSCharles.Forsyth * eliminate leading and trailing 0's
2226*18eb7a2dSCharles.Forsyth */
2227*18eb7a2dSCharles.Forsyth
2228*18eb7a2dSCharles.Forsyth q = p+n;
2229*18eb7a2dSCharles.Forsyth for(pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
2230*18eb7a2dSCharles.Forsyth ;
2231*18eb7a2dSCharles.Forsyth /* no actions */
2232*18eb7a2dSCharles.Forsyth if(pp > q)
2233*18eb7a2dSCharles.Forsyth return 0;
2234*18eb7a2dSCharles.Forsyth p = pp;
2235*18eb7a2dSCharles.Forsyth
2236*18eb7a2dSCharles.Forsyth /* now, find a place for the elements from p to q, inclusive */
2237*18eb7a2dSCharles.Forsyth r = &amem[ACTSIZE-1];
2238*18eb7a2dSCharles.Forsyth for(rr = amem; rr <= r; rr++, off++) {
2239*18eb7a2dSCharles.Forsyth for(qq = rr, pp = p; pp <= q; pp++, qq++)
2240*18eb7a2dSCharles.Forsyth if(*pp != 0)
2241*18eb7a2dSCharles.Forsyth if(*pp != *qq && *qq != 0)
2242*18eb7a2dSCharles.Forsyth goto nextk;
2243*18eb7a2dSCharles.Forsyth
2244*18eb7a2dSCharles.Forsyth /* we have found an acceptable k */
2245*18eb7a2dSCharles.Forsyth if(pkdebug && foutput != 0)
2246*18eb7a2dSCharles.Forsyth Bprint(foutput, "off = %d, k = %d\n", off, (int)(rr-amem));
2247*18eb7a2dSCharles.Forsyth for(qq = rr, pp = p; pp <= q; pp++, qq++)
2248*18eb7a2dSCharles.Forsyth if(*pp) {
2249*18eb7a2dSCharles.Forsyth if(qq > r)
2250*18eb7a2dSCharles.Forsyth error("action table overflow");
2251*18eb7a2dSCharles.Forsyth if(qq > memp)
2252*18eb7a2dSCharles.Forsyth memp = qq;
2253*18eb7a2dSCharles.Forsyth *qq = *pp;
2254*18eb7a2dSCharles.Forsyth }
2255*18eb7a2dSCharles.Forsyth if(pkdebug && foutput != 0)
2256*18eb7a2dSCharles.Forsyth for(pp = amem; pp <= memp; pp += 10) {
2257*18eb7a2dSCharles.Forsyth Bprint(foutput, "\t");
2258*18eb7a2dSCharles.Forsyth for(qq = pp; qq <= pp+9; qq++)
2259*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d ", *qq);
2260*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n");
2261*18eb7a2dSCharles.Forsyth }
2262*18eb7a2dSCharles.Forsyth return(off);
2263*18eb7a2dSCharles.Forsyth nextk:;
2264*18eb7a2dSCharles.Forsyth }
2265*18eb7a2dSCharles.Forsyth error("no space in action table");
2266*18eb7a2dSCharles.Forsyth return 0;
2267*18eb7a2dSCharles.Forsyth }
2268*18eb7a2dSCharles.Forsyth
2269*18eb7a2dSCharles.Forsyth /*
2270*18eb7a2dSCharles.Forsyth * output the gotos for the nontermninals
2271*18eb7a2dSCharles.Forsyth */
2272*18eb7a2dSCharles.Forsyth void
go2out(void)2273*18eb7a2dSCharles.Forsyth go2out(void)
2274*18eb7a2dSCharles.Forsyth {
2275*18eb7a2dSCharles.Forsyth int i, j, k, best, count, cbest, times;
2276*18eb7a2dSCharles.Forsyth
2277*18eb7a2dSCharles.Forsyth /* mark begining of gotos */
2278*18eb7a2dSCharles.Forsyth Bprint(ftemp, "$\n");
2279*18eb7a2dSCharles.Forsyth for(i = 1; i <= nnonter; i++) {
2280*18eb7a2dSCharles.Forsyth go2gen(i);
2281*18eb7a2dSCharles.Forsyth
2282*18eb7a2dSCharles.Forsyth /* find the best one to make default */
2283*18eb7a2dSCharles.Forsyth best = -1;
2284*18eb7a2dSCharles.Forsyth times = 0;
2285*18eb7a2dSCharles.Forsyth
2286*18eb7a2dSCharles.Forsyth /* is j the most frequent */
2287*18eb7a2dSCharles.Forsyth for(j = 0; j <= nstate; j++) {
2288*18eb7a2dSCharles.Forsyth if(tystate[j] == 0)
2289*18eb7a2dSCharles.Forsyth continue;
2290*18eb7a2dSCharles.Forsyth if(tystate[j] == best)
2291*18eb7a2dSCharles.Forsyth continue;
2292*18eb7a2dSCharles.Forsyth
2293*18eb7a2dSCharles.Forsyth /* is tystate[j] the most frequent */
2294*18eb7a2dSCharles.Forsyth count = 0;
2295*18eb7a2dSCharles.Forsyth cbest = tystate[j];
2296*18eb7a2dSCharles.Forsyth for(k = j; k <= nstate; k++)
2297*18eb7a2dSCharles.Forsyth if(tystate[k] == cbest)
2298*18eb7a2dSCharles.Forsyth count++;
2299*18eb7a2dSCharles.Forsyth if(count > times) {
2300*18eb7a2dSCharles.Forsyth best = cbest;
2301*18eb7a2dSCharles.Forsyth times = count;
2302*18eb7a2dSCharles.Forsyth }
2303*18eb7a2dSCharles.Forsyth }
2304*18eb7a2dSCharles.Forsyth
2305*18eb7a2dSCharles.Forsyth /* best is now the default entry */
2306*18eb7a2dSCharles.Forsyth zzgobest += times-1;
2307*18eb7a2dSCharles.Forsyth for(j = 0; j <= nstate; j++)
2308*18eb7a2dSCharles.Forsyth if(tystate[j] != 0 && tystate[j] != best) {
2309*18eb7a2dSCharles.Forsyth Bprint(ftemp, "%d,%d,", j, tystate[j]);
2310*18eb7a2dSCharles.Forsyth zzgoent++;
2311*18eb7a2dSCharles.Forsyth }
2312*18eb7a2dSCharles.Forsyth
2313*18eb7a2dSCharles.Forsyth /* now, the default */
2314*18eb7a2dSCharles.Forsyth if(best == -1)
2315*18eb7a2dSCharles.Forsyth best = 0;
2316*18eb7a2dSCharles.Forsyth zzgoent++;
2317*18eb7a2dSCharles.Forsyth Bprint(ftemp, "%d\n", best);
2318*18eb7a2dSCharles.Forsyth }
2319*18eb7a2dSCharles.Forsyth }
2320*18eb7a2dSCharles.Forsyth
2321*18eb7a2dSCharles.Forsyth /*
2322*18eb7a2dSCharles.Forsyth * output the gotos for nonterminal c
2323*18eb7a2dSCharles.Forsyth */
2324*18eb7a2dSCharles.Forsyth void
go2gen(int c)2325*18eb7a2dSCharles.Forsyth go2gen(int c)
2326*18eb7a2dSCharles.Forsyth {
2327*18eb7a2dSCharles.Forsyth int i, work, cc;
2328*18eb7a2dSCharles.Forsyth Item *p, *q;
2329*18eb7a2dSCharles.Forsyth
2330*18eb7a2dSCharles.Forsyth
2331*18eb7a2dSCharles.Forsyth /* first, find nonterminals with gotos on c */
2332*18eb7a2dSCharles.Forsyth aryfil(temp1, nnonter+1, 0);
2333*18eb7a2dSCharles.Forsyth temp1[c] = 1;
2334*18eb7a2dSCharles.Forsyth work = 1;
2335*18eb7a2dSCharles.Forsyth while(work) {
2336*18eb7a2dSCharles.Forsyth work = 0;
2337*18eb7a2dSCharles.Forsyth PLOOP(0, i)
2338*18eb7a2dSCharles.Forsyth
2339*18eb7a2dSCharles.Forsyth /* cc is a nonterminal */
2340*18eb7a2dSCharles.Forsyth if((cc=prdptr[i][1]-NTBASE) >= 0)
2341*18eb7a2dSCharles.Forsyth /* cc has a goto on c */
2342*18eb7a2dSCharles.Forsyth if(temp1[cc] != 0) {
2343*18eb7a2dSCharles.Forsyth
2344*18eb7a2dSCharles.Forsyth /* thus, the left side of production i does too */
2345*18eb7a2dSCharles.Forsyth cc = *prdptr[i]-NTBASE;
2346*18eb7a2dSCharles.Forsyth if(temp1[cc] == 0) {
2347*18eb7a2dSCharles.Forsyth work = 1;
2348*18eb7a2dSCharles.Forsyth temp1[cc] = 1;
2349*18eb7a2dSCharles.Forsyth }
2350*18eb7a2dSCharles.Forsyth }
2351*18eb7a2dSCharles.Forsyth }
2352*18eb7a2dSCharles.Forsyth
2353*18eb7a2dSCharles.Forsyth /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
2354*18eb7a2dSCharles.Forsyth if(g2debug && foutput != 0) {
2355*18eb7a2dSCharles.Forsyth Bprint(foutput, "%s: gotos on ", nontrst[c].name);
2356*18eb7a2dSCharles.Forsyth NTLOOP(i)
2357*18eb7a2dSCharles.Forsyth if(temp1[i])
2358*18eb7a2dSCharles.Forsyth Bprint(foutput, "%s ", nontrst[i].name);
2359*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n");
2360*18eb7a2dSCharles.Forsyth }
2361*18eb7a2dSCharles.Forsyth
2362*18eb7a2dSCharles.Forsyth /* now, go through and put gotos into tystate */
2363*18eb7a2dSCharles.Forsyth aryfil(tystate, nstate, 0);
2364*18eb7a2dSCharles.Forsyth SLOOP(i)
2365*18eb7a2dSCharles.Forsyth ITMLOOP(i, p, q)
2366*18eb7a2dSCharles.Forsyth if((cc = *p->pitem) >= NTBASE)
2367*18eb7a2dSCharles.Forsyth /* goto on c is possible */
2368*18eb7a2dSCharles.Forsyth if(temp1[cc-NTBASE]) {
2369*18eb7a2dSCharles.Forsyth tystate[i] = amem[indgo[i]+c];
2370*18eb7a2dSCharles.Forsyth break;
2371*18eb7a2dSCharles.Forsyth }
2372*18eb7a2dSCharles.Forsyth }
2373*18eb7a2dSCharles.Forsyth
2374*18eb7a2dSCharles.Forsyth /*
2375*18eb7a2dSCharles.Forsyth * decide a shift/reduce conflict by precedence.
2376*18eb7a2dSCharles.Forsyth * r is a rule number, t a token number
2377*18eb7a2dSCharles.Forsyth * the conflict is in state s
2378*18eb7a2dSCharles.Forsyth * temp1[t] is changed to reflect the action
2379*18eb7a2dSCharles.Forsyth */
2380*18eb7a2dSCharles.Forsyth void
precftn(int r,int t,int s)2381*18eb7a2dSCharles.Forsyth precftn(int r, int t, int s)
2382*18eb7a2dSCharles.Forsyth {
2383*18eb7a2dSCharles.Forsyth int lp, lt, action;
2384*18eb7a2dSCharles.Forsyth
2385*18eb7a2dSCharles.Forsyth lp = levprd[r];
2386*18eb7a2dSCharles.Forsyth lt = toklev[t];
2387*18eb7a2dSCharles.Forsyth if(PLEVEL(lt) == 0 || PLEVEL(lp) == 0) {
2388*18eb7a2dSCharles.Forsyth
2389*18eb7a2dSCharles.Forsyth /* conflict */
2390*18eb7a2dSCharles.Forsyth if(foutput != 0)
2391*18eb7a2dSCharles.Forsyth Bprint(foutput,
2392*18eb7a2dSCharles.Forsyth "\n%d: shift/reduce conflict (shift %d(%d), red'n %d(%d)) on %s",
2393*18eb7a2dSCharles.Forsyth s, temp1[t], PLEVEL(lt), r, PLEVEL(lp), symnam(t));
2394*18eb7a2dSCharles.Forsyth zzsrconf++;
2395*18eb7a2dSCharles.Forsyth return;
2396*18eb7a2dSCharles.Forsyth }
2397*18eb7a2dSCharles.Forsyth if(PLEVEL(lt) == PLEVEL(lp))
2398*18eb7a2dSCharles.Forsyth action = ASSOC(lt);
2399*18eb7a2dSCharles.Forsyth else
2400*18eb7a2dSCharles.Forsyth if(PLEVEL(lt) > PLEVEL(lp))
2401*18eb7a2dSCharles.Forsyth action = RASC; /* shift */
2402*18eb7a2dSCharles.Forsyth else
2403*18eb7a2dSCharles.Forsyth action = LASC; /* reduce */
2404*18eb7a2dSCharles.Forsyth switch(action) {
2405*18eb7a2dSCharles.Forsyth case BASC: /* error action */
2406*18eb7a2dSCharles.Forsyth temp1[t] = ERRCODE;
2407*18eb7a2dSCharles.Forsyth break;
2408*18eb7a2dSCharles.Forsyth case LASC: /* reduce */
2409*18eb7a2dSCharles.Forsyth temp1[t] = -r;
2410*18eb7a2dSCharles.Forsyth break;
2411*18eb7a2dSCharles.Forsyth }
2412*18eb7a2dSCharles.Forsyth }
2413*18eb7a2dSCharles.Forsyth
2414*18eb7a2dSCharles.Forsyth /*
2415*18eb7a2dSCharles.Forsyth * output state i
2416*18eb7a2dSCharles.Forsyth * temp1 has the actions, lastred the default
2417*18eb7a2dSCharles.Forsyth */
2418*18eb7a2dSCharles.Forsyth void
wract(int i)2419*18eb7a2dSCharles.Forsyth wract(int i)
2420*18eb7a2dSCharles.Forsyth {
2421*18eb7a2dSCharles.Forsyth int p, p0, p1, ntimes, tred, count, j, flag;
2422*18eb7a2dSCharles.Forsyth
2423*18eb7a2dSCharles.Forsyth /* find the best choice for lastred */
2424*18eb7a2dSCharles.Forsyth lastred = 0;
2425*18eb7a2dSCharles.Forsyth ntimes = 0;
2426*18eb7a2dSCharles.Forsyth TLOOP(j) {
2427*18eb7a2dSCharles.Forsyth if(temp1[j] >= 0)
2428*18eb7a2dSCharles.Forsyth continue;
2429*18eb7a2dSCharles.Forsyth if(temp1[j]+lastred == 0)
2430*18eb7a2dSCharles.Forsyth continue;
2431*18eb7a2dSCharles.Forsyth /* count the number of appearances of temp1[j] */
2432*18eb7a2dSCharles.Forsyth count = 0;
2433*18eb7a2dSCharles.Forsyth tred = -temp1[j];
2434*18eb7a2dSCharles.Forsyth levprd[tred] |= REDFLAG;
2435*18eb7a2dSCharles.Forsyth TLOOP(p)
2436*18eb7a2dSCharles.Forsyth if(temp1[p]+tred == 0)
2437*18eb7a2dSCharles.Forsyth count++;
2438*18eb7a2dSCharles.Forsyth if(count > ntimes) {
2439*18eb7a2dSCharles.Forsyth lastred = tred;
2440*18eb7a2dSCharles.Forsyth ntimes = count;
2441*18eb7a2dSCharles.Forsyth }
2442*18eb7a2dSCharles.Forsyth }
2443*18eb7a2dSCharles.Forsyth
2444*18eb7a2dSCharles.Forsyth /*
2445*18eb7a2dSCharles.Forsyth * for error recovery, arrange that, if there is a shift on the
2446*18eb7a2dSCharles.Forsyth * error recovery token, `error', that the default be the error action
2447*18eb7a2dSCharles.Forsyth */
2448*18eb7a2dSCharles.Forsyth if(temp1[2] > 0)
2449*18eb7a2dSCharles.Forsyth lastred = 0;
2450*18eb7a2dSCharles.Forsyth
2451*18eb7a2dSCharles.Forsyth /* clear out entries in temp1 which equal lastred */
2452*18eb7a2dSCharles.Forsyth TLOOP(p)
2453*18eb7a2dSCharles.Forsyth if(temp1[p]+lastred == 0)
2454*18eb7a2dSCharles.Forsyth temp1[p] = 0;
2455*18eb7a2dSCharles.Forsyth
2456*18eb7a2dSCharles.Forsyth wrstate(i);
2457*18eb7a2dSCharles.Forsyth defact[i] = lastred;
2458*18eb7a2dSCharles.Forsyth flag = 0;
2459*18eb7a2dSCharles.Forsyth TLOOP(p0)
2460*18eb7a2dSCharles.Forsyth if((p1=temp1[p0]) != 0) {
2461*18eb7a2dSCharles.Forsyth if(p1 < 0) {
2462*18eb7a2dSCharles.Forsyth p1 = -p1;
2463*18eb7a2dSCharles.Forsyth goto exc;
2464*18eb7a2dSCharles.Forsyth }
2465*18eb7a2dSCharles.Forsyth if(p1 == ACCEPTCODE) {
2466*18eb7a2dSCharles.Forsyth p1 = -1;
2467*18eb7a2dSCharles.Forsyth goto exc;
2468*18eb7a2dSCharles.Forsyth }
2469*18eb7a2dSCharles.Forsyth if(p1 == ERRCODE) {
2470*18eb7a2dSCharles.Forsyth p1 = 0;
2471*18eb7a2dSCharles.Forsyth exc:
2472*18eb7a2dSCharles.Forsyth if(flag++ == 0)
2473*18eb7a2dSCharles.Forsyth Bprint(ftable, "-1, %d,\n", i);
2474*18eb7a2dSCharles.Forsyth Bprint(ftable, "\t%d, %d,\n", p0, p1);
2475*18eb7a2dSCharles.Forsyth zzexcp++;
2476*18eb7a2dSCharles.Forsyth continue;
2477*18eb7a2dSCharles.Forsyth }
2478*18eb7a2dSCharles.Forsyth Bprint(ftemp, "%d,%d,", p0, p1);
2479*18eb7a2dSCharles.Forsyth zzacent++;
2480*18eb7a2dSCharles.Forsyth }
2481*18eb7a2dSCharles.Forsyth if(flag) {
2482*18eb7a2dSCharles.Forsyth defact[i] = -2;
2483*18eb7a2dSCharles.Forsyth Bprint(ftable, "\t-2, %d,\n", lastred);
2484*18eb7a2dSCharles.Forsyth }
2485*18eb7a2dSCharles.Forsyth Bprint(ftemp, "\n");
2486*18eb7a2dSCharles.Forsyth }
2487*18eb7a2dSCharles.Forsyth
2488*18eb7a2dSCharles.Forsyth /*
2489*18eb7a2dSCharles.Forsyth * writes state i
2490*18eb7a2dSCharles.Forsyth */
2491*18eb7a2dSCharles.Forsyth void
wrstate(int i)2492*18eb7a2dSCharles.Forsyth wrstate(int i)
2493*18eb7a2dSCharles.Forsyth {
2494*18eb7a2dSCharles.Forsyth int j0, j1;
2495*18eb7a2dSCharles.Forsyth Item *pp, *qq;
2496*18eb7a2dSCharles.Forsyth Wset *u;
2497*18eb7a2dSCharles.Forsyth
2498*18eb7a2dSCharles.Forsyth if(fdebug) {
2499*18eb7a2dSCharles.Forsyth if(lastred) {
2500*18eb7a2dSCharles.Forsyth Bprint(fdebug, " 0, /*%d*/\n", i);
2501*18eb7a2dSCharles.Forsyth } else {
2502*18eb7a2dSCharles.Forsyth Bprint(fdebug, " \"");
2503*18eb7a2dSCharles.Forsyth ITMLOOP(i, pp, qq)
2504*18eb7a2dSCharles.Forsyth Bprint(fdebug, "%s\\n", writem(pp->pitem));
2505*18eb7a2dSCharles.Forsyth if(tystate[i] == MUSTLOOKAHEAD)
2506*18eb7a2dSCharles.Forsyth WSLOOP(wsets + (pstate[i+1] - pstate[i]), u)
2507*18eb7a2dSCharles.Forsyth if(*u->pitem < 0)
2508*18eb7a2dSCharles.Forsyth Bprint(fdebug, "%s\\n", writem(u->pitem));
2509*18eb7a2dSCharles.Forsyth Bprint(fdebug, "\", /*%d*/\n", i);
2510*18eb7a2dSCharles.Forsyth }
2511*18eb7a2dSCharles.Forsyth }
2512*18eb7a2dSCharles.Forsyth if(foutput == 0)
2513*18eb7a2dSCharles.Forsyth return;
2514*18eb7a2dSCharles.Forsyth Bprint(foutput, "\nstate %d\n", i);
2515*18eb7a2dSCharles.Forsyth ITMLOOP(i, pp, qq)
2516*18eb7a2dSCharles.Forsyth Bprint(foutput, "\t%s\n", writem(pp->pitem));
2517*18eb7a2dSCharles.Forsyth if(tystate[i] == MUSTLOOKAHEAD)
2518*18eb7a2dSCharles.Forsyth /* print out empty productions in closure */
2519*18eb7a2dSCharles.Forsyth WSLOOP(wsets+(pstate[i+1]-pstate[i]), u)
2520*18eb7a2dSCharles.Forsyth if(*u->pitem < 0)
2521*18eb7a2dSCharles.Forsyth Bprint(foutput, "\t%s\n", writem(u->pitem));
2522*18eb7a2dSCharles.Forsyth
2523*18eb7a2dSCharles.Forsyth /* check for state equal to another */
2524*18eb7a2dSCharles.Forsyth TLOOP(j0)
2525*18eb7a2dSCharles.Forsyth if((j1=temp1[j0]) != 0) {
2526*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n\t%s ", symnam(j0));
2527*18eb7a2dSCharles.Forsyth /* shift, error, or accept */
2528*18eb7a2dSCharles.Forsyth if(j1 > 0) {
2529*18eb7a2dSCharles.Forsyth if(j1 == ACCEPTCODE)
2530*18eb7a2dSCharles.Forsyth Bprint(foutput, "accept");
2531*18eb7a2dSCharles.Forsyth else
2532*18eb7a2dSCharles.Forsyth if(j1 == ERRCODE)
2533*18eb7a2dSCharles.Forsyth Bprint(foutput, "error");
2534*18eb7a2dSCharles.Forsyth else
2535*18eb7a2dSCharles.Forsyth Bprint(foutput, "shift %d", j1);
2536*18eb7a2dSCharles.Forsyth } else
2537*18eb7a2dSCharles.Forsyth Bprint(foutput, "reduce %d (src line %d)", -j1, rlines[-j1]);
2538*18eb7a2dSCharles.Forsyth }
2539*18eb7a2dSCharles.Forsyth
2540*18eb7a2dSCharles.Forsyth /* output the final production */
2541*18eb7a2dSCharles.Forsyth if(lastred)
2542*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n\t. reduce %d (src line %d)\n\n",
2543*18eb7a2dSCharles.Forsyth lastred, rlines[lastred]);
2544*18eb7a2dSCharles.Forsyth else
2545*18eb7a2dSCharles.Forsyth Bprint(foutput, "\n\t. error\n\n");
2546*18eb7a2dSCharles.Forsyth
2547*18eb7a2dSCharles.Forsyth /* now, output nonterminal actions */
2548*18eb7a2dSCharles.Forsyth j1 = ntokens;
2549*18eb7a2dSCharles.Forsyth for(j0 = 1; j0 <= nnonter; j0++) {
2550*18eb7a2dSCharles.Forsyth j1++;
2551*18eb7a2dSCharles.Forsyth if(temp1[j1])
2552*18eb7a2dSCharles.Forsyth Bprint(foutput, "\t%s goto %d\n", symnam(j0+NTBASE), temp1[j1]);
2553*18eb7a2dSCharles.Forsyth }
2554*18eb7a2dSCharles.Forsyth }
2555*18eb7a2dSCharles.Forsyth
2556*18eb7a2dSCharles.Forsyth void
warray(char * s,int * v,int n)2557*18eb7a2dSCharles.Forsyth warray(char *s, int *v, int n)
2558*18eb7a2dSCharles.Forsyth {
2559*18eb7a2dSCharles.Forsyth int i;
2560*18eb7a2dSCharles.Forsyth
2561*18eb7a2dSCharles.Forsyth Bprint(ftable, "short %s[] =\n{", s);
2562*18eb7a2dSCharles.Forsyth for(i=0;;) {
2563*18eb7a2dSCharles.Forsyth if(i%10 == 0)
2564*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n");
2565*18eb7a2dSCharles.Forsyth Bprint(ftable, "%4d", v[i]);
2566*18eb7a2dSCharles.Forsyth i++;
2567*18eb7a2dSCharles.Forsyth if(i >= n) {
2568*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n};\n");
2569*18eb7a2dSCharles.Forsyth break;
2570*18eb7a2dSCharles.Forsyth }
2571*18eb7a2dSCharles.Forsyth Bprint(ftable, ",");
2572*18eb7a2dSCharles.Forsyth }
2573*18eb7a2dSCharles.Forsyth }
2574*18eb7a2dSCharles.Forsyth
2575*18eb7a2dSCharles.Forsyth /*
2576*18eb7a2dSCharles.Forsyth * in order to free up the mem and amem arrays for the optimizer,
2577*18eb7a2dSCharles.Forsyth * and still be able to output yyr1, etc., after the sizes of
2578*18eb7a2dSCharles.Forsyth * the action array is known, we hide the nonterminals
2579*18eb7a2dSCharles.Forsyth * derived by productions in levprd.
2580*18eb7a2dSCharles.Forsyth */
2581*18eb7a2dSCharles.Forsyth
2582*18eb7a2dSCharles.Forsyth void
hideprod(void)2583*18eb7a2dSCharles.Forsyth hideprod(void)
2584*18eb7a2dSCharles.Forsyth {
2585*18eb7a2dSCharles.Forsyth int i, j;
2586*18eb7a2dSCharles.Forsyth
2587*18eb7a2dSCharles.Forsyth j = 0;
2588*18eb7a2dSCharles.Forsyth levprd[0] = 0;
2589*18eb7a2dSCharles.Forsyth PLOOP(1, i) {
2590*18eb7a2dSCharles.Forsyth if(!(levprd[i] & REDFLAG)) {
2591*18eb7a2dSCharles.Forsyth j++;
2592*18eb7a2dSCharles.Forsyth if(foutput != 0)
2593*18eb7a2dSCharles.Forsyth Bprint(foutput, "Rule not reduced: %s\n", writem(prdptr[i]));
2594*18eb7a2dSCharles.Forsyth }
2595*18eb7a2dSCharles.Forsyth levprd[i] = *prdptr[i] - NTBASE;
2596*18eb7a2dSCharles.Forsyth }
2597*18eb7a2dSCharles.Forsyth if(j)
2598*18eb7a2dSCharles.Forsyth print("%d rules never reduced\n", j);
2599*18eb7a2dSCharles.Forsyth }
2600*18eb7a2dSCharles.Forsyth
2601*18eb7a2dSCharles.Forsyth void
callopt(void)2602*18eb7a2dSCharles.Forsyth callopt(void)
2603*18eb7a2dSCharles.Forsyth {
2604*18eb7a2dSCharles.Forsyth int i, *p, j, k, *q;
2605*18eb7a2dSCharles.Forsyth
2606*18eb7a2dSCharles.Forsyth /* read the arrays from tempfile and set parameters */
2607*18eb7a2dSCharles.Forsyth finput = Bopen(tempname, OREAD);
2608*18eb7a2dSCharles.Forsyth if(finput == 0)
2609*18eb7a2dSCharles.Forsyth error("optimizer cannot open tempfile");
2610*18eb7a2dSCharles.Forsyth pgo[0] = 0;
2611*18eb7a2dSCharles.Forsyth temp1[0] = 0;
2612*18eb7a2dSCharles.Forsyth nstate = 0;
2613*18eb7a2dSCharles.Forsyth nnonter = 0;
2614*18eb7a2dSCharles.Forsyth for(;;) {
2615*18eb7a2dSCharles.Forsyth switch(gtnm()) {
2616*18eb7a2dSCharles.Forsyth case '\n':
2617*18eb7a2dSCharles.Forsyth nstate++;
2618*18eb7a2dSCharles.Forsyth pmem--;
2619*18eb7a2dSCharles.Forsyth temp1[nstate] = pmem - mem0;
2620*18eb7a2dSCharles.Forsyth case ',':
2621*18eb7a2dSCharles.Forsyth continue;
2622*18eb7a2dSCharles.Forsyth case '$':
2623*18eb7a2dSCharles.Forsyth break;
2624*18eb7a2dSCharles.Forsyth default:
2625*18eb7a2dSCharles.Forsyth error("bad tempfile");
2626*18eb7a2dSCharles.Forsyth }
2627*18eb7a2dSCharles.Forsyth break;
2628*18eb7a2dSCharles.Forsyth }
2629*18eb7a2dSCharles.Forsyth
2630*18eb7a2dSCharles.Forsyth pmem--;
2631*18eb7a2dSCharles.Forsyth temp1[nstate] = yypgo[0] = pmem - mem0;
2632*18eb7a2dSCharles.Forsyth for(;;) {
2633*18eb7a2dSCharles.Forsyth switch(gtnm()) {
2634*18eb7a2dSCharles.Forsyth case '\n':
2635*18eb7a2dSCharles.Forsyth nnonter++;
2636*18eb7a2dSCharles.Forsyth yypgo[nnonter] = pmem-mem0;
2637*18eb7a2dSCharles.Forsyth case ',':
2638*18eb7a2dSCharles.Forsyth continue;
2639*18eb7a2dSCharles.Forsyth case -1:
2640*18eb7a2dSCharles.Forsyth break;
2641*18eb7a2dSCharles.Forsyth default:
2642*18eb7a2dSCharles.Forsyth error("bad tempfile");
2643*18eb7a2dSCharles.Forsyth }
2644*18eb7a2dSCharles.Forsyth break;
2645*18eb7a2dSCharles.Forsyth }
2646*18eb7a2dSCharles.Forsyth pmem--;
2647*18eb7a2dSCharles.Forsyth yypgo[nnonter--] = pmem - mem0;
2648*18eb7a2dSCharles.Forsyth for(i = 0; i < nstate; i++) {
2649*18eb7a2dSCharles.Forsyth k = 32000;
2650*18eb7a2dSCharles.Forsyth j = 0;
2651*18eb7a2dSCharles.Forsyth q = mem0 + temp1[i+1];
2652*18eb7a2dSCharles.Forsyth for(p = mem0 + temp1[i]; p < q ; p += 2) {
2653*18eb7a2dSCharles.Forsyth if(*p > j)
2654*18eb7a2dSCharles.Forsyth j = *p;
2655*18eb7a2dSCharles.Forsyth if(*p < k)
2656*18eb7a2dSCharles.Forsyth k = *p;
2657*18eb7a2dSCharles.Forsyth }
2658*18eb7a2dSCharles.Forsyth /* nontrivial situation */
2659*18eb7a2dSCharles.Forsyth if(k <= j) {
2660*18eb7a2dSCharles.Forsyth /* j is now the range */
2661*18eb7a2dSCharles.Forsyth /* j -= k; /* call scj */
2662*18eb7a2dSCharles.Forsyth if(k > maxoff)
2663*18eb7a2dSCharles.Forsyth maxoff = k;
2664*18eb7a2dSCharles.Forsyth }
2665*18eb7a2dSCharles.Forsyth tystate[i] = (temp1[i+1]-temp1[i]) + 2*j;
2666*18eb7a2dSCharles.Forsyth if(j > maxspr)
2667*18eb7a2dSCharles.Forsyth maxspr = j;
2668*18eb7a2dSCharles.Forsyth }
2669*18eb7a2dSCharles.Forsyth
2670*18eb7a2dSCharles.Forsyth /* initialize ggreed table */
2671*18eb7a2dSCharles.Forsyth for(i = 1; i <= nnonter; i++) {
2672*18eb7a2dSCharles.Forsyth ggreed[i] = 1;
2673*18eb7a2dSCharles.Forsyth j = 0;
2674*18eb7a2dSCharles.Forsyth
2675*18eb7a2dSCharles.Forsyth /* minimum entry index is always 0 */
2676*18eb7a2dSCharles.Forsyth q = mem0 + yypgo[i+1] - 1;
2677*18eb7a2dSCharles.Forsyth for(p = mem0+yypgo[i]; p < q ; p += 2) {
2678*18eb7a2dSCharles.Forsyth ggreed[i] += 2;
2679*18eb7a2dSCharles.Forsyth if(*p > j)
2680*18eb7a2dSCharles.Forsyth j = *p;
2681*18eb7a2dSCharles.Forsyth }
2682*18eb7a2dSCharles.Forsyth ggreed[i] = ggreed[i] + 2*j;
2683*18eb7a2dSCharles.Forsyth if(j > maxoff)
2684*18eb7a2dSCharles.Forsyth maxoff = j;
2685*18eb7a2dSCharles.Forsyth }
2686*18eb7a2dSCharles.Forsyth
2687*18eb7a2dSCharles.Forsyth /* now, prepare to put the shift actions into the amem array */
2688*18eb7a2dSCharles.Forsyth for(i = 0; i < ACTSIZE; i++)
2689*18eb7a2dSCharles.Forsyth amem[i] = 0;
2690*18eb7a2dSCharles.Forsyth maxa = amem;
2691*18eb7a2dSCharles.Forsyth for(i = 0; i < nstate; i++) {
2692*18eb7a2dSCharles.Forsyth if(tystate[i] == 0 && adb > 1)
2693*18eb7a2dSCharles.Forsyth Bprint(ftable, "State %d: null\n", i);
2694*18eb7a2dSCharles.Forsyth indgo[i] = YYFLAG1;
2695*18eb7a2dSCharles.Forsyth }
2696*18eb7a2dSCharles.Forsyth while((i = nxti()) != NOMORE)
2697*18eb7a2dSCharles.Forsyth if(i >= 0)
2698*18eb7a2dSCharles.Forsyth stin(i);
2699*18eb7a2dSCharles.Forsyth else
2700*18eb7a2dSCharles.Forsyth gin(-i);
2701*18eb7a2dSCharles.Forsyth
2702*18eb7a2dSCharles.Forsyth /* print amem array */
2703*18eb7a2dSCharles.Forsyth if(adb > 2 )
2704*18eb7a2dSCharles.Forsyth for(p = amem; p <= maxa; p += 10) {
2705*18eb7a2dSCharles.Forsyth Bprint(ftable, "%4d ", (int)(p-amem));
2706*18eb7a2dSCharles.Forsyth for(i = 0; i < 10; ++i)
2707*18eb7a2dSCharles.Forsyth Bprint(ftable, "%4d ", p[i]);
2708*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n");
2709*18eb7a2dSCharles.Forsyth }
2710*18eb7a2dSCharles.Forsyth
2711*18eb7a2dSCharles.Forsyth /* write out the output appropriate to the language */
2712*18eb7a2dSCharles.Forsyth aoutput();
2713*18eb7a2dSCharles.Forsyth osummary();
2714*18eb7a2dSCharles.Forsyth Bterm(finput);
2715*18eb7a2dSCharles.Forsyth ZAPFILE(tempname);
2716*18eb7a2dSCharles.Forsyth }
2717*18eb7a2dSCharles.Forsyth
2718*18eb7a2dSCharles.Forsyth void
gin(int i)2719*18eb7a2dSCharles.Forsyth gin(int i)
2720*18eb7a2dSCharles.Forsyth {
2721*18eb7a2dSCharles.Forsyth int *p, *r, *s, *q1, *q2;
2722*18eb7a2dSCharles.Forsyth
2723*18eb7a2dSCharles.Forsyth /* enter gotos on nonterminal i into array amem */
2724*18eb7a2dSCharles.Forsyth ggreed[i] = 0;
2725*18eb7a2dSCharles.Forsyth
2726*18eb7a2dSCharles.Forsyth q2 = mem0+ yypgo[i+1] - 1;
2727*18eb7a2dSCharles.Forsyth q1 = mem0 + yypgo[i];
2728*18eb7a2dSCharles.Forsyth
2729*18eb7a2dSCharles.Forsyth /* now, find amem place for it */
2730*18eb7a2dSCharles.Forsyth for(p = amem; p < &amem[ACTSIZE]; p++) {
2731*18eb7a2dSCharles.Forsyth if(*p)
2732*18eb7a2dSCharles.Forsyth continue;
2733*18eb7a2dSCharles.Forsyth for(r = q1; r < q2; r += 2) {
2734*18eb7a2dSCharles.Forsyth s = p + *r + 1;
2735*18eb7a2dSCharles.Forsyth if(*s)
2736*18eb7a2dSCharles.Forsyth goto nextgp;
2737*18eb7a2dSCharles.Forsyth if(s > maxa)
2738*18eb7a2dSCharles.Forsyth if((maxa = s) > &amem[ACTSIZE])
2739*18eb7a2dSCharles.Forsyth error("a array overflow");
2740*18eb7a2dSCharles.Forsyth }
2741*18eb7a2dSCharles.Forsyth /* we have found amem spot */
2742*18eb7a2dSCharles.Forsyth *p = *q2;
2743*18eb7a2dSCharles.Forsyth if(p > maxa)
2744*18eb7a2dSCharles.Forsyth if((maxa = p) > &amem[ACTSIZE])
2745*18eb7a2dSCharles.Forsyth error("a array overflow");
2746*18eb7a2dSCharles.Forsyth for(r = q1; r < q2; r += 2) {
2747*18eb7a2dSCharles.Forsyth s = p + *r + 1;
2748*18eb7a2dSCharles.Forsyth *s = r[1];
2749*18eb7a2dSCharles.Forsyth }
2750*18eb7a2dSCharles.Forsyth pgo[i] = p-amem;
2751*18eb7a2dSCharles.Forsyth if(adb > 1)
2752*18eb7a2dSCharles.Forsyth Bprint(ftable, "Nonterminal %d, entry at %d\n", i, pgo[i]);
2753*18eb7a2dSCharles.Forsyth return;
2754*18eb7a2dSCharles.Forsyth
2755*18eb7a2dSCharles.Forsyth nextgp:;
2756*18eb7a2dSCharles.Forsyth }
2757*18eb7a2dSCharles.Forsyth error("cannot place goto %d\n", i);
2758*18eb7a2dSCharles.Forsyth }
2759*18eb7a2dSCharles.Forsyth
2760*18eb7a2dSCharles.Forsyth void
stin(int i)2761*18eb7a2dSCharles.Forsyth stin(int i)
2762*18eb7a2dSCharles.Forsyth {
2763*18eb7a2dSCharles.Forsyth int *r, *s, n, flag, j, *q1, *q2;
2764*18eb7a2dSCharles.Forsyth
2765*18eb7a2dSCharles.Forsyth tystate[i] = 0;
2766*18eb7a2dSCharles.Forsyth
2767*18eb7a2dSCharles.Forsyth /* enter state i into the amem array */
2768*18eb7a2dSCharles.Forsyth q2 = mem0+temp1[i+1];
2769*18eb7a2dSCharles.Forsyth q1 = mem0+temp1[i];
2770*18eb7a2dSCharles.Forsyth /* find an acceptable place */
2771*18eb7a2dSCharles.Forsyth for(n = -maxoff; n < ACTSIZE; n++) {
2772*18eb7a2dSCharles.Forsyth flag = 0;
2773*18eb7a2dSCharles.Forsyth for(r = q1; r < q2; r += 2) {
2774*18eb7a2dSCharles.Forsyth if((s = *r + n + amem) < amem)
2775*18eb7a2dSCharles.Forsyth goto nextn;
2776*18eb7a2dSCharles.Forsyth if(*s == 0)
2777*18eb7a2dSCharles.Forsyth flag++;
2778*18eb7a2dSCharles.Forsyth else
2779*18eb7a2dSCharles.Forsyth if(*s != r[1])
2780*18eb7a2dSCharles.Forsyth goto nextn;
2781*18eb7a2dSCharles.Forsyth }
2782*18eb7a2dSCharles.Forsyth
2783*18eb7a2dSCharles.Forsyth /* check that the position equals another only if the states are identical */
2784*18eb7a2dSCharles.Forsyth for(j=0; j<nstate; j++) {
2785*18eb7a2dSCharles.Forsyth if(indgo[j] == n) {
2786*18eb7a2dSCharles.Forsyth
2787*18eb7a2dSCharles.Forsyth /* we have some disagreement */
2788*18eb7a2dSCharles.Forsyth if(flag)
2789*18eb7a2dSCharles.Forsyth goto nextn;
2790*18eb7a2dSCharles.Forsyth if(temp1[j+1]+temp1[i] == temp1[j]+temp1[i+1]) {
2791*18eb7a2dSCharles.Forsyth
2792*18eb7a2dSCharles.Forsyth /* states are equal */
2793*18eb7a2dSCharles.Forsyth indgo[i] = n;
2794*18eb7a2dSCharles.Forsyth if(adb > 1)
2795*18eb7a2dSCharles.Forsyth Bprint(ftable,
2796*18eb7a2dSCharles.Forsyth "State %d: entry at %d equals state %d\n",
2797*18eb7a2dSCharles.Forsyth i, n, j);
2798*18eb7a2dSCharles.Forsyth return;
2799*18eb7a2dSCharles.Forsyth }
2800*18eb7a2dSCharles.Forsyth
2801*18eb7a2dSCharles.Forsyth /* we have some disagreement */
2802*18eb7a2dSCharles.Forsyth goto nextn;
2803*18eb7a2dSCharles.Forsyth }
2804*18eb7a2dSCharles.Forsyth }
2805*18eb7a2dSCharles.Forsyth
2806*18eb7a2dSCharles.Forsyth for(r = q1; r < q2; r += 2) {
2807*18eb7a2dSCharles.Forsyth if((s = *r+n+amem) >= &amem[ACTSIZE])
2808*18eb7a2dSCharles.Forsyth error("out of space in optimizer a array");
2809*18eb7a2dSCharles.Forsyth if(s > maxa)
2810*18eb7a2dSCharles.Forsyth maxa = s;
2811*18eb7a2dSCharles.Forsyth if(*s != 0 && *s != r[1])
2812*18eb7a2dSCharles.Forsyth error("clobber of a array, pos'n %d, by %d", s-amem, r[1]);
2813*18eb7a2dSCharles.Forsyth *s = r[1];
2814*18eb7a2dSCharles.Forsyth }
2815*18eb7a2dSCharles.Forsyth indgo[i] = n;
2816*18eb7a2dSCharles.Forsyth if(adb > 1)
2817*18eb7a2dSCharles.Forsyth Bprint(ftable, "State %d: entry at %d\n", i, indgo[i]);
2818*18eb7a2dSCharles.Forsyth return;
2819*18eb7a2dSCharles.Forsyth nextn:;
2820*18eb7a2dSCharles.Forsyth }
2821*18eb7a2dSCharles.Forsyth error("Error; failure to place state %d\n", i);
2822*18eb7a2dSCharles.Forsyth }
2823*18eb7a2dSCharles.Forsyth
2824*18eb7a2dSCharles.Forsyth /*
2825*18eb7a2dSCharles.Forsyth * finds the next i
2826*18eb7a2dSCharles.Forsyth */
2827*18eb7a2dSCharles.Forsyth int
nxti(void)2828*18eb7a2dSCharles.Forsyth nxti(void)
2829*18eb7a2dSCharles.Forsyth {
2830*18eb7a2dSCharles.Forsyth int i, max, maxi;
2831*18eb7a2dSCharles.Forsyth
2832*18eb7a2dSCharles.Forsyth max = 0;
2833*18eb7a2dSCharles.Forsyth maxi = 0;
2834*18eb7a2dSCharles.Forsyth for(i = 1; i <= nnonter; i++)
2835*18eb7a2dSCharles.Forsyth if(ggreed[i] >= max) {
2836*18eb7a2dSCharles.Forsyth max = ggreed[i];
2837*18eb7a2dSCharles.Forsyth maxi = -i;
2838*18eb7a2dSCharles.Forsyth }
2839*18eb7a2dSCharles.Forsyth for(i = 0; i < nstate; ++i)
2840*18eb7a2dSCharles.Forsyth if(tystate[i] >= max) {
2841*18eb7a2dSCharles.Forsyth max = tystate[i];
2842*18eb7a2dSCharles.Forsyth maxi = i;
2843*18eb7a2dSCharles.Forsyth }
2844*18eb7a2dSCharles.Forsyth if(nxdb)
2845*18eb7a2dSCharles.Forsyth Bprint(ftable, "nxti = %d, max = %d\n", maxi, max);
2846*18eb7a2dSCharles.Forsyth if(max == 0)
2847*18eb7a2dSCharles.Forsyth return NOMORE;
2848*18eb7a2dSCharles.Forsyth return maxi;
2849*18eb7a2dSCharles.Forsyth }
2850*18eb7a2dSCharles.Forsyth
2851*18eb7a2dSCharles.Forsyth /*
2852*18eb7a2dSCharles.Forsyth * write summary
2853*18eb7a2dSCharles.Forsyth */
2854*18eb7a2dSCharles.Forsyth void
osummary(void)2855*18eb7a2dSCharles.Forsyth osummary(void)
2856*18eb7a2dSCharles.Forsyth {
2857*18eb7a2dSCharles.Forsyth
2858*18eb7a2dSCharles.Forsyth int i, *p;
2859*18eb7a2dSCharles.Forsyth
2860*18eb7a2dSCharles.Forsyth if(foutput == 0)
2861*18eb7a2dSCharles.Forsyth return;
2862*18eb7a2dSCharles.Forsyth i = 0;
2863*18eb7a2dSCharles.Forsyth for(p = maxa; p >= amem; p--)
2864*18eb7a2dSCharles.Forsyth if(*p == 0)
2865*18eb7a2dSCharles.Forsyth i++;
2866*18eb7a2dSCharles.Forsyth
2867*18eb7a2dSCharles.Forsyth Bprint(foutput, "Optimizer space used: input %d/%d, output %d/%d\n",
2868*18eb7a2dSCharles.Forsyth (int)(pmem-mem0+1), MEMSIZE, (int)(maxa-amem+1), ACTSIZE);
2869*18eb7a2dSCharles.Forsyth Bprint(foutput, "%d table entries, %d zero\n", (int)(maxa-amem+1), i);
2870*18eb7a2dSCharles.Forsyth Bprint(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff);
2871*18eb7a2dSCharles.Forsyth }
2872*18eb7a2dSCharles.Forsyth
2873*18eb7a2dSCharles.Forsyth /*
2874*18eb7a2dSCharles.Forsyth * this version is for C
2875*18eb7a2dSCharles.Forsyth * write out the optimized parser
2876*18eb7a2dSCharles.Forsyth */
2877*18eb7a2dSCharles.Forsyth void
aoutput(void)2878*18eb7a2dSCharles.Forsyth aoutput(void)
2879*18eb7a2dSCharles.Forsyth {
2880*18eb7a2dSCharles.Forsyth Bprint(ftable, "#define\tYYLAST\t%d\n", (int)(maxa-amem+1));
2881*18eb7a2dSCharles.Forsyth arout("yyact", amem, (maxa-amem)+1);
2882*18eb7a2dSCharles.Forsyth arout("yypact", indgo, nstate);
2883*18eb7a2dSCharles.Forsyth arout("yypgo", pgo, nnonter+1);
2884*18eb7a2dSCharles.Forsyth }
2885*18eb7a2dSCharles.Forsyth
2886*18eb7a2dSCharles.Forsyth void
arout(char * s,int * v,int n)2887*18eb7a2dSCharles.Forsyth arout(char *s, int *v, int n)
2888*18eb7a2dSCharles.Forsyth {
2889*18eb7a2dSCharles.Forsyth int i;
2890*18eb7a2dSCharles.Forsyth
2891*18eb7a2dSCharles.Forsyth Bprint(ftable, "short %s[] =\n{", s);
2892*18eb7a2dSCharles.Forsyth for(i = 0; i < n;) {
2893*18eb7a2dSCharles.Forsyth if(i%10 == 0)
2894*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n");
2895*18eb7a2dSCharles.Forsyth Bprint(ftable, "%4d", v[i]);
2896*18eb7a2dSCharles.Forsyth i++;
2897*18eb7a2dSCharles.Forsyth if(i == n)
2898*18eb7a2dSCharles.Forsyth Bprint(ftable, "\n};\n");
2899*18eb7a2dSCharles.Forsyth else
2900*18eb7a2dSCharles.Forsyth Bprint(ftable, ",");
2901*18eb7a2dSCharles.Forsyth }
2902*18eb7a2dSCharles.Forsyth }
2903*18eb7a2dSCharles.Forsyth
2904*18eb7a2dSCharles.Forsyth /*
2905*18eb7a2dSCharles.Forsyth * read and convert an integer from the standard input
2906*18eb7a2dSCharles.Forsyth * return the terminating character
2907*18eb7a2dSCharles.Forsyth * blanks, tabs, and newlines are ignored
2908*18eb7a2dSCharles.Forsyth */
2909*18eb7a2dSCharles.Forsyth int
gtnm(void)2910*18eb7a2dSCharles.Forsyth gtnm(void)
2911*18eb7a2dSCharles.Forsyth {
2912*18eb7a2dSCharles.Forsyth int sign, val, c;
2913*18eb7a2dSCharles.Forsyth
2914*18eb7a2dSCharles.Forsyth sign = 0;
2915*18eb7a2dSCharles.Forsyth val = 0;
2916*18eb7a2dSCharles.Forsyth while((c=Bgetrune(finput)) != Beof) {
2917*18eb7a2dSCharles.Forsyth if(isdigit(c)) {
2918*18eb7a2dSCharles.Forsyth val = val*10 + c-'0';
2919*18eb7a2dSCharles.Forsyth continue;
2920*18eb7a2dSCharles.Forsyth }
2921*18eb7a2dSCharles.Forsyth if(c == '-') {
2922*18eb7a2dSCharles.Forsyth sign = 1;
2923*18eb7a2dSCharles.Forsyth continue;
2924*18eb7a2dSCharles.Forsyth }
2925*18eb7a2dSCharles.Forsyth break;
2926*18eb7a2dSCharles.Forsyth }
2927*18eb7a2dSCharles.Forsyth if(sign)
2928*18eb7a2dSCharles.Forsyth val = -val;
2929*18eb7a2dSCharles.Forsyth *pmem++ = val;
2930*18eb7a2dSCharles.Forsyth if(pmem >= &mem0[MEMSIZE])
2931*18eb7a2dSCharles.Forsyth error("out of space");
2932*18eb7a2dSCharles.Forsyth return c;
2933*18eb7a2dSCharles.Forsyth }
2934