|
|
1.1 root 1: /*
2: * lex3.c
3: * output and table generating routines
4: */
5: #include "lex.h"
6:
7: /* VARARGS */
8: output(s)
9: char *s;
10: {
11: fprintf (fileout, "%r", &s);
12: }
13:
14: /* VARARGS 2 */
15: loutput(i, s)
16: char *s;
17: {
18: while (i--)
19: putc('\t', fileout);
20: fprintf (fileout, "%r\n", &s);
21: }
22:
23: /*
24: * estimate the size of the working space
25: * the generated automata would require, worst case.
26: * this is non-optimum, but fast.
27: * optimum could be a thousand times slower to save a few bytes
28: */
29: ltable()
30: {
31: register c, i, l;
32: register lookflag;
33:
34: l = 0;
35: i = 0;
36: lookflag = 0;
37: while (i < nxt) {
38: c = 0;
39: do {
40: switch(nfa[i][0]) {
41: case LX_LINK:
42: case LX_JUMP:
43: c += mark(nfa[i][1]);
44: case LX_BLIN:
45: case LX_ELIN:
46: case LX_SCON:
47: if (nfa[i][0] != LX_JUMP)
48: c += mark(i+1);
49: ++c;
50: nfa[i][0] = -nfa[i][0];
51: break;
52: case LX_LOOK:
53: case -LX_LOOK:
54: lookflag = 1;
55: if (c > l)
56: l = c;
57: c = mark(i+1);
58: break;
59: case LX_STOP:
60: if (nfa[i][1])
61: nfa[i][1] = 0;
62: else
63: ++c;
64: }
65: } while (nfa[i++][0] != LX_STOP);
66: if (c > l)
67: l = c;
68: }
69: ++l;
70: for (i=0; i<nxt; ++i)
71: if (nfa[i][0] < 0)
72: nfa[i][0] = -nfa[i][0];
73: loutput(0, "int *yy_clist[0%o];", l);
74: loutput(0, "int *yy_nlist[0%o];", l);
75: if (lookflag == 0)
76: return;
77: loutput(0, "int *yy_llist[0%o];", l);
78: }
79:
80: /*
81: * used by ltable, mark a state as counted
82: */
83: mark(state)
84: {
85: switch (nfa[state][0]) {
86: case LX_STOP:
87: if (nfa[state][1]++)
88: break;
89: case LX_LOOK:
90: case LX_ACPT:
91: case LX_CHAR:
92: case LX_CLAS:
93: case LX_ANYC:
94: nfa[state][0] = -nfa[state][0];
95: return (1);
96: }
97: return (0);
98: }
99:
100: stats()
101: {
102: fprintf(stderr, "rules: %d\tstates: %d\tclasses: %d\n",
103: actn, nxt, clas);
104: }
105:
106: /*
107: * put out #defines for start conditions
108: */
109: sdefns()
110: {
111: register struct def *pd;
112:
113: pd = scnstart;
114: while ((pd=pd->d_next) != NULL)
115: loutput(0, "#define\t%s\t\t0%o", pd->d_name, pd->d_data);
116: }
117:
118: /*
119: * put out #defines for contexts
120: */
121: xdefns()
122: {
123: register struct def *pd;
124: register i = 0;
125:
126: for (pd=ctxstart; pd!=NULL; pd=pd->d_next)
127: ++i;
128: loutput(0, "#define\tyyswitch(x)\tyyctxt((x),(0%o))", i);
129: i = 0;
130: pd = ctxstart;
131: while ((pd=pd->d_next) != NULL)
132: loutput(0, "#define\t%s\t\t0%o", pd->d_name, ++i);
133: }
134:
135: /*
136: * table of nfa starting locations for contexts
137: */
138: xtable()
139: {
140: register struct def *pd;
141:
142: loutput(0, "int yy_ctxtab[] = {");
143: output("00");
144: pd = ctxstart;
145: while ((pd=pd->d_next) != NULL)
146: output(",0%o", pd->d_data);
147: output("\n");
148: loutput(0, "};");
149: }
150:
151: /*
152: * character class tables, here we convert the vertical
153: * class storage to horizontal to save space
154: */
155: btable()
156: {
157: register unsigned char *index;
158: register bit;
159: register b, n, i, t;
160:
161: if (classptr == NULL)
162: return;
163: b = 1;
164: loutput(0, "int yy_lxctab[] = {");
165: for (n=0; n<clas; ++n) {
166: index = classptr + classindex(n);
167: bit = classbit(n);
168: t = 0;
169: i = 0;
170: while (i <= MAXUCHAR) {
171: if (index[i]&bit)
172: t |= b;
173: if ((b<<=1) == 0) {
174: output("0%o", t);
175: if (n+1<clas || i<MAXUCHAR)
176: output(",");
177: if (++i%(8*NBINT) == 0)
178: output("\n");
179: b = 1;
180: t = 0;
181: } else
182: ++i;
183: }
184: }
185: loutput(0, "};");
186: /*
187: * output the bit selector table
188: */
189: loutput(0, "int yy_lxbtab[] = {");
190: i = 0;
191: while (i < NBINT) {
192: output("01<<0%02o", i);
193: if (++i < NBINT)
194: output(",");
195: if (i%(NBINT/2) == 0)
196: output("\n");
197: }
198: loutput(0, "};");
199: }
200:
201: /*
202: * output the actual automata table
203: * each state is packed into an int with the low four bits
204: * being the opcode, the high twelve being the data
205: */
206: ptable()
207: {
208: register i,s;
209:
210: loutput(0, "int yy_lextab[] = {");
211: for (s=0,i=0; i<nxt; ++s,++i) {
212: if (i)
213: output(",");
214: if (s && s%8 == 0)
215: output("\n");
216: output("0%o", nfa[i][0] | (nfa[i][1]<<LR_SHFT));
217: }
218: output("\n");
219: loutput(0, "};");
220: }
221:
222: /*
223: * put a human readable form of the automaton onto stderr
224: * undocumented, but useful for debugging and sort of interesting
225: */
226: printnfa()
227: {
228: register i;
229:
230: for (i=0; i<nxt; ++i) {
231: fprintf(stderr, "%d:\t", i);
232: switch (nfa[i][0]) {
233: case LX_STOP:
234: fprintf(stderr, "stop");
235: break;
236: case LX_LINK:
237: fprintf(stderr, "link ");
238: if (nfa[i][1] > 0)
239: putc('+', stderr);
240: fprintf(stderr, "%d", nfa[i][1]);
241: break;
242: case LX_JUMP:
243: fprintf(stderr, "jump ");
244: if (nfa[i][1] > 0)
245: putc('+', stderr);
246: fprintf(stderr, "%d", nfa[i][1]);
247: break;
248: case LX_LOOK:
249: fprintf(stderr, "look");
250: break;
251: case LX_ACPT:
252: fprintf(stderr, "acpt %d", nfa[i][1]);
253: break;
254: case LX_CHAR:
255: fprintf(stderr, "char ");
256: if (nfa[i][1] == EOF)
257: fprintf(stderr, "EOF");
258: else {
259: putc('\'', stderr);
260: if (iscntrl(nfa[i][1])) switch (nfa[i][1]) {
261: case '\b':
262: fprintf(stderr, "\\b");
263: break;
264: case '\f':
265: fprintf(stderr, "\\f");
266: break;
267: case '\n':
268: fprintf(stderr, "\\n");
269: break;
270: case '\r':
271: fprintf(stderr, "\\r");
272: break;
273: case '\t':
274: fprintf(stderr, "\\t");
275: break;
276: default:
277: fprintf(stderr, "\\%03o", nfa[i][1]);
278: } else
279: putc(nfa[i][1], stderr);
280: putc('\'', stderr);
281: }
282: break;
283: case LX_CLAS:
284: fprintf(stderr, "clas %d", nfa[i][1]);
285: break;
286: case LX_BLIN:
287: fprintf(stderr, "blin");
288: break;
289: case LX_ELIN:
290: fprintf(stderr, "elin");
291: break;
292: case LX_ANYC:
293: fprintf(stderr, "anyc");
294: break;
295: case LX_SCON:
296: fprintf(stderr, "scon %d", nfa[i][1]);
297: break;
298: case LX_TERM:
299: fprintf(stderr, "term");
300: break;
301: default:
302: fprintf(stderr, "undefined");
303: }
304: putc('\n', stderr);
305: }
306: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.