Commit | Line | Data |
---|---|---|
30885fad WJ |
1 | /* |
2 | * Copyright (c) 1989 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Robert Paul Corbett. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | |
16 | * 3. All advertising materials mentioning features or use of this software | |
17 | * must display the following acknowledgement: | |
18 | * This product includes software developed by the University of | |
19 | * California, Berkeley and its contributors. | |
20 | * 4. Neither the name of the University nor the names of its contributors | |
21 | * may be used to endorse or promote products derived from this software | |
22 | * without specific prior written permission. | |
23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
34 | * SUCH DAMAGE. | |
35 | */ | |
36 | ||
37 | #ifndef lint | |
38 | static char sccsid[] = "@(#)output.c 5.6 (Berkeley) 1/20/91"; | |
39 | #endif /* not lint */ | |
40 | ||
41 | #include "defs.h" | |
42 | ||
43 | static int nvectors; | |
44 | static int nentries; | |
45 | static short **froms; | |
46 | static short **tos; | |
47 | static short *tally; | |
48 | static short *width; | |
49 | static short *state_count; | |
50 | static short *order; | |
51 | static short *base; | |
52 | static short *pos; | |
53 | static int maxtable; | |
54 | static short *table; | |
55 | static short *check; | |
56 | static int lowzero; | |
57 | static int high; | |
58 | ||
59 | ||
60 | output() | |
61 | { | |
62 | free_itemsets(); | |
63 | free_shifts(); | |
64 | free_reductions(); | |
65 | output_stored_text(); | |
66 | output_defines(); | |
67 | output_rule_data(); | |
68 | output_yydefred(); | |
69 | output_actions(); | |
70 | free_parser(); | |
71 | output_debug(); | |
72 | output_stype(); | |
73 | if (rflag) write_section(tables); | |
74 | write_section(header); | |
75 | output_trailing_text(); | |
76 | write_section(body); | |
77 | output_semantic_actions(); | |
78 | write_section(trailer); | |
79 | } | |
80 | ||
81 | ||
82 | output_rule_data() | |
83 | { | |
84 | register int i; | |
85 | register int j; | |
86 | ||
87 | ||
88 | fprintf(output_file, "short yylhs[] = {%42d,", | |
89 | symbol_value[start_symbol]); | |
90 | ||
91 | j = 10; | |
92 | for (i = 3; i < nrules; i++) | |
93 | { | |
94 | if (j >= 10) | |
95 | { | |
96 | if (!rflag) ++outline; | |
97 | putc('\n', output_file); | |
98 | j = 1; | |
99 | } | |
100 | else | |
101 | ++j; | |
102 | ||
103 | fprintf(output_file, "%5d,", symbol_value[rlhs[i]]); | |
104 | } | |
105 | if (!rflag) outline += 2; | |
106 | fprintf(output_file, "\n};\n"); | |
107 | ||
108 | fprintf(output_file, "short yylen[] = {%42d,", 2); | |
109 | ||
110 | j = 10; | |
111 | for (i = 3; i < nrules; i++) | |
112 | { | |
113 | if (j >= 10) | |
114 | { | |
115 | if (!rflag) ++outline; | |
116 | putc('\n', output_file); | |
117 | j = 1; | |
118 | } | |
119 | else | |
120 | j++; | |
121 | ||
122 | fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1); | |
123 | } | |
124 | if (!rflag) outline += 2; | |
125 | fprintf(output_file, "\n};\n"); | |
126 | } | |
127 | ||
128 | ||
129 | output_yydefred() | |
130 | { | |
131 | register int i, j; | |
132 | ||
133 | fprintf(output_file, "short yydefred[] = {%39d,", | |
134 | (defred[0] ? defred[0] - 2 : 0)); | |
135 | ||
136 | j = 10; | |
137 | for (i = 1; i < nstates; i++) | |
138 | { | |
139 | if (j < 10) | |
140 | ++j; | |
141 | else | |
142 | { | |
143 | if (!rflag) ++outline; | |
144 | putc('\n', output_file); | |
145 | j = 1; | |
146 | } | |
147 | ||
148 | fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0)); | |
149 | } | |
150 | ||
151 | if (!rflag) outline += 2; | |
152 | fprintf(output_file, "\n};\n"); | |
153 | } | |
154 | ||
155 | ||
156 | output_actions() | |
157 | { | |
158 | nvectors = 2*nstates + nvars; | |
159 | ||
160 | froms = NEW2(nvectors, short *); | |
161 | tos = NEW2(nvectors, short *); | |
162 | tally = NEW2(nvectors, short); | |
163 | width = NEW2(nvectors, short); | |
164 | ||
165 | token_actions(); | |
166 | FREE(lookaheads); | |
167 | FREE(LA); | |
168 | FREE(LAruleno); | |
169 | FREE(accessing_symbol); | |
170 | ||
171 | goto_actions(); | |
172 | FREE(goto_map + ntokens); | |
173 | FREE(from_state); | |
174 | FREE(to_state); | |
175 | ||
176 | sort_actions(); | |
177 | pack_table(); | |
178 | output_base(); | |
179 | output_table(); | |
180 | output_check(); | |
181 | } | |
182 | ||
183 | ||
184 | token_actions() | |
185 | { | |
186 | register int i, j; | |
187 | register int shiftcount, reducecount; | |
188 | register int max, min; | |
189 | register short *actionrow, *r, *s; | |
190 | register action *p; | |
191 | ||
192 | actionrow = NEW2(2*ntokens, short); | |
193 | for (i = 0; i < nstates; ++i) | |
194 | { | |
195 | if (parser[i]) | |
196 | { | |
197 | for (j = 0; j < 2*ntokens; ++j) | |
198 | actionrow[j] = 0; | |
199 | ||
200 | shiftcount = 0; | |
201 | reducecount = 0; | |
202 | for (p = parser[i]; p; p = p->next) | |
203 | { | |
204 | if (p->suppressed == 0) | |
205 | { | |
206 | if (p->action_code == SHIFT) | |
207 | { | |
208 | ++shiftcount; | |
209 | actionrow[p->symbol] = p->number; | |
210 | } | |
211 | else if (p->action_code == REDUCE && p->number != defred[i]) | |
212 | { | |
213 | ++reducecount; | |
214 | actionrow[p->symbol + ntokens] = p->number; | |
215 | } | |
216 | } | |
217 | } | |
218 | ||
219 | tally[i] = shiftcount; | |
220 | tally[nstates+i] = reducecount; | |
221 | width[i] = 0; | |
222 | width[nstates+i] = 0; | |
223 | if (shiftcount > 0) | |
224 | { | |
225 | froms[i] = r = NEW2(shiftcount, short); | |
226 | tos[i] = s = NEW2(shiftcount, short); | |
227 | min = MAXSHORT; | |
228 | max = 0; | |
229 | for (j = 0; j < ntokens; ++j) | |
230 | { | |
231 | if (actionrow[j]) | |
232 | { | |
233 | if (min > symbol_value[j]) | |
234 | min = symbol_value[j]; | |
235 | if (max < symbol_value[j]) | |
236 | max = symbol_value[j]; | |
237 | *r++ = symbol_value[j]; | |
238 | *s++ = actionrow[j]; | |
239 | } | |
240 | } | |
241 | width[i] = max - min + 1; | |
242 | } | |
243 | if (reducecount > 0) | |
244 | { | |
245 | froms[nstates+i] = r = NEW2(reducecount, short); | |
246 | tos[nstates+i] = s = NEW2(reducecount, short); | |
247 | min = MAXSHORT; | |
248 | max = 0; | |
249 | for (j = 0; j < ntokens; ++j) | |
250 | { | |
251 | if (actionrow[ntokens+j]) | |
252 | { | |
253 | if (min > symbol_value[j]) | |
254 | min = symbol_value[j]; | |
255 | if (max < symbol_value[j]) | |
256 | max = symbol_value[j]; | |
257 | *r++ = symbol_value[j]; | |
258 | *s++ = actionrow[ntokens+j] - 2; | |
259 | } | |
260 | } | |
261 | width[nstates+i] = max - min + 1; | |
262 | } | |
263 | } | |
264 | } | |
265 | FREE(actionrow); | |
266 | } | |
267 | ||
268 | goto_actions() | |
269 | { | |
270 | register int i, j, k; | |
271 | ||
272 | state_count = NEW2(nstates, short); | |
273 | ||
274 | k = default_goto(start_symbol + 1); | |
275 | fprintf(output_file, "short yydgoto[] = {%40d,", k); | |
276 | save_column(start_symbol + 1, k); | |
277 | ||
278 | j = 10; | |
279 | for (i = start_symbol + 2; i < nsyms; i++) | |
280 | { | |
281 | if (j >= 10) | |
282 | { | |
283 | if (!rflag) ++outline; | |
284 | putc('\n', output_file); | |
285 | j = 1; | |
286 | } | |
287 | else | |
288 | ++j; | |
289 | ||
290 | k = default_goto(i); | |
291 | fprintf(output_file, "%5d,", k); | |
292 | save_column(i, k); | |
293 | } | |
294 | ||
295 | if (!rflag) outline += 2; | |
296 | fprintf(output_file, "\n};\n"); | |
297 | FREE(state_count); | |
298 | } | |
299 | ||
300 | int | |
301 | default_goto(symbol) | |
302 | int symbol; | |
303 | { | |
304 | register int i; | |
305 | register int m; | |
306 | register int n; | |
307 | register int default_state; | |
308 | register int max; | |
309 | ||
310 | m = goto_map[symbol]; | |
311 | n = goto_map[symbol + 1]; | |
312 | ||
313 | if (m == n) return (0); | |
314 | ||
315 | for (i = 0; i < nstates; i++) | |
316 | state_count[i] = 0; | |
317 | ||
318 | for (i = m; i < n; i++) | |
319 | state_count[to_state[i]]++; | |
320 | ||
321 | max = 0; | |
322 | default_state = 0; | |
323 | for (i = 0; i < nstates; i++) | |
324 | { | |
325 | if (state_count[i] > max) | |
326 | { | |
327 | max = state_count[i]; | |
328 | default_state = i; | |
329 | } | |
330 | } | |
331 | ||
332 | return (default_state); | |
333 | } | |
334 | ||
335 | ||
336 | ||
337 | save_column(symbol, default_state) | |
338 | int symbol; | |
339 | int default_state; | |
340 | { | |
341 | register int i; | |
342 | register int m; | |
343 | register int n; | |
344 | register short *sp; | |
345 | register short *sp1; | |
346 | register short *sp2; | |
347 | register int count; | |
348 | register int symno; | |
349 | ||
350 | m = goto_map[symbol]; | |
351 | n = goto_map[symbol + 1]; | |
352 | ||
353 | count = 0; | |
354 | for (i = m; i < n; i++) | |
355 | { | |
356 | if (to_state[i] != default_state) | |
357 | ++count; | |
358 | } | |
359 | if (count == 0) return; | |
360 | ||
361 | symno = symbol_value[symbol] + 2*nstates; | |
362 | ||
363 | froms[symno] = sp1 = sp = NEW2(count, short); | |
364 | tos[symno] = sp2 = NEW2(count, short); | |
365 | ||
366 | for (i = m; i < n; i++) | |
367 | { | |
368 | if (to_state[i] != default_state) | |
369 | { | |
370 | *sp1++ = from_state[i]; | |
371 | *sp2++ = to_state[i]; | |
372 | } | |
373 | } | |
374 | ||
375 | tally[symno] = count; | |
376 | width[symno] = sp1[-1] - sp[0] + 1; | |
377 | } | |
378 | ||
379 | sort_actions() | |
380 | { | |
381 | register int i; | |
382 | register int j; | |
383 | register int k; | |
384 | register int t; | |
385 | register int w; | |
386 | ||
387 | order = NEW2(nvectors, short); | |
388 | nentries = 0; | |
389 | ||
390 | for (i = 0; i < nvectors; i++) | |
391 | { | |
392 | if (tally[i] > 0) | |
393 | { | |
394 | t = tally[i]; | |
395 | w = width[i]; | |
396 | j = nentries - 1; | |
397 | ||
398 | while (j >= 0 && (width[order[j]] < w)) | |
399 | j--; | |
400 | ||
401 | while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) | |
402 | j--; | |
403 | ||
404 | for (k = nentries - 1; k > j; k--) | |
405 | order[k + 1] = order[k]; | |
406 | ||
407 | order[j + 1] = i; | |
408 | nentries++; | |
409 | } | |
410 | } | |
411 | } | |
412 | ||
413 | ||
414 | pack_table() | |
415 | { | |
416 | register int i; | |
417 | register int place; | |
418 | register int state; | |
419 | ||
420 | base = NEW2(nvectors, short); | |
421 | pos = NEW2(nentries, short); | |
422 | ||
423 | maxtable = 1000; | |
424 | table = NEW2(maxtable, short); | |
425 | check = NEW2(maxtable, short); | |
426 | ||
427 | lowzero = 0; | |
428 | high = 0; | |
429 | ||
430 | for (i = 0; i < maxtable; i++) | |
431 | check[i] = -1; | |
432 | ||
433 | for (i = 0; i < nentries; i++) | |
434 | { | |
435 | state = matching_vector(i); | |
436 | ||
437 | if (state < 0) | |
438 | place = pack_vector(i); | |
439 | else | |
440 | place = base[state]; | |
441 | ||
442 | pos[i] = place; | |
443 | base[order[i]] = place; | |
444 | } | |
445 | ||
446 | for (i = 0; i < nvectors; i++) | |
447 | { | |
448 | if (froms[i]) | |
449 | FREE(froms[i]); | |
450 | if (tos[i]) | |
451 | FREE(tos[i]); | |
452 | } | |
453 | ||
454 | FREE(froms); | |
455 | FREE(tos); | |
456 | FREE(pos); | |
457 | } | |
458 | ||
459 | ||
460 | /* The function matching_vector determines if the vector specified by */ | |
461 | /* the input parameter matches a previously considered vector. The */ | |
462 | /* test at the start of the function checks if the vector represents */ | |
463 | /* a row of shifts over terminal symbols or a row of reductions, or a */ | |
464 | /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ | |
465 | /* check if a column of shifts over a nonterminal symbols matches a */ | |
466 | /* previously considered vector. Because of the nature of LR parsing */ | |
467 | /* tables, no two columns can match. Therefore, the only possible */ | |
468 | /* match would be between a row and a column. Such matches are */ | |
469 | /* unlikely. Therefore, to save time, no attempt is made to see if a */ | |
470 | /* column matches a previously considered vector. */ | |
471 | /* */ | |
472 | /* Matching_vector is poorly designed. The test could easily be made */ | |
473 | /* faster. Also, it depends on the vectors being in a specific */ | |
474 | /* order. */ | |
475 | ||
476 | int | |
477 | matching_vector(vector) | |
478 | int vector; | |
479 | { | |
480 | register int i; | |
481 | register int j; | |
482 | register int k; | |
483 | register int t; | |
484 | register int w; | |
485 | register int match; | |
486 | register int prev; | |
487 | ||
488 | i = order[vector]; | |
489 | if (i >= 2*nstates) | |
490 | return (-1); | |
491 | ||
492 | t = tally[i]; | |
493 | w = width[i]; | |
494 | ||
495 | for (prev = vector - 1; prev >= 0; prev--) | |
496 | { | |
497 | j = order[prev]; | |
498 | if (width[j] != w || tally[j] != t) | |
499 | return (-1); | |
500 | ||
501 | match = 1; | |
502 | for (k = 0; match && k < t; k++) | |
503 | { | |
504 | if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) | |
505 | match = 0; | |
506 | } | |
507 | ||
508 | if (match) | |
509 | return (j); | |
510 | } | |
511 | ||
512 | return (-1); | |
513 | } | |
514 | ||
515 | ||
516 | ||
517 | int | |
518 | pack_vector(vector) | |
519 | int vector; | |
520 | { | |
521 | register int i, j, k, l; | |
522 | register int t; | |
523 | register int loc; | |
524 | register int ok; | |
525 | register short *from; | |
526 | register short *to; | |
527 | int newmax; | |
528 | ||
529 | i = order[vector]; | |
530 | t = tally[i]; | |
531 | assert(t); | |
532 | ||
533 | from = froms[i]; | |
534 | to = tos[i]; | |
535 | ||
536 | j = lowzero - from[0]; | |
537 | for (k = 1; k < t; ++k) | |
538 | if (lowzero - from[k] > j) | |
539 | j = lowzero - from[k]; | |
540 | for (;; ++j) | |
541 | { | |
542 | if (j == 0) | |
543 | continue; | |
544 | ok = 1; | |
545 | for (k = 0; ok && k < t; k++) | |
546 | { | |
547 | loc = j + from[k]; | |
548 | if (loc >= maxtable) | |
549 | { | |
550 | if (loc >= MAXTABLE) | |
551 | fatal("maximum table size exceeded"); | |
552 | ||
553 | newmax = maxtable; | |
554 | do { newmax += 200; } while (newmax <= loc); | |
555 | table = (short *) REALLOC(table, newmax*sizeof(short)); | |
556 | if (table == 0) no_space(); | |
557 | check = (short *) REALLOC(check, newmax*sizeof(short)); | |
558 | if (check == 0) no_space(); | |
559 | for (l = maxtable; l < newmax; ++l) | |
560 | { | |
561 | table[l] = 0; | |
562 | check[l] = -1; | |
563 | } | |
564 | maxtable = newmax; | |
565 | } | |
566 | ||
567 | if (check[loc] != -1) | |
568 | ok = 0; | |
569 | } | |
570 | for (k = 0; ok && k < vector; k++) | |
571 | { | |
572 | if (pos[k] == j) | |
573 | ok = 0; | |
574 | } | |
575 | if (ok) | |
576 | { | |
577 | for (k = 0; k < t; k++) | |
578 | { | |
579 | loc = j + from[k]; | |
580 | table[loc] = to[k]; | |
581 | check[loc] = from[k]; | |
582 | if (loc > high) high = loc; | |
583 | } | |
584 | ||
585 | while (check[lowzero] != -1) | |
586 | ++lowzero; | |
587 | ||
588 | return (j); | |
589 | } | |
590 | } | |
591 | } | |
592 | ||
593 | ||
594 | ||
595 | output_base() | |
596 | { | |
597 | register int i, j; | |
598 | ||
599 | fprintf(output_file, "short yysindex[] = {%39d,", base[0]); | |
600 | ||
601 | j = 10; | |
602 | for (i = 1; i < nstates; i++) | |
603 | { | |
604 | if (j >= 10) | |
605 | { | |
606 | if (!rflag) ++outline; | |
607 | putc('\n', output_file); | |
608 | j = 1; | |
609 | } | |
610 | else | |
611 | ++j; | |
612 | ||
613 | fprintf(output_file, "%5d,", base[i]); | |
614 | } | |
615 | ||
616 | if (!rflag) outline += 2; | |
617 | fprintf(output_file, "\n};\nshort yyrindex[] = {%39d,", | |
618 | base[nstates]); | |
619 | ||
620 | j = 10; | |
621 | for (i = nstates + 1; i < 2*nstates; i++) | |
622 | { | |
623 | if (j >= 10) | |
624 | { | |
625 | if (!rflag) ++outline; | |
626 | putc('\n', output_file); | |
627 | j = 1; | |
628 | } | |
629 | else | |
630 | ++j; | |
631 | ||
632 | fprintf(output_file, "%5d,", base[i]); | |
633 | } | |
634 | ||
635 | if (!rflag) outline += 2; | |
636 | fprintf(output_file, "\n};\nshort yygindex[] = {%39d,", | |
637 | base[2*nstates]); | |
638 | ||
639 | j = 10; | |
640 | for (i = 2*nstates + 1; i < nvectors - 1; i++) | |
641 | { | |
642 | if (j >= 10) | |
643 | { | |
644 | if (!rflag) ++outline; | |
645 | putc('\n', output_file); | |
646 | j = 1; | |
647 | } | |
648 | else | |
649 | ++j; | |
650 | ||
651 | fprintf(output_file, "%5d,", base[i]); | |
652 | } | |
653 | ||
654 | if (!rflag) outline += 2; | |
655 | fprintf(output_file, "\n};\n"); | |
656 | FREE(base); | |
657 | } | |
658 | ||
659 | ||
660 | ||
661 | output_table() | |
662 | { | |
663 | register int i; | |
664 | register int j; | |
665 | ||
666 | ++outline; | |
667 | fprintf(code_file, "#define YYTABLESIZE %d\n", high); | |
668 | fprintf(output_file, "short yytable[] = {%40d,", table[0]); | |
669 | ||
670 | j = 10; | |
671 | for (i = 1; i <= high; i++) | |
672 | { | |
673 | if (j >= 10) | |
674 | { | |
675 | if (!rflag) ++outline; | |
676 | putc('\n', output_file); | |
677 | j = 1; | |
678 | } | |
679 | else | |
680 | ++j; | |
681 | ||
682 | fprintf(output_file, "%5d,", table[i]); | |
683 | } | |
684 | ||
685 | if (!rflag) outline += 2; | |
686 | fprintf(output_file, "\n};\n"); | |
687 | FREE(table); | |
688 | } | |
689 | ||
690 | ||
691 | ||
692 | output_check() | |
693 | { | |
694 | register int i; | |
695 | register int j; | |
696 | ||
697 | fprintf(output_file, "short yycheck[] = {%40d,", check[0]); | |
698 | ||
699 | j = 10; | |
700 | for (i = 1; i <= high; i++) | |
701 | { | |
702 | if (j >= 10) | |
703 | { | |
704 | if (!rflag) ++outline; | |
705 | putc('\n', output_file); | |
706 | j = 1; | |
707 | } | |
708 | else | |
709 | ++j; | |
710 | ||
711 | fprintf(output_file, "%5d,", check[i]); | |
712 | } | |
713 | ||
714 | if (!rflag) outline += 2; | |
715 | fprintf(output_file, "\n};\n"); | |
716 | FREE(check); | |
717 | } | |
718 | ||
719 | ||
720 | int | |
721 | is_C_identifier(name) | |
722 | char *name; | |
723 | { | |
724 | register char *s; | |
725 | register int c; | |
726 | ||
727 | s = name; | |
728 | c = *s; | |
729 | if (c == '"') | |
730 | { | |
731 | c = *++s; | |
732 | if (!isalpha(c) && c != '_' && c != '$') | |
733 | return (0); | |
734 | while ((c = *++s) != '"') | |
735 | { | |
736 | if (!isalnum(c) && c != '_' && c != '$') | |
737 | return (0); | |
738 | } | |
739 | return (1); | |
740 | } | |
741 | ||
742 | if (!isalpha(c) && c != '_' && c != '$') | |
743 | return (0); | |
744 | while (c = *++s) | |
745 | { | |
746 | if (!isalnum(c) && c != '_' && c != '$') | |
747 | return (0); | |
748 | } | |
749 | return (1); | |
750 | } | |
751 | ||
752 | ||
753 | output_defines() | |
754 | { | |
755 | register int c, i; | |
756 | register char *s; | |
757 | ||
758 | for (i = 2; i < ntokens; ++i) | |
759 | { | |
760 | s = symbol_name[i]; | |
761 | if (is_C_identifier(s)) | |
762 | { | |
763 | fprintf(code_file, "#define "); | |
764 | if (dflag) fprintf(defines_file, "#define "); | |
765 | c = *s; | |
766 | if (c == '"') | |
767 | { | |
768 | while ((c = *++s) != '"') | |
769 | { | |
770 | putc(c, code_file); | |
771 | if (dflag) putc(c, defines_file); | |
772 | } | |
773 | } | |
774 | else | |
775 | { | |
776 | do | |
777 | { | |
778 | putc(c, code_file); | |
779 | if (dflag) putc(c, defines_file); | |
780 | } | |
781 | while (c = *++s); | |
782 | } | |
783 | ++outline; | |
784 | fprintf(code_file, " %d\n", symbol_value[i]); | |
785 | if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]); | |
786 | } | |
787 | } | |
788 | ||
789 | ++outline; | |
790 | fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]); | |
791 | ||
792 | if (dflag && unionized) | |
793 | { | |
794 | fclose(union_file); | |
795 | union_file = fopen(union_file_name, "r"); | |
796 | if (union_file == NULL) open_error(union_file_name); | |
797 | while ((c = getc(union_file)) != EOF) | |
798 | putc(c, defines_file); | |
799 | fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE yylval;\n"); | |
800 | } | |
801 | } | |
802 | ||
803 | ||
804 | output_stored_text() | |
805 | { | |
806 | register int c; | |
807 | register FILE *in, *out; | |
808 | ||
809 | fclose(text_file); | |
810 | text_file = fopen(text_file_name, "r"); | |
811 | if (text_file == NULL) | |
812 | open_error(text_file_name); | |
813 | in = text_file; | |
814 | if ((c = getc(in)) == EOF) | |
815 | return; | |
816 | out = code_file; | |
817 | if (c == '\n') | |
818 | ++outline; | |
819 | putc(c, out); | |
820 | while ((c = getc(in)) != EOF) | |
821 | { | |
822 | if (c == '\n') | |
823 | ++outline; | |
824 | putc(c, out); | |
825 | } | |
826 | if (!lflag) | |
827 | fprintf(out, line_format, ++outline + 1, code_file_name); | |
828 | } | |
829 | ||
830 | ||
831 | output_debug() | |
832 | { | |
833 | register int i, j, k, max; | |
834 | char **symnam, *s; | |
835 | ||
836 | ++outline; | |
837 | fprintf(code_file, "#define YYFINAL %d\n", final_state); | |
838 | outline += 3; | |
839 | fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", | |
840 | tflag); | |
841 | if (rflag) | |
842 | fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", | |
843 | tflag); | |
844 | ||
845 | max = 0; | |
846 | for (i = 2; i < ntokens; ++i) | |
847 | if (symbol_value[i] > max) | |
848 | max = symbol_value[i]; | |
849 | ++outline; | |
850 | fprintf(code_file, "#define YYMAXTOKEN %d\n", max); | |
851 | ||
852 | symnam = (char **) MALLOC((max+1)*sizeof(char *)); | |
853 | if (symnam == 0) no_space(); | |
854 | ||
855 | /* Note that it is not necessary to initialize the element */ | |
856 | /* symnam[max]. */ | |
857 | for (i = 0; i < max; ++i) | |
858 | symnam[i] = 0; | |
859 | for (i = ntokens - 1; i >= 2; --i) | |
860 | symnam[symbol_value[i]] = symbol_name[i]; | |
861 | symnam[0] = "end-of-file"; | |
862 | ||
863 | if (!rflag) ++outline; | |
864 | fprintf(output_file, "#if YYDEBUG\nchar *yyname[] = {"); | |
865 | j = 80; | |
866 | for (i = 0; i <= max; ++i) | |
867 | { | |
868 | if (s = symnam[i]) | |
869 | { | |
870 | if (s[0] == '"') | |
871 | { | |
872 | k = 7; | |
873 | while (*++s != '"') | |
874 | { | |
875 | ++k; | |
876 | if (*s == '\\') | |
877 | { | |
878 | k += 2; | |
879 | if (*++s == '\\') | |
880 | ++k; | |
881 | } | |
882 | } | |
883 | j += k; | |
884 | if (j > 80) | |
885 | { | |
886 | if (!rflag) ++outline; | |
887 | putc('\n', output_file); | |
888 | j = k; | |
889 | } | |
890 | fprintf(output_file, "\"\\\""); | |
891 | s = symnam[i]; | |
892 | while (*++s != '"') | |
893 | { | |
894 | if (*s == '\\') | |
895 | { | |
896 | fprintf(output_file, "\\\\"); | |
897 | if (*++s == '\\') | |
898 | fprintf(output_file, "\\\\"); | |
899 | else | |
900 | putc(*s, output_file); | |
901 | } | |
902 | else | |
903 | putc(*s, output_file); | |
904 | } | |
905 | fprintf(output_file, "\\\"\","); | |
906 | } | |
907 | else if (s[0] == '\'') | |
908 | { | |
909 | if (s[1] == '"') | |
910 | { | |
911 | j += 7; | |
912 | if (j > 80) | |
913 | { | |
914 | if (!rflag) ++outline; | |
915 | putc('\n', output_file); | |
916 | j = 7; | |
917 | } | |
918 | fprintf(output_file, "\"'\\\"'\","); | |
919 | } | |
920 | else | |
921 | { | |
922 | k = 5; | |
923 | while (*++s != '\'') | |
924 | { | |
925 | ++k; | |
926 | if (*s == '\\') | |
927 | { | |
928 | k += 2; | |
929 | if (*++s == '\\') | |
930 | ++k; | |
931 | } | |
932 | } | |
933 | j += k; | |
934 | if (j > 80) | |
935 | { | |
936 | if (!rflag) ++outline; | |
937 | putc('\n', output_file); | |
938 | j = k; | |
939 | } | |
940 | fprintf(output_file, "\"'"); | |
941 | s = symnam[i]; | |
942 | while (*++s != '\'') | |
943 | { | |
944 | if (*s == '\\') | |
945 | { | |
946 | fprintf(output_file, "\\\\"); | |
947 | if (*++s == '\\') | |
948 | fprintf(output_file, "\\\\"); | |
949 | else | |
950 | putc(*s, output_file); | |
951 | } | |
952 | else | |
953 | putc(*s, output_file); | |
954 | } | |
955 | fprintf(output_file, "'\","); | |
956 | } | |
957 | } | |
958 | else | |
959 | { | |
960 | k = strlen(s) + 3; | |
961 | j += k; | |
962 | if (j > 80) | |
963 | { | |
964 | if (!rflag) ++outline; | |
965 | putc('\n', output_file); | |
966 | j = k; | |
967 | } | |
968 | putc('"', output_file); | |
969 | do { putc(*s, output_file); } while (*++s); | |
970 | fprintf(output_file, "\","); | |
971 | } | |
972 | } | |
973 | else | |
974 | { | |
975 | j += 2; | |
976 | if (j > 80) | |
977 | { | |
978 | if (!rflag) ++outline; | |
979 | putc('\n', output_file); | |
980 | j = 2; | |
981 | } | |
982 | fprintf(output_file, "0,"); | |
983 | } | |
984 | } | |
985 | if (!rflag) outline += 2; | |
986 | fprintf(output_file, "\n};\n"); | |
987 | FREE(symnam); | |
988 | ||
989 | if (!rflag) ++outline; | |
990 | fprintf(output_file, "char *yyrule[] = {\n"); | |
991 | for (i = 2; i < nrules; ++i) | |
992 | { | |
993 | fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); | |
994 | for (j = rrhs[i]; ritem[j] > 0; ++j) | |
995 | { | |
996 | s = symbol_name[ritem[j]]; | |
997 | if (s[0] == '"') | |
998 | { | |
999 | fprintf(output_file, " \\\""); | |
1000 | while (*++s != '"') | |
1001 | { | |
1002 | if (*s == '\\') | |
1003 | { | |
1004 | if (s[1] == '\\') | |
1005 | fprintf(output_file, "\\\\\\\\"); | |
1006 | else | |
1007 | fprintf(output_file, "\\\\%c", s[1]); | |
1008 | ++s; | |
1009 | } | |
1010 | else | |
1011 | putc(*s, output_file); | |
1012 | } | |
1013 | fprintf(output_file, "\\\""); | |
1014 | } | |
1015 | else if (s[0] == '\'') | |
1016 | { | |
1017 | if (s[1] == '"') | |
1018 | fprintf(output_file, " '\\\"'"); | |
1019 | else if (s[1] == '\\') | |
1020 | { | |
1021 | if (s[2] == '\\') | |
1022 | fprintf(output_file, " '\\\\\\\\"); | |
1023 | else | |
1024 | fprintf(output_file, " '\\\\%c", s[2]); | |
1025 | s += 2; | |
1026 | while (*++s != '\'') | |
1027 | putc(*s, output_file); | |
1028 | putc('\'', output_file); | |
1029 | } | |
1030 | else | |
1031 | fprintf(output_file, " '%c'", s[1]); | |
1032 | } | |
1033 | else | |
1034 | fprintf(output_file, " %s", s); | |
1035 | } | |
1036 | if (!rflag) ++outline; | |
1037 | fprintf(output_file, "\",\n"); | |
1038 | } | |
1039 | ||
1040 | if (!rflag) outline += 2; | |
1041 | fprintf(output_file, "};\n#endif\n"); | |
1042 | } | |
1043 | ||
1044 | ||
1045 | output_stype() | |
1046 | { | |
1047 | if (!unionized && ntags == 0) | |
1048 | { | |
1049 | outline += 3; | |
1050 | fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n"); | |
1051 | } | |
1052 | } | |
1053 | ||
1054 | ||
1055 | output_trailing_text() | |
1056 | { | |
1057 | register int c, last; | |
1058 | register FILE *in, *out; | |
1059 | ||
1060 | if (line == 0) | |
1061 | return; | |
1062 | ||
1063 | in = input_file; | |
1064 | out = code_file; | |
1065 | c = *cptr; | |
1066 | if (c == '\n') | |
1067 | { | |
1068 | ++lineno; | |
1069 | if ((c = getc(in)) == EOF) | |
1070 | return; | |
1071 | if (!lflag) | |
1072 | { | |
1073 | ++outline; | |
1074 | fprintf(out, line_format, lineno, input_file_name); | |
1075 | } | |
1076 | if (c == '\n') | |
1077 | ++outline; | |
1078 | putc(c, out); | |
1079 | last = c; | |
1080 | } | |
1081 | else | |
1082 | { | |
1083 | if (!lflag) | |
1084 | { | |
1085 | ++outline; | |
1086 | fprintf(out, line_format, lineno, input_file_name); | |
1087 | } | |
1088 | do { putc(c, out); } while ((c = *++cptr) != '\n'); | |
1089 | ++outline; | |
1090 | putc('\n', out); | |
1091 | last = '\n'; | |
1092 | } | |
1093 | ||
1094 | while ((c = getc(in)) != EOF) | |
1095 | { | |
1096 | if (c == '\n') | |
1097 | ++outline; | |
1098 | putc(c, out); | |
1099 | last = c; | |
1100 | } | |
1101 | ||
1102 | if (last != '\n') | |
1103 | { | |
1104 | ++outline; | |
1105 | putc('\n', out); | |
1106 | } | |
1107 | if (!lflag) | |
1108 | fprintf(out, line_format, ++outline + 1, code_file_name); | |
1109 | } | |
1110 | ||
1111 | ||
1112 | output_semantic_actions() | |
1113 | { | |
1114 | register int c, last; | |
1115 | register FILE *out; | |
1116 | ||
1117 | fclose(action_file); | |
1118 | action_file = fopen(action_file_name, "r"); | |
1119 | if (action_file == NULL) | |
1120 | open_error(action_file_name); | |
1121 | ||
1122 | if ((c = getc(action_file)) == EOF) | |
1123 | return; | |
1124 | ||
1125 | out = code_file; | |
1126 | last = c; | |
1127 | if (c == '\n') | |
1128 | ++outline; | |
1129 | putc(c, out); | |
1130 | while ((c = getc(action_file)) != EOF) | |
1131 | { | |
1132 | if (c == '\n') | |
1133 | ++outline; | |
1134 | putc(c, out); | |
1135 | last = c; | |
1136 | } | |
1137 | ||
1138 | if (last != '\n') | |
1139 | { | |
1140 | ++outline; | |
1141 | putc('\n', out); | |
1142 | } | |
1143 | ||
1144 | if (!lflag) | |
1145 | fprintf(out, line_format, ++outline + 1, code_file_name); | |
1146 | } | |
1147 | ||
1148 | ||
1149 | free_itemsets() | |
1150 | { | |
1151 | register core *cp, *next; | |
1152 | ||
1153 | FREE(state_table); | |
1154 | for (cp = first_state; cp; cp = next) | |
1155 | { | |
1156 | next = cp->next; | |
1157 | FREE(cp); | |
1158 | } | |
1159 | } | |
1160 | ||
1161 | ||
1162 | free_shifts() | |
1163 | { | |
1164 | register shifts *sp, *next; | |
1165 | ||
1166 | FREE(shift_table); | |
1167 | for (sp = first_shift; sp; sp = next) | |
1168 | { | |
1169 | next = sp->next; | |
1170 | FREE(sp); | |
1171 | } | |
1172 | } | |
1173 | ||
1174 | ||
1175 | ||
1176 | free_reductions() | |
1177 | { | |
1178 | register reductions *rp, *next; | |
1179 | ||
1180 | FREE(reduction_table); | |
1181 | for (rp = first_reduction; rp; rp = next) | |
1182 | { | |
1183 | next = rp->next; | |
1184 | FREE(rp); | |
1185 | } | |
1186 | } |