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