vm: merge i386 and arm pagetable code
[minix.git] / external / bsd / byacc / dist / reader.c
blobc4af87a520739b9163c6cfb041201738b1901125
1 /* $NetBSD: reader.c,v 1.7 2011/09/10 21:29:04 christos Exp $ */
2 /* Id: reader.c,v 1.33 2011/09/06 22:56:53 tom Exp */
4 #include "defs.h"
6 #include <sys/cdefs.h>
7 __RCSID("$NetBSD: reader.c,v 1.7 2011/09/10 21:29:04 christos Exp $");
9 /* The line size must be a positive integer. One hundred was chosen */
10 /* because few lines in Yacc input grammars exceed 100 characters. */
11 /* Note that if a line exceeds LINESIZE characters, the line buffer */
12 /* will be expanded to accomodate it. */
14 #define LINESIZE 100
16 #define L_CURL '{'
17 #define R_CURL '}'
19 static void start_rule(bucket *bp, int s_lineno);
21 static char *cache;
22 static int cinc, cache_size;
24 int ntags;
25 static int tagmax;
26 static char **tag_table;
28 static char saw_eof;
29 char unionized;
30 char *cptr, *line;
31 static int linesize;
33 static bucket *goal;
34 static Value_t prec;
35 static int gensym;
36 static char last_was_action;
38 static int maxitems;
39 static bucket **pitem;
41 static int maxrules;
42 static bucket **plhs;
44 static size_t name_pool_size;
45 static char *name_pool;
47 char line_format[] = "#line %d \"%s\"\n";
49 param *lex_param;
50 param *parse_param;
52 static void
53 cachec(int c)
55 assert(cinc >= 0);
56 if (cinc >= cache_size)
58 cache_size += 256;
59 cache = REALLOC(cache, cache_size);
60 NO_SPACE(cache);
62 cache[cinc] = (char)c;
63 ++cinc;
66 static void
67 get_line(void)
69 FILE *f = input_file;
70 int c;
71 int i;
73 if (saw_eof || (c = getc(f)) == EOF)
75 if (line)
77 FREE(line);
78 line = 0;
80 cptr = 0;
81 saw_eof = 1;
82 return;
85 if (line == 0 || linesize != (LINESIZE + 1))
87 if (line)
88 FREE(line);
89 linesize = LINESIZE + 1;
90 line = MALLOC(linesize);
91 NO_SPACE(line);
94 i = 0;
95 ++lineno;
96 for (;;)
98 line[i] = (char)c;
99 if (c == '\n')
101 cptr = line;
102 return;
104 if (++i >= linesize)
106 linesize += LINESIZE;
107 line = REALLOC(line, linesize);
108 NO_SPACE(line);
110 c = getc(f);
111 if (c == EOF)
113 line[i] = '\n';
114 saw_eof = 1;
115 cptr = line;
116 return;
121 static char *
122 dup_line(void)
124 char *p, *s, *t;
126 if (line == 0)
127 return (0);
128 s = line;
129 while (*s != '\n')
130 ++s;
131 p = MALLOC(s - line + 1);
132 NO_SPACE(p);
134 s = line;
135 t = p;
136 while ((*t++ = *s++) != '\n')
137 continue;
138 return (p);
141 static void
142 skip_comment(void)
144 char *s;
146 int st_lineno = lineno;
147 char *st_line = dup_line();
148 char *st_cptr = st_line + (cptr - line);
150 s = cptr + 2;
151 for (;;)
153 if (*s == '*' && s[1] == '/')
155 cptr = s + 2;
156 FREE(st_line);
157 return;
159 if (*s == '\n')
161 get_line();
162 if (line == 0)
163 unterminated_comment(st_lineno, st_line, st_cptr);
164 s = cptr;
166 else
167 ++s;
171 static int
172 nextc(void)
174 char *s;
176 if (line == 0)
178 get_line();
179 if (line == 0)
180 return (EOF);
183 s = cptr;
184 for (;;)
186 switch (*s)
188 case '\n':
189 get_line();
190 if (line == 0)
191 return (EOF);
192 s = cptr;
193 break;
195 case ' ':
196 case '\t':
197 case '\f':
198 case '\r':
199 case '\v':
200 case ',':
201 case ';':
202 ++s;
203 break;
205 case '\\':
206 cptr = s;
207 return ('%');
209 case '/':
210 if (s[1] == '*')
212 cptr = s;
213 skip_comment();
214 s = cptr;
215 break;
217 else if (s[1] == '/')
219 get_line();
220 if (line == 0)
221 return (EOF);
222 s = cptr;
223 break;
225 /* FALLTHRU */
227 default:
228 cptr = s;
229 return (*s);
235 * Compare keyword to cached token, treating '_' and '-' the same. Some
236 * grammars rely upon this misfeature.
238 static int
239 matchec(const char *name)
241 const char *p = cache;
242 const char *q = name;
243 int code = 0; /* assume mismatch */
245 while (*p != '\0' && *q != '\0')
247 char a = *p++;
248 char b = *q++;
249 if (a == '_')
250 a = '-';
251 if (b == '_')
252 b = '-';
253 if (a != b)
254 break;
255 if (*p == '\0' && *q == '\0')
257 code = 1;
258 break;
261 return code;
264 static int
265 keyword(void)
267 int c;
268 char *t_cptr = cptr;
270 c = *++cptr;
271 if (isalpha(c))
273 cinc = 0;
274 for (;;)
276 if (isalpha(c))
278 if (isupper(c))
279 c = tolower(c);
280 cachec(c);
282 else if (isdigit(c)
283 || c == '-'
284 || c == '_'
285 || c == '.'
286 || c == '$')
288 cachec(c);
290 else
292 break;
294 c = *++cptr;
296 cachec(NUL);
298 if (matchec("token") || matchec("term"))
299 return (TOKEN);
300 if (matchec("type"))
301 return (TYPE);
302 if (matchec("left"))
303 return (LEFT);
304 if (matchec("right"))
305 return (RIGHT);
306 if (matchec("nonassoc") || matchec("binary"))
307 return (NONASSOC);
308 if (matchec("start"))
309 return (START);
310 if (matchec("union"))
311 return (UNION);
312 if (matchec("ident"))
313 return (IDENT);
314 if (matchec("expect"))
315 return (EXPECT);
316 if (matchec("expect-rr"))
317 return (EXPECT_RR);
318 if (matchec("pure-parser"))
319 return (PURE_PARSER);
320 if (matchec("parse-param"))
321 return (PARSE_PARAM);
322 if (matchec("lex-param"))
323 return (LEX_PARAM);
324 if (matchec("yacc"))
325 return (POSIX_YACC);
327 else
329 ++cptr;
330 if (c == L_CURL)
331 return (TEXT);
332 if (c == '%' || c == '\\')
333 return (MARK);
334 if (c == '<')
335 return (LEFT);
336 if (c == '>')
337 return (RIGHT);
338 if (c == '0')
339 return (TOKEN);
340 if (c == '2')
341 return (NONASSOC);
343 syntax_error(lineno, line, t_cptr);
344 /*NOTREACHED */
348 static void
349 copy_ident(void)
351 int c;
352 FILE *f = output_file;
354 c = nextc();
355 if (c == EOF)
356 unexpected_EOF();
357 if (c != '"')
358 syntax_error(lineno, line, cptr);
359 ++outline;
360 fprintf(f, "#ident \"");
361 for (;;)
363 c = *++cptr;
364 if (c == '\n')
366 fprintf(f, "\"\n");
367 return;
369 putc(c, f);
370 if (c == '"')
372 putc('\n', f);
373 ++cptr;
374 return;
379 static void
380 copy_text(void)
382 int c;
383 int quote;
384 FILE *f = text_file;
385 int need_newline = 0;
386 int t_lineno = lineno;
387 char *t_line = dup_line();
388 char *t_cptr = t_line + (cptr - line - 2);
390 if (*cptr == '\n')
392 get_line();
393 if (line == 0)
394 unterminated_text(t_lineno, t_line, t_cptr);
396 if (!lflag)
397 fprintf(f, line_format, lineno, input_file_name);
399 loop:
400 c = *cptr++;
401 switch (c)
403 case '\n':
404 next_line:
405 putc('\n', f);
406 need_newline = 0;
407 get_line();
408 if (line)
409 goto loop;
410 unterminated_text(t_lineno, t_line, t_cptr);
412 case '\'':
413 case '"':
415 int s_lineno = lineno;
416 char *s_line = dup_line();
417 char *s_cptr = s_line + (cptr - line - 1);
419 quote = c;
420 putc(c, f);
421 for (;;)
423 c = *cptr++;
424 putc(c, f);
425 if (c == quote)
427 need_newline = 1;
428 FREE(s_line);
429 goto loop;
431 if (c == '\n')
432 unterminated_string(s_lineno, s_line, s_cptr);
433 if (c == '\\')
435 c = *cptr++;
436 putc(c, f);
437 if (c == '\n')
439 get_line();
440 if (line == 0)
441 unterminated_string(s_lineno, s_line, s_cptr);
447 case '/':
448 putc(c, f);
449 need_newline = 1;
450 c = *cptr;
451 if (c == '/')
453 putc('*', f);
454 while ((c = *++cptr) != '\n')
456 if (c == '*' && cptr[1] == '/')
457 fprintf(f, "* ");
458 else
459 putc(c, f);
461 fprintf(f, "*/");
462 goto next_line;
464 if (c == '*')
466 int c_lineno = lineno;
467 char *c_line = dup_line();
468 char *c_cptr = c_line + (cptr - line - 1);
470 putc('*', f);
471 ++cptr;
472 for (;;)
474 c = *cptr++;
475 putc(c, f);
476 if (c == '*' && *cptr == '/')
478 putc('/', f);
479 ++cptr;
480 FREE(c_line);
481 goto loop;
483 if (c == '\n')
485 get_line();
486 if (line == 0)
487 unterminated_comment(c_lineno, c_line, c_cptr);
491 need_newline = 1;
492 goto loop;
494 case '%':
495 case '\\':
496 if (*cptr == R_CURL)
498 if (need_newline)
499 putc('\n', f);
500 ++cptr;
501 FREE(t_line);
502 return;
504 /* FALLTHRU */
506 default:
507 putc(c, f);
508 need_newline = 1;
509 goto loop;
513 static void
514 puts_both(const char *s)
516 fputs(s, text_file);
517 if (dflag)
518 fputs(s, union_file);
521 static void
522 putc_both(int c)
524 putc(c, text_file);
525 if (dflag)
526 putc(c, union_file);
529 static void
530 copy_union(void)
532 int c;
533 int quote;
534 int depth;
535 int u_lineno = lineno;
536 char *u_line = dup_line();
537 char *u_cptr = u_line + (cptr - line - 6);
539 if (unionized)
540 over_unionized(cptr - 6);
541 unionized = 1;
543 if (!lflag)
544 fprintf(text_file, line_format, lineno, input_file_name);
546 puts_both("#ifdef YYSTYPE\n");
547 puts_both("#undef YYSTYPE_IS_DECLARED\n");
548 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
549 puts_both("#endif\n");
550 puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
551 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
552 puts_both("typedef union");
554 depth = 0;
555 loop:
556 c = *cptr++;
557 putc_both(c);
558 switch (c)
560 case '\n':
561 next_line:
562 get_line();
563 if (line == 0)
564 unterminated_union(u_lineno, u_line, u_cptr);
565 goto loop;
567 case L_CURL:
568 ++depth;
569 goto loop;
571 case R_CURL:
572 if (--depth == 0)
574 puts_both(" YYSTYPE;\n");
575 puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
576 FREE(u_line);
577 return;
579 goto loop;
581 case '\'':
582 case '"':
584 int s_lineno = lineno;
585 char *s_line = dup_line();
586 char *s_cptr = s_line + (cptr - line - 1);
588 quote = c;
589 for (;;)
591 c = *cptr++;
592 putc_both(c);
593 if (c == quote)
595 FREE(s_line);
596 goto loop;
598 if (c == '\n')
599 unterminated_string(s_lineno, s_line, s_cptr);
600 if (c == '\\')
602 c = *cptr++;
603 putc_both(c);
604 if (c == '\n')
606 get_line();
607 if (line == 0)
608 unterminated_string(s_lineno, s_line, s_cptr);
614 case '/':
615 c = *cptr;
616 if (c == '/')
618 putc_both('*');
619 while ((c = *++cptr) != '\n')
621 if (c == '*' && cptr[1] == '/')
623 puts_both("* ");
625 else
627 putc_both(c);
630 puts_both("*/\n");
631 goto next_line;
633 if (c == '*')
635 int c_lineno = lineno;
636 char *c_line = dup_line();
637 char *c_cptr = c_line + (cptr - line - 1);
639 putc_both('*');
640 ++cptr;
641 for (;;)
643 c = *cptr++;
644 putc_both(c);
645 if (c == '*' && *cptr == '/')
647 putc_both('/');
648 ++cptr;
649 FREE(c_line);
650 goto loop;
652 if (c == '\n')
654 get_line();
655 if (line == 0)
656 unterminated_comment(c_lineno, c_line, c_cptr);
660 goto loop;
662 default:
663 goto loop;
668 * Keep a linked list of parameters
670 static void
671 copy_param(int k)
673 char *buf;
674 int c;
675 param *head, *p;
676 int i;
677 int name, type2;
679 c = nextc();
680 if (c == EOF)
681 unexpected_EOF();
682 if (c != '{')
683 goto out;
684 cptr++;
686 c = nextc();
687 if (c == EOF)
688 unexpected_EOF();
689 if (c == '}')
690 goto out;
692 buf = MALLOC(linesize);
693 NO_SPACE(buf);
695 for (i = 0; (c = *cptr++) != '}'; i++)
697 if (c == '\0')
698 missing_brace();
699 if (c == EOF)
700 unexpected_EOF();
701 buf[i] = (char)c;
704 if (i == 0)
705 goto out;
707 buf[i--] = '\0';
708 while (i >= 0 && isspace(UCH(buf[i])))
709 buf[i--] = '\0';
711 if (buf[i] == ']')
713 int level = 1;
714 while (i >= 0 && level > 0 && buf[i] != '[')
716 if (buf[i] == ']')
717 ++level;
718 else if (buf[i] == '[')
719 --level;
720 i--;
722 if (i <= 0)
723 unexpected_EOF();
724 type2 = i--;
726 else
728 type2 = i + 1;
731 while (i >= 0 && (isalnum(UCH(buf[i])) ||
732 UCH(buf[i]) == '_'))
733 i--;
735 if (!isspace(UCH(buf[i])) && buf[i] != '*')
736 goto out;
738 name = i + 1;
740 p = MALLOC(sizeof(*p));
741 NO_SPACE(p);
743 p->type2 = strdup(buf + type2);
744 NO_SPACE(p->type2);
746 buf[type2] = '\0';
748 p->name = strdup(buf + name);
749 NO_SPACE(p->name);
751 buf[name] = '\0';
752 p->type = buf;
754 if (k == LEX_PARAM)
755 head = lex_param;
756 else
757 head = parse_param;
759 if (head != NULL)
761 while (head->next)
762 head = head->next;
763 head->next = p;
765 else
767 if (k == LEX_PARAM)
768 lex_param = p;
769 else
770 parse_param = p;
772 p->next = NULL;
773 return;
775 out:
776 syntax_error(lineno, line, cptr);
779 static int
780 hexval(int c)
782 if (c >= '0' && c <= '9')
783 return (c - '0');
784 if (c >= 'A' && c <= 'F')
785 return (c - 'A' + 10);
786 if (c >= 'a' && c <= 'f')
787 return (c - 'a' + 10);
788 return (-1);
791 static bucket *
792 get_literal(void)
794 int c, quote;
795 int i;
796 int n;
797 char *s;
798 bucket *bp;
799 int s_lineno = lineno;
800 char *s_line = dup_line();
801 char *s_cptr = s_line + (cptr - line);
803 quote = *cptr++;
804 cinc = 0;
805 for (;;)
807 c = *cptr++;
808 if (c == quote)
809 break;
810 if (c == '\n')
811 unterminated_string(s_lineno, s_line, s_cptr);
812 if (c == '\\')
814 char *c_cptr = cptr - 1;
816 c = *cptr++;
817 switch (c)
819 case '\n':
820 get_line();
821 if (line == 0)
822 unterminated_string(s_lineno, s_line, s_cptr);
823 continue;
825 case '0':
826 case '1':
827 case '2':
828 case '3':
829 case '4':
830 case '5':
831 case '6':
832 case '7':
833 n = c - '0';
834 c = *cptr;
835 if (IS_OCTAL(c))
837 n = (n << 3) + (c - '0');
838 c = *++cptr;
839 if (IS_OCTAL(c))
841 n = (n << 3) + (c - '0');
842 ++cptr;
845 if (n > MAXCHAR)
846 illegal_character(c_cptr);
847 c = n;
848 break;
850 case 'x':
851 c = *cptr++;
852 n = hexval(c);
853 if (n < 0 || n >= 16)
854 illegal_character(c_cptr);
855 for (;;)
857 c = *cptr;
858 i = hexval(c);
859 if (i < 0 || i >= 16)
860 break;
861 ++cptr;
862 n = (n << 4) + i;
863 if (n > MAXCHAR)
864 illegal_character(c_cptr);
866 c = n;
867 break;
869 case 'a':
870 c = 7;
871 break;
872 case 'b':
873 c = '\b';
874 break;
875 case 'f':
876 c = '\f';
877 break;
878 case 'n':
879 c = '\n';
880 break;
881 case 'r':
882 c = '\r';
883 break;
884 case 't':
885 c = '\t';
886 break;
887 case 'v':
888 c = '\v';
889 break;
892 cachec(c);
894 FREE(s_line);
896 n = cinc;
897 s = MALLOC(n);
898 NO_SPACE(s);
900 for (i = 0; i < n; ++i)
901 s[i] = cache[i];
903 cinc = 0;
904 if (n == 1)
905 cachec('\'');
906 else
907 cachec('"');
909 for (i = 0; i < n; ++i)
911 c = UCH(s[i]);
912 if (c == '\\' || c == cache[0])
914 cachec('\\');
915 cachec(c);
917 else if (isprint(c))
918 cachec(c);
919 else
921 cachec('\\');
922 switch (c)
924 case 7:
925 cachec('a');
926 break;
927 case '\b':
928 cachec('b');
929 break;
930 case '\f':
931 cachec('f');
932 break;
933 case '\n':
934 cachec('n');
935 break;
936 case '\r':
937 cachec('r');
938 break;
939 case '\t':
940 cachec('t');
941 break;
942 case '\v':
943 cachec('v');
944 break;
945 default:
946 cachec(((c >> 6) & 7) + '0');
947 cachec(((c >> 3) & 7) + '0');
948 cachec((c & 7) + '0');
949 break;
954 if (n == 1)
955 cachec('\'');
956 else
957 cachec('"');
959 cachec(NUL);
960 bp = lookup(cache);
961 bp->class = TERM;
962 if (n == 1 && bp->value == UNDEFINED)
963 bp->value = UCH(*s);
964 FREE(s);
966 return (bp);
969 static int
970 is_reserved(char *name)
972 char *s;
974 if (strcmp(name, ".") == 0 ||
975 strcmp(name, "$accept") == 0 ||
976 strcmp(name, "$end") == 0)
977 return (1);
979 if (name[0] == '$' && name[1] == '$' && isdigit(UCH(name[2])))
981 s = name + 3;
982 while (isdigit(UCH(*s)))
983 ++s;
984 if (*s == NUL)
985 return (1);
988 return (0);
991 static bucket *
992 get_name(void)
994 int c;
996 cinc = 0;
997 for (c = *cptr; IS_IDENT(c); c = *++cptr)
998 cachec(c);
999 cachec(NUL);
1001 if (is_reserved(cache))
1002 used_reserved(cache);
1004 return (lookup(cache));
1007 static Value_t
1008 get_number(void)
1010 int c;
1011 Value_t n;
1013 n = 0;
1014 for (c = *cptr; isdigit(c); c = *++cptr)
1015 n = (Value_t) (10 * n + (c - '0'));
1017 return (n);
1020 static char *
1021 get_tag(void)
1023 int c;
1024 int i;
1025 char *s;
1026 int t_lineno = lineno;
1027 char *t_line = dup_line();
1028 char *t_cptr = t_line + (cptr - line);
1030 ++cptr;
1031 c = nextc();
1032 if (c == EOF)
1033 unexpected_EOF();
1034 if (!isalpha(c) && c != '_' && c != '$')
1035 illegal_tag(t_lineno, t_line, t_cptr);
1037 cinc = 0;
1040 cachec(c);
1041 c = *++cptr;
1043 while (IS_IDENT(c));
1044 cachec(NUL);
1046 c = nextc();
1047 if (c == EOF)
1048 unexpected_EOF();
1049 if (c != '>')
1050 illegal_tag(t_lineno, t_line, t_cptr);
1051 ++cptr;
1053 for (i = 0; i < ntags; ++i)
1055 if (strcmp(cache, tag_table[i]) == 0)
1057 FREE(t_line);
1058 return (tag_table[i]);
1062 if (ntags >= tagmax)
1064 tagmax += 16;
1065 tag_table = (char **)
1066 (tag_table
1067 ? REALLOC(tag_table, (unsigned)tagmax * sizeof(char *))
1068 : MALLOC((unsigned)tagmax * sizeof(char *)));
1069 NO_SPACE(tag_table);
1072 s = MALLOC(cinc);
1073 NO_SPACE(s);
1075 strcpy(s, cache);
1076 tag_table[ntags] = s;
1077 ++ntags;
1078 FREE(t_line);
1079 return (s);
1082 static void
1083 declare_tokens(int assoc)
1085 int c;
1086 bucket *bp;
1087 Value_t value;
1088 char *tag = 0;
1090 if (assoc != TOKEN)
1091 ++prec;
1093 c = nextc();
1094 if (c == EOF)
1095 unexpected_EOF();
1096 if (c == '<')
1098 tag = get_tag();
1099 c = nextc();
1100 if (c == EOF)
1101 unexpected_EOF();
1104 for (;;)
1106 if (isalpha(c) || c == '_' || c == '.' || c == '$')
1107 bp = get_name();
1108 else if (c == '\'' || c == '"')
1109 bp = get_literal();
1110 else
1111 return;
1113 if (bp == goal)
1114 tokenized_start(bp->name);
1115 bp->class = TERM;
1117 if (tag)
1119 if (bp->tag && tag != bp->tag)
1120 retyped_warning(bp->name);
1121 bp->tag = tag;
1124 if (assoc != TOKEN)
1126 if (bp->prec && prec != bp->prec)
1127 reprec_warning(bp->name);
1128 bp->assoc = (Assoc_t) assoc;
1129 bp->prec = prec;
1132 c = nextc();
1133 if (c == EOF)
1134 unexpected_EOF();
1136 if (isdigit(c))
1138 value = get_number();
1139 if (bp->value != UNDEFINED && value != bp->value)
1140 revalued_warning(bp->name);
1141 bp->value = value;
1142 c = nextc();
1143 if (c == EOF)
1144 unexpected_EOF();
1150 * %expect requires special handling
1151 * as it really isn't part of the yacc
1152 * grammar only a flag for yacc proper.
1154 static void
1155 declare_expect(int assoc)
1157 int c;
1159 if (assoc != EXPECT && assoc != EXPECT_RR)
1160 ++prec;
1163 * Stay away from nextc - doesn't
1164 * detect EOL and will read to EOF.
1166 c = *++cptr;
1167 if (c == EOF)
1168 unexpected_EOF();
1170 for (;;)
1172 if (isdigit(c))
1174 if (assoc == EXPECT)
1175 SRexpect = get_number();
1176 else
1177 RRexpect = get_number();
1178 break;
1181 * Looking for number before EOL.
1182 * Spaces, tabs, and numbers are ok,
1183 * words, punc., etc. are syntax errors.
1185 else if (c == '\n' || isalpha(c) || !isspace(c))
1187 syntax_error(lineno, line, cptr);
1189 else
1191 c = *++cptr;
1192 if (c == EOF)
1193 unexpected_EOF();
1198 static void
1199 declare_types(void)
1201 int c;
1202 bucket *bp;
1203 char *tag;
1205 c = nextc();
1206 if (c == EOF)
1207 unexpected_EOF();
1208 if (c != '<')
1209 syntax_error(lineno, line, cptr);
1210 tag = get_tag();
1212 for (;;)
1214 c = nextc();
1215 if (isalpha(c) || c == '_' || c == '.' || c == '$')
1216 bp = get_name();
1217 else if (c == '\'' || c == '"')
1218 bp = get_literal();
1219 else
1220 return;
1222 if (bp->tag && tag != bp->tag)
1223 retyped_warning(bp->name);
1224 bp->tag = tag;
1228 static void
1229 declare_start(void)
1231 int c;
1232 bucket *bp;
1234 c = nextc();
1235 if (c == EOF)
1236 unexpected_EOF();
1237 if (!isalpha(c) && c != '_' && c != '.' && c != '$')
1238 syntax_error(lineno, line, cptr);
1239 bp = get_name();
1240 if (bp->class == TERM)
1241 terminal_start(bp->name);
1242 if (goal && goal != bp)
1243 restarted_warning();
1244 goal = bp;
1247 static void
1248 read_declarations(void)
1250 int c, k;
1252 cache_size = 256;
1253 cache = MALLOC(cache_size);
1254 NO_SPACE(cache);
1256 for (;;)
1258 c = nextc();
1259 if (c == EOF)
1260 unexpected_EOF();
1261 if (c != '%')
1262 syntax_error(lineno, line, cptr);
1263 switch (k = keyword())
1265 case MARK:
1266 return;
1268 case IDENT:
1269 copy_ident();
1270 break;
1272 case TEXT:
1273 copy_text();
1274 break;
1276 case UNION:
1277 copy_union();
1278 break;
1280 case TOKEN:
1281 case LEFT:
1282 case RIGHT:
1283 case NONASSOC:
1284 declare_tokens(k);
1285 break;
1287 case EXPECT:
1288 case EXPECT_RR:
1289 declare_expect(k);
1290 break;
1292 case TYPE:
1293 declare_types();
1294 break;
1296 case START:
1297 declare_start();
1298 break;
1300 case PURE_PARSER:
1301 pure_parser = 1;
1302 break;
1304 case PARSE_PARAM:
1305 case LEX_PARAM:
1306 copy_param(k);
1307 break;
1309 case POSIX_YACC:
1310 /* noop for bison compatibility. byacc is already designed to be posix
1311 * yacc compatible. */
1312 break;
1317 static void
1318 initialize_grammar(void)
1320 nitems = 4;
1321 maxitems = 300;
1323 pitem = (bucket **)MALLOC((unsigned)maxitems * sizeof(bucket *));
1324 NO_SPACE(pitem);
1326 pitem[0] = 0;
1327 pitem[1] = 0;
1328 pitem[2] = 0;
1329 pitem[3] = 0;
1331 nrules = 3;
1332 maxrules = 100;
1334 plhs = (bucket **)MALLOC((unsigned)maxrules * sizeof(bucket *));
1335 NO_SPACE(plhs);
1337 plhs[0] = 0;
1338 plhs[1] = 0;
1339 plhs[2] = 0;
1341 rprec = (short *)MALLOC((unsigned)maxrules * sizeof(short));
1342 NO_SPACE(rprec);
1344 rprec[0] = 0;
1345 rprec[1] = 0;
1346 rprec[2] = 0;
1348 rassoc = (char *)MALLOC((unsigned)maxrules * sizeof(char));
1349 NO_SPACE(rassoc);
1351 rassoc[0] = TOKEN;
1352 rassoc[1] = TOKEN;
1353 rassoc[2] = TOKEN;
1356 static void
1357 expand_items(void)
1359 maxitems += 300;
1360 pitem = (bucket **)REALLOC(pitem, (unsigned)maxitems * sizeof(bucket *));
1361 NO_SPACE(pitem);
1364 static void
1365 expand_rules(void)
1367 maxrules += 100;
1369 plhs = (bucket **)REALLOC(plhs, (unsigned)maxrules * sizeof(bucket *));
1370 NO_SPACE(plhs);
1372 rprec = (short *)REALLOC(rprec, (unsigned)maxrules * sizeof(short));
1373 NO_SPACE(rprec);
1375 rassoc = (char *)REALLOC(rassoc, (unsigned)maxrules * sizeof(char));
1376 NO_SPACE(rassoc);
1379 static void
1380 advance_to_start(void)
1382 int c;
1383 bucket *bp;
1384 char *s_cptr;
1385 int s_lineno;
1387 for (;;)
1389 c = nextc();
1390 if (c != '%')
1391 break;
1392 s_cptr = cptr;
1393 switch (keyword())
1395 case MARK:
1396 no_grammar();
1398 case TEXT:
1399 copy_text();
1400 break;
1402 case START:
1403 declare_start();
1404 break;
1406 default:
1407 syntax_error(lineno, line, s_cptr);
1411 c = nextc();
1412 if (!isalpha(c) && c != '_' && c != '.' && c != '_')
1413 syntax_error(lineno, line, cptr);
1414 bp = get_name();
1415 if (goal == 0)
1417 if (bp->class == TERM)
1418 terminal_start(bp->name);
1419 goal = bp;
1422 s_lineno = lineno;
1423 c = nextc();
1424 if (c == EOF)
1425 unexpected_EOF();
1426 if (c != ':')
1427 syntax_error(lineno, line, cptr);
1428 start_rule(bp, s_lineno);
1429 ++cptr;
1432 static void
1433 start_rule(bucket *bp, int s_lineno)
1435 if (bp->class == TERM)
1436 terminal_lhs(s_lineno);
1437 bp->class = NONTERM;
1438 if (nrules >= maxrules)
1439 expand_rules();
1440 plhs[nrules] = bp;
1441 rprec[nrules] = UNDEFINED;
1442 rassoc[nrules] = TOKEN;
1445 static void
1446 end_rule(void)
1448 int i;
1450 if (!last_was_action && plhs[nrules]->tag)
1452 if (pitem[nitems - 1])
1454 for (i = nitems - 1; (i > 0) && pitem[i]; --i)
1455 continue;
1456 if (pitem[i + 1] == 0 || pitem[i + 1]->tag != plhs[nrules]->tag)
1457 default_action_warning();
1459 else
1461 default_action_warning();
1465 last_was_action = 0;
1466 if (nitems >= maxitems)
1467 expand_items();
1468 pitem[nitems] = 0;
1469 ++nitems;
1470 ++nrules;
1473 static void
1474 insert_empty_rule(void)
1476 bucket *bp, **bpp;
1478 assert(cache);
1479 sprintf(cache, "$$%d", ++gensym);
1480 bp = make_bucket(cache);
1481 last_symbol->next = bp;
1482 last_symbol = bp;
1483 bp->tag = plhs[nrules]->tag;
1484 bp->class = NONTERM;
1486 if ((nitems += 2) > maxitems)
1487 expand_items();
1488 bpp = pitem + nitems - 1;
1489 *bpp-- = bp;
1490 while ((bpp[0] = bpp[-1]) != 0)
1491 --bpp;
1493 if (++nrules >= maxrules)
1494 expand_rules();
1495 plhs[nrules] = plhs[nrules - 1];
1496 plhs[nrules - 1] = bp;
1497 rprec[nrules] = rprec[nrules - 1];
1498 rprec[nrules - 1] = 0;
1499 rassoc[nrules] = rassoc[nrules - 1];
1500 rassoc[nrules - 1] = TOKEN;
1503 static void
1504 add_symbol(void)
1506 int c;
1507 bucket *bp;
1508 int s_lineno = lineno;
1510 c = *cptr;
1511 if (c == '\'' || c == '"')
1512 bp = get_literal();
1513 else
1514 bp = get_name();
1516 c = nextc();
1517 if (c == ':')
1519 end_rule();
1520 start_rule(bp, s_lineno);
1521 ++cptr;
1522 return;
1525 if (last_was_action)
1526 insert_empty_rule();
1527 last_was_action = 0;
1529 if (++nitems > maxitems)
1530 expand_items();
1531 pitem[nitems - 1] = bp;
1534 static char *
1535 after_blanks(char *s)
1537 while (*s != '\0' && isspace(UCH(*s)))
1538 ++s;
1539 return s;
1542 static void
1543 copy_action(void)
1545 int c;
1546 int i, n;
1547 int depth;
1548 int quote;
1549 char *tag;
1550 FILE *f = action_file;
1551 int a_lineno = lineno;
1552 char *a_line = dup_line();
1553 char *a_cptr = a_line + (cptr - line);
1555 if (last_was_action)
1556 insert_empty_rule();
1557 last_was_action = 1;
1559 fprintf(f, "case %d:\n", nrules - 2);
1560 if (!lflag)
1561 fprintf(f, line_format, lineno, input_file_name);
1562 if (*cptr == '=')
1563 ++cptr;
1565 /* avoid putting curly-braces in first column, to ease editing */
1566 if (*after_blanks(cptr) == L_CURL)
1568 putc('\t', f);
1569 cptr = after_blanks(cptr);
1572 n = 0;
1573 for (i = nitems - 1; pitem[i]; --i)
1574 ++n;
1576 depth = 0;
1577 loop:
1578 c = *cptr;
1579 if (c == '$')
1581 if (cptr[1] == '<')
1583 int d_lineno = lineno;
1584 char *d_line = dup_line();
1585 char *d_cptr = d_line + (cptr - line);
1587 ++cptr;
1588 tag = get_tag();
1589 c = *cptr;
1590 if (c == '$')
1592 fprintf(f, "yyval.%s", tag);
1593 ++cptr;
1594 FREE(d_line);
1595 goto loop;
1597 else if (isdigit(c))
1599 i = get_number();
1600 if (i > n)
1601 dollar_warning(d_lineno, i);
1602 fprintf(f, "yystack.l_mark[%d].%s", i - n, tag);
1603 FREE(d_line);
1604 goto loop;
1606 else if (c == '-' && isdigit(UCH(cptr[1])))
1608 ++cptr;
1609 i = -get_number() - n;
1610 fprintf(f, "yystack.l_mark[%d].%s", i, tag);
1611 FREE(d_line);
1612 goto loop;
1614 else
1615 dollar_error(d_lineno, d_line, d_cptr);
1617 else if (cptr[1] == '$')
1619 if (ntags)
1621 tag = plhs[nrules]->tag;
1622 if (tag == 0)
1623 untyped_lhs();
1624 fprintf(f, "yyval.%s", tag);
1626 else
1627 fprintf(f, "yyval");
1628 cptr += 2;
1629 goto loop;
1631 else if (isdigit(UCH(cptr[1])))
1633 ++cptr;
1634 i = get_number();
1635 if (ntags)
1637 if (i <= 0 || i > n)
1638 unknown_rhs(i);
1639 tag = pitem[nitems + i - n - 1]->tag;
1640 if (tag == 0)
1641 untyped_rhs(i, pitem[nitems + i - n - 1]->name);
1642 fprintf(f, "yystack.l_mark[%d].%s", i - n, tag);
1644 else
1646 if (i > n)
1647 dollar_warning(lineno, i);
1648 fprintf(f, "yystack.l_mark[%d]", i - n);
1650 goto loop;
1652 else if (cptr[1] == '-')
1654 cptr += 2;
1655 i = get_number();
1656 if (ntags)
1657 unknown_rhs(-i);
1658 fprintf(f, "yystack.l_mark[%d]", -i - n);
1659 goto loop;
1662 if (isalpha(c) || c == '_' || c == '$')
1666 putc(c, f);
1667 c = *++cptr;
1669 while (isalnum(c) || c == '_' || c == '$');
1670 goto loop;
1672 putc(c, f);
1673 ++cptr;
1674 switch (c)
1676 case '\n':
1677 next_line:
1678 get_line();
1679 if (line)
1680 goto loop;
1681 unterminated_action(a_lineno, a_line, a_cptr);
1683 case ';':
1684 if (depth > 0)
1685 goto loop;
1686 fprintf(f, "\nbreak;\n");
1687 free(a_line);
1688 return;
1690 case L_CURL:
1691 ++depth;
1692 goto loop;
1694 case R_CURL:
1695 if (--depth > 0)
1696 goto loop;
1697 fprintf(f, "\nbreak;\n");
1698 free(a_line);
1699 return;
1701 case '\'':
1702 case '"':
1704 int s_lineno = lineno;
1705 char *s_line = dup_line();
1706 char *s_cptr = s_line + (cptr - line - 1);
1708 quote = c;
1709 for (;;)
1711 c = *cptr++;
1712 putc(c, f);
1713 if (c == quote)
1715 FREE(s_line);
1716 goto loop;
1718 if (c == '\n')
1719 unterminated_string(s_lineno, s_line, s_cptr);
1720 if (c == '\\')
1722 c = *cptr++;
1723 putc(c, f);
1724 if (c == '\n')
1726 get_line();
1727 if (line == 0)
1728 unterminated_string(s_lineno, s_line, s_cptr);
1734 case '/':
1735 c = *cptr;
1736 if (c == '/')
1738 putc('*', f);
1739 while ((c = *++cptr) != '\n')
1741 if (c == '*' && cptr[1] == '/')
1742 fprintf(f, "* ");
1743 else
1744 putc(c, f);
1746 fprintf(f, "*/\n");
1747 goto next_line;
1749 if (c == '*')
1751 int c_lineno = lineno;
1752 char *c_line = dup_line();
1753 char *c_cptr = c_line + (cptr - line - 1);
1755 putc('*', f);
1756 ++cptr;
1757 for (;;)
1759 c = *cptr++;
1760 putc(c, f);
1761 if (c == '*' && *cptr == '/')
1763 putc('/', f);
1764 ++cptr;
1765 FREE(c_line);
1766 goto loop;
1768 if (c == '\n')
1770 get_line();
1771 if (line == 0)
1772 unterminated_comment(c_lineno, c_line, c_cptr);
1776 goto loop;
1778 default:
1779 goto loop;
1783 static int
1784 mark_symbol(void)
1786 int c;
1787 bucket *bp;
1789 c = cptr[1];
1790 if (c == '%' || c == '\\')
1792 cptr += 2;
1793 return (1);
1796 if (c == '=')
1797 cptr += 2;
1798 else if ((c == 'p' || c == 'P') &&
1799 ((c = cptr[2]) == 'r' || c == 'R') &&
1800 ((c = cptr[3]) == 'e' || c == 'E') &&
1801 ((c = cptr[4]) == 'c' || c == 'C') &&
1802 ((c = cptr[5], !IS_IDENT(c))))
1803 cptr += 5;
1804 else
1805 syntax_error(lineno, line, cptr);
1807 c = nextc();
1808 if (isalpha(c) || c == '_' || c == '.' || c == '$')
1809 bp = get_name();
1810 else if (c == '\'' || c == '"')
1811 bp = get_literal();
1812 else
1814 syntax_error(lineno, line, cptr);
1815 /*NOTREACHED */
1818 if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
1819 prec_redeclared();
1821 rprec[nrules] = bp->prec;
1822 rassoc[nrules] = bp->assoc;
1823 return (0);
1826 static void
1827 read_grammar(void)
1829 int c;
1831 initialize_grammar();
1832 advance_to_start();
1834 for (;;)
1836 c = nextc();
1837 if (c == EOF)
1838 break;
1839 if (isalpha(c)
1840 || c == '_'
1841 || c == '.'
1842 || c == '$'
1843 || c == '\''
1844 || c == '"')
1845 add_symbol();
1846 else if (c == L_CURL || c == '=')
1847 copy_action();
1848 else if (c == '|')
1850 end_rule();
1851 start_rule(plhs[nrules - 1], 0);
1852 ++cptr;
1854 else if (c == '%')
1856 if (mark_symbol())
1857 break;
1859 else
1860 syntax_error(lineno, line, cptr);
1862 end_rule();
1865 static void
1866 free_tags(void)
1868 int i;
1870 if (tag_table == 0)
1871 return;
1873 for (i = 0; i < ntags; ++i)
1875 assert(tag_table[i]);
1876 FREE(tag_table[i]);
1878 FREE(tag_table);
1881 static void
1882 pack_names(void)
1884 bucket *bp;
1885 char *p, *s, *t;
1887 name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
1888 for (bp = first_symbol; bp; bp = bp->next)
1889 name_pool_size += strlen(bp->name) + 1;
1891 name_pool = MALLOC(name_pool_size);
1892 NO_SPACE(name_pool);
1894 strlcpy(name_pool, "$accept", name_pool_size);
1895 strlcpy(name_pool + 8, "$end", name_pool_size - 8);
1896 t = name_pool + 13;
1897 for (bp = first_symbol; bp; bp = bp->next)
1899 p = t;
1900 s = bp->name;
1901 while ((*t++ = *s++) != 0)
1902 continue;
1903 FREE(bp->name);
1904 bp->name = p;
1908 static void
1909 check_symbols(void)
1911 bucket *bp;
1913 if (goal->class == UNKNOWN)
1914 undefined_goal(goal->name);
1916 for (bp = first_symbol; bp; bp = bp->next)
1918 if (bp->class == UNKNOWN)
1920 undefined_symbol_warning(bp->name);
1921 bp->class = TERM;
1926 static void
1927 protect_string(char *src, char **des)
1929 unsigned len;
1930 char *s;
1931 char *d;
1933 *des = src;
1934 if (src)
1936 len = 1;
1937 s = src;
1938 while (*s)
1940 if ('\\' == *s || '"' == *s)
1941 len++;
1942 s++;
1943 len++;
1946 *des = d = (char *)MALLOC(len);
1947 NO_SPACE(d);
1949 s = src;
1950 while (*s)
1952 if ('\\' == *s || '"' == *s)
1953 *d++ = '\\';
1954 *d++ = *s++;
1956 *d = '\0';
1960 static void
1961 pack_symbols(void)
1963 bucket *bp;
1964 bucket **v;
1965 Value_t i, j, k, n;
1967 nsyms = 2;
1968 ntokens = 1;
1969 for (bp = first_symbol; bp; bp = bp->next)
1971 ++nsyms;
1972 if (bp->class == TERM)
1973 ++ntokens;
1975 start_symbol = (Value_t) ntokens;
1976 nvars = nsyms - ntokens;
1978 symbol_name = (char **)MALLOC((unsigned)nsyms * sizeof(char *));
1979 NO_SPACE(symbol_name);
1981 symbol_value = (short *)MALLOC((unsigned)nsyms * sizeof(short));
1982 NO_SPACE(symbol_value);
1984 symbol_prec = (short *)MALLOC((unsigned)nsyms * sizeof(short));
1985 NO_SPACE(symbol_prec);
1987 symbol_assoc = MALLOC(nsyms);
1988 NO_SPACE(symbol_assoc);
1990 v = (bucket **)MALLOC((unsigned)nsyms * sizeof(bucket *));
1991 NO_SPACE(v);
1993 v[0] = 0;
1994 v[start_symbol] = 0;
1996 i = 1;
1997 j = (Value_t) (start_symbol + 1);
1998 for (bp = first_symbol; bp; bp = bp->next)
2000 if (bp->class == TERM)
2001 v[i++] = bp;
2002 else
2003 v[j++] = bp;
2005 assert(i == ntokens && j == nsyms);
2007 for (i = 1; i < ntokens; ++i)
2008 v[i]->index = i;
2010 goal->index = (Index_t) (start_symbol + 1);
2011 k = (Value_t) (start_symbol + 2);
2012 while (++i < nsyms)
2013 if (v[i] != goal)
2015 v[i]->index = k;
2016 ++k;
2019 goal->value = 0;
2020 k = 1;
2021 for (i = (Value_t) (start_symbol + 1); i < nsyms; ++i)
2023 if (v[i] != goal)
2025 v[i]->value = k;
2026 ++k;
2030 k = 0;
2031 for (i = 1; i < ntokens; ++i)
2033 n = v[i]->value;
2034 if (n > 256)
2036 for (j = k++; j > 0 && symbol_value[j - 1] > n; --j)
2037 symbol_value[j] = symbol_value[j - 1];
2038 symbol_value[j] = n;
2042 assert(v[1] != 0);
2044 if (v[1]->value == UNDEFINED)
2045 v[1]->value = 256;
2047 j = 0;
2048 n = 257;
2049 for (i = 2; i < ntokens; ++i)
2051 if (v[i]->value == UNDEFINED)
2053 while (j < k && n == symbol_value[j])
2055 while (++j < k && n == symbol_value[j])
2056 continue;
2057 ++n;
2059 v[i]->value = n;
2060 ++n;
2064 symbol_name[0] = name_pool + 8;
2065 symbol_value[0] = 0;
2066 symbol_prec[0] = 0;
2067 symbol_assoc[0] = TOKEN;
2068 for (i = 1; i < ntokens; ++i)
2070 symbol_name[i] = v[i]->name;
2071 symbol_value[i] = v[i]->value;
2072 symbol_prec[i] = v[i]->prec;
2073 symbol_assoc[i] = v[i]->assoc;
2075 symbol_name[start_symbol] = name_pool;
2076 symbol_value[start_symbol] = -1;
2077 symbol_prec[start_symbol] = 0;
2078 symbol_assoc[start_symbol] = TOKEN;
2079 for (++i; i < nsyms; ++i)
2081 k = v[i]->index;
2082 symbol_name[k] = v[i]->name;
2083 symbol_value[k] = v[i]->value;
2084 symbol_prec[k] = v[i]->prec;
2085 symbol_assoc[k] = v[i]->assoc;
2088 if (gflag)
2090 symbol_pname = (char **)MALLOC((unsigned)nsyms * sizeof(char *));
2091 NO_SPACE(symbol_pname);
2093 for (i = 0; i < nsyms; ++i)
2094 protect_string(symbol_name[i], &(symbol_pname[i]));
2097 FREE(v);
2100 static void
2101 pack_grammar(void)
2103 int i;
2104 Value_t j;
2105 Assoc_t assoc;
2106 Value_t prec2;
2108 ritem = (short *)MALLOC((unsigned)nitems * sizeof(short));
2109 NO_SPACE(ritem);
2111 rlhs = (short *)MALLOC((unsigned)nrules * sizeof(short));
2112 NO_SPACE(rlhs);
2114 rrhs = (short *)MALLOC((unsigned)(nrules + 1) * sizeof(short));
2115 NO_SPACE(rrhs);
2117 rprec = (short *)REALLOC(rprec, (unsigned)nrules * sizeof(short));
2118 NO_SPACE(rprec);
2120 rassoc = REALLOC(rassoc, nrules);
2121 NO_SPACE(rassoc);
2123 ritem[0] = -1;
2124 ritem[1] = goal->index;
2125 ritem[2] = 0;
2126 ritem[3] = -2;
2127 rlhs[0] = 0;
2128 rlhs[1] = 0;
2129 rlhs[2] = start_symbol;
2130 rrhs[0] = 0;
2131 rrhs[1] = 0;
2132 rrhs[2] = 1;
2134 j = 4;
2135 for (i = 3; i < nrules; ++i)
2137 rlhs[i] = plhs[i]->index;
2138 rrhs[i] = j;
2139 assoc = TOKEN;
2140 prec2 = 0;
2141 while (pitem[j])
2143 ritem[j] = pitem[j]->index;
2144 if (pitem[j]->class == TERM)
2146 prec2 = pitem[j]->prec;
2147 assoc = pitem[j]->assoc;
2149 ++j;
2151 ritem[j] = (Value_t) - i;
2152 ++j;
2153 if (rprec[i] == UNDEFINED)
2155 rprec[i] = prec2;
2156 rassoc[i] = assoc;
2159 rrhs[i] = j;
2161 FREE(plhs);
2162 FREE(pitem);
2165 static void
2166 print_grammar(void)
2168 int i, k;
2169 size_t j, spacing = 0;
2170 FILE *f = verbose_file;
2172 if (!vflag)
2173 return;
2175 k = 1;
2176 for (i = 2; i < nrules; ++i)
2178 if (rlhs[i] != rlhs[i - 1])
2180 if (i != 2)
2181 fprintf(f, "\n");
2182 fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
2183 spacing = strlen(symbol_name[rlhs[i]]) + 1;
2185 else
2187 fprintf(f, "%4d ", i - 2);
2188 j = spacing;
2189 while (j-- != 0)
2190 putc(' ', f);
2191 putc('|', f);
2194 while (ritem[k] >= 0)
2196 fprintf(f, " %s", symbol_name[ritem[k]]);
2197 ++k;
2199 ++k;
2200 putc('\n', f);
2204 void
2205 reader(void)
2207 write_section(code_file, banner);
2208 create_symbol_table();
2209 read_declarations();
2210 read_grammar();
2211 free_symbol_table();
2212 free_tags();
2213 pack_names();
2214 check_symbols();
2215 pack_symbols();
2216 pack_grammar();
2217 free_symbols();
2218 print_grammar();
2221 #ifdef NO_LEAKS
2222 static param *
2223 free_declarations(param * list)
2225 while (list != 0)
2227 param *next = list->next;
2228 free(list->type);
2229 free(list->name);
2230 free(list->type2);
2231 free(list);
2232 list = next;
2234 return list;
2237 void
2238 reader_leaks(void)
2240 lex_param = free_declarations(lex_param);
2241 parse_param = free_declarations(parse_param);
2243 DO_FREE(line);
2244 DO_FREE(rrhs);
2245 DO_FREE(rlhs);
2246 DO_FREE(rprec);
2247 DO_FREE(ritem);
2248 DO_FREE(rassoc);
2249 DO_FREE(cache);
2250 DO_FREE(name_pool);
2251 DO_FREE(symbol_name);
2252 DO_FREE(symbol_prec);
2253 DO_FREE(symbol_assoc);
2254 DO_FREE(symbol_value);
2256 #endif