1 /* $Id: reader.c,v 1.90 2021/08/08 22:11:04 tom Exp $ */
5 /* The line size must be a positive integer. One hundred was chosen */
6 /* because few lines in Yacc input grammars exceed 100 characters. */
7 /* Note that if a line exceeds LINESIZE characters, the line buffer */
8 /* will be expanded to accommodate it. */
19 /* the maximum number of arguments (inherited attributes) to a non-terminal */
20 /* this is a hard limit, but seems more than adequate */
23 #define begin_case(f,n) fprintf(f, "case %d:\n", (int)(n))
27 fprintf_lineno(f, 1, ""); \
28 fprintf(f, "break;\n")
30 static void start_rule(bucket *bp, int s_lineno);
32 static void copy_initial_action(void);
33 static void copy_destructor(void);
34 static char *process_destructor_XX(char *code, char *tag);
37 #define CACHE_SIZE 256
39 static int cinc, cache_size;
42 static int tagmax, havetags;
43 static char **tag_table;
53 static char last_was_action;
55 static int trialaction;
59 static bucket **pitem;
64 static size_t name_pool_size;
65 static char *name_pool;
67 char line_format[] = "#line %d \"%s\"\n";
72 static const char *code_keys[] =
74 "", "requires", "provides", "top", "imports",
77 struct code_lines code_lines[CODE_MAX];
80 int destructor = 0; /* =1 if at least one %destructor */
82 static bucket *default_destructor[3] =
85 #define UNTYPED_DEFAULT 0
86 #define TYPED_DEFAULT 1
87 #define TYPE_SPECIFIED 2
90 lookup_type_destructor(char *tag)
92 const char fmt[] = "%.*s destructor";
93 char name[1024] = "\0";
94 bucket *bp, **bpp = &default_destructor[TYPE_SPECIFIED];
96 while ((bp = *bpp) != NULL)
103 sprintf(name, fmt, (int)(sizeof(name) - sizeof(fmt)), tag);
104 *bpp = bp = make_bucket(name);
109 #endif /* defined(YYBTYACC) */
115 if (cinc >= cache_size)
117 cache_size += CACHE_SIZE;
118 cache = TREALLOC(char, cache, cache_size);
121 cache[cinc] = (char)c;
140 * Expect this pattern:
141 * /^[[:space:]]*#[[:space:]]*
144 * ([[:space:]]*|[[:space:]]+"[^"]+")/
149 #define UNLESS(what) if (what) { ld = ldERR; break; }
154 LINE_DIR ld = ldSPC1;
155 for (n = 0; (ld <= ldOK) && (line[n] != '\0'); ++n)
157 int ch = UCH(line[n]);
161 if (isspace(UCH(ch)))
170 if (isspace(UCH(ch)))
176 UNLESS(strncmp(line + n, "line", 4));
184 UNLESS(!isspace(UCH(line[n])));
188 if (isspace(UCH(ch)))
193 UNLESS(!isdigit(UCH(ch)));
195 ld = ldNUM; /* this is needed, but cppcheck says no... */
198 if (isdigit(UCH(ch)))
203 UNLESS(!isspace(UCH(ch)));
207 if (isspace(UCH(ch)))
213 UNLESS(line[n + 1] == '"');
233 size_t need = (size_t)(name_end - name_1st);
234 if ((long)need > (long)input_file_name_len)
236 input_file_name_len = ((need + 1) * 3) / 2;
237 input_file_name = TREALLOC(char, input_file_name, input_file_name_len);
238 NO_SPACE(input_file_name);
242 memcpy(input_file_name, line + name_1st + 1, need - 1);
243 input_file_name[need - 1] = '\0';
247 input_file_name[0] = '\0';
251 if (ld >= ldNUM && ld < ldERR)
255 lineno = (int)strtol(line + line_1st, NULL, 10) - 1;
270 FILE *f = input_file;
277 if (saw_eof || (c = getc(f)) == EOF)
289 if (line == NULL || linesize != (LINESIZE + 1))
293 linesize = LINESIZE + 1;
294 line = TMALLOC(char, linesize);
305 if ((i + 3) >= linesize)
307 linesize += LINESIZE;
308 line = TREALLOC(char, line, linesize);
321 while (line_directive());
336 p = TMALLOC(char, s - line + 1);
341 while ((*t++ = *s++) != '\n')
352 a.a_line = dup_line();
353 a.a_cptr = a.a_line + (cptr - line);
358 if (*s == '*' && s[1] == '/')
368 unterminated_comment(&a);
401 else if (s[1] == '/')
426 switch (ch = next_inline())
453 static struct keyword
459 { "binary", NONASSOC },
461 { "debug", NONPOSIX_DEBUG },
462 #if defined(YYBTYACC)
463 { "destructor", DESTRUCTOR },
465 { "error-verbose",ERROR_VERBOSE },
466 { "expect", EXPECT },
467 { "expect-rr", EXPECT_RR },
469 #if defined(YYBTYACC)
470 { "initial-action", INITIAL_ACTION },
473 { "lex-param", LEX_PARAM },
474 #if defined(YYBTYACC)
475 { "locations", LOCATIONS },
477 { "nonassoc", NONASSOC },
478 { "parse-param", PARSE_PARAM },
479 { "pure-parser", PURE_PARSER },
484 { "token-table", TOKEN_TABLE },
487 { "yacc", POSIX_YACC },
492 compare_keys(const void *a, const void *b)
494 const struct keyword *p = (const struct keyword *)a;
495 const struct keyword *q = (const struct keyword *)b;
496 return strcmp(p->name, q->name);
519 else if (isdigit(UCH(c))
528 /* treat keywords spelled with '_' as if it were '-' */
539 if ((key = bsearch(cache, keywords,
540 sizeof(keywords) / sizeof(*key),
541 sizeof(*key), compare_keys)))
549 if (c == '%' || c == '\\')
560 syntax_error(lineno, line, t_cptr);
568 FILE *f = output_file;
574 syntax_error(lineno, line, cptr);
576 fprintf(f, "#ident \"");
596 copy_string(int quote)
598 struct mstring *temp = msnew();
601 a.a_line = dup_line();
602 a.a_cptr = a.a_line + (cptr - line - 1);
615 unterminated_string(&a);
624 unterminated_string(&a);
633 struct mstring *temp = msnew();
640 while ((c = *++cptr) != '\n')
643 if (c == '*' && cptr[1] == '/')
653 a.a_line = dup_line();
654 a.a_cptr = a.a_line + (cptr - line - 1);
662 if (c == '*' && *cptr == '/')
673 unterminated_comment(&a);
683 const char *key = code_keys[pos];
684 while (*cptr && *key)
685 if (*key++ != *cptr++)
687 if (*key || (!isspace(UCH(*cptr)) && *cptr != L_CURL))
700 int pos = CODE_HEADER;
701 struct mstring *code_mstr;
703 /* read %code <keyword> { */
715 if (pos == CODE_HEADER)
735 if (pos == -1 || !check_key(pos))
737 syntax_error(lineno, line, cptr);
743 cptr++; /* skip initial curl */
744 while (*cptr && isspace(UCH(*cptr))) /* skip space */
746 curl = 1; /* nesting count */
749 code_lines[pos].name = code_keys[pos];
750 if ((cline = (int)code_lines[pos].num) != 0)
752 code_mstr = msrenew(code_lines[pos].lines);
760 msprintf(code_mstr, line_format, lineno, input_file_name);
786 mputc(code_mstr, '\n');
789 code_lines[pos].lines = msdone(code_mstr);
790 code_lines[pos].num = (size_t)cline;
807 int need_newline = 0;
810 a.a_line = dup_line();
811 a.a_cptr = a.a_line + (cptr - line - 2);
817 unterminated_text(&a);
819 fprintf_lineno(f, lineno, input_file_name);
831 unterminated_text(&a);
837 char *s = copy_string(c);
847 char *s = copy_comment();
874 puts_both(const char *s)
878 fputs(s, union_file);
896 a.a_line = dup_line();
897 a.a_cptr = a.a_line + (cptr - line - 6);
900 over_unionized(cptr - 6);
903 puts_both("#ifdef YYSTYPE\n");
904 puts_both("#undef YYSTYPE_IS_DECLARED\n");
905 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
906 puts_both("#endif\n");
907 puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
908 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
910 fprintf_lineno(text_file, lineno, input_file_name);
911 puts_both("typedef union YYSTYPE");
922 unterminated_union(&a);
932 puts_both(" YYSTYPE;\n");
933 puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
942 char *s = copy_string(c);
950 char *s = copy_comment();
962 after_blanks(char *s)
964 while (*s != '\0' && isspace(UCH(*s)))
970 * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
971 * single space. Return index to last character in the buffer.
974 trim_blanks(char *buffer)
979 char *s = after_blanks(d);
981 while ((*d++ = *s++) != '\0')
987 while ((--d != buffer) && isspace(UCH(*d)))
990 for (s = d = buffer; (*d++ = *s++) != '\0';)
992 if (isspace(UCH(*s)))
995 while (isspace(UCH(*s)))
1004 return (int)strlen(buffer) - 1;
1008 * Scan forward in the current line-buffer looking for a right-curly bracket.
1010 * Parameters begin with a left-curly bracket, and continue until there are no
1011 * more interesting characters after the last right-curly bracket on the
1012 * current line. Bison documents parameters as separated like this:
1013 * {type param1} {type2 param2}
1014 * but also accepts commas (although some versions of bison mishandle this)
1015 * {type param1, type2 param2}
1025 switch (next_inline())
1044 save_param(int k, char *buffer, int name, int type2)
1048 p = TMALLOC(param, 1);
1051 p->type2 = strdup(buffer + type2);
1053 buffer[type2] = '\0';
1054 (void)trim_blanks(p->type2);
1056 p->name = strdup(buffer + name);
1058 buffer[name] = '\0';
1059 (void)trim_blanks(p->name);
1061 p->type = strdup(buffer);
1063 (void)trim_blanks(p->type);
1087 * Keep a linked list of parameters. This may be multi-line, if the trailing
1088 * right-curly bracket is absent.
1098 size_t buf_size = 0;
1099 int st_lineno = lineno;
1133 if ((curly == 1) && (cptr == line))
1143 if (curly == 0 && !isspace(UCH(c)))
1151 buf_size = (size_t)linesize;
1152 buf = TMALLOC(char, buf_size);
1163 buf_size += (size_t)linesize;
1164 tmp = TREALLOC(char, buf, buf_size);
1170 if ((state == 2) && (c == L_CURL))
1174 else if ((state == 2) && isspace(UCH(c)))
1178 else if ((c != L_CURL) && (c != R_CURL))
1185 while (curly < 2 || more_curly());
1198 (void)trim_blanks(buf);
1203 char *parms = (comma + 1);
1204 comma = strchr(parms, ',');
1208 (void)trim_blanks(parms);
1209 i = (int)strlen(parms) - 1;
1215 if (parms[i] == ']')
1220 char ch = parms[i--];
1243 while (i > 0 && (isalnum(UCH(parms[i])) || UCH(parms[i]) == '_'))
1246 if (!isspace(UCH(parms[i])) && parms[i] != '*')
1251 save_param(k, parms, name, type2);
1259 syntax_error(lineno, line, cptr);
1265 if (c >= '0' && c <= '9')
1267 if (c >= 'A' && c <= 'F')
1268 return (c - 'A' + 10);
1269 if (c >= 'a' && c <= 'f')
1270 return (c - 'a' + 10);
1283 a.a_lineno = lineno;
1284 a.a_line = dup_line();
1285 a.a_cptr = a.a_line + (cptr - line);
1295 unterminated_string(&a);
1298 char *c_cptr = cptr - 1;
1306 unterminated_string(&a);
1321 n = (n << 3) + (c - '0');
1325 n = (n << 3) + (c - '0');
1330 illegal_character(c_cptr);
1337 if (n < 0 || n >= 16)
1338 illegal_character(c_cptr);
1343 if (i < 0 || i >= 16)
1348 illegal_character(c_cptr);
1381 s = TMALLOC(char, n);
1384 for (i = 0; i < n; ++i)
1393 for (i = 0; i < n; ++i)
1396 if (c == '\\' || c == cache[0])
1401 else if (isprint(UCH(c)))
1430 cachec(((c >> 6) & 7) + '0');
1431 cachec(((c >> 3) & 7) + '0');
1432 cachec((c & 7) + '0');
1446 if (n == 1 && bp->value == UNDEFINED)
1447 bp->value = UCH(*s);
1454 is_reserved(char *name)
1456 if (strcmp(name, ".") == 0 ||
1457 strcmp(name, "$accept") == 0 ||
1458 strcmp(name, "$end") == 0)
1461 if (name[0] == '$' && name[1] == '$' && isdigit(UCH(name[2])))
1465 while (isdigit(UCH(*s)))
1480 for (c = *cptr; IS_IDENT(c); c = *++cptr)
1484 if (is_reserved(cache))
1485 used_reserved(cache);
1487 return (lookup(cache));
1498 for (c = *cptr; isdigit(UCH(c)); c = *++cptr)
1500 n = (10 * n + (c - '0'));
1503 syntax_error(lineno, line, base);
1508 return (Value_t)(n);
1512 cache_tag(char *tag, size_t len)
1517 for (i = 0; i < ntags; ++i)
1519 if (strncmp(tag, tag_table[i], len) == 0 &&
1520 tag_table[i][len] == NUL)
1521 return (tag_table[i]);
1524 if (ntags >= tagmax)
1529 ? TREALLOC(char *, tag_table, tagmax)
1530 : TMALLOC(char *, tagmax));
1531 NO_SPACE(tag_table);
1534 s = TMALLOC(char, len + 1);
1537 strncpy(s, tag, len);
1539 tag_table[ntags++] = s;
1547 int t_lineno = lineno;
1548 char *t_line = dup_line();
1549 char *t_cptr = t_line + (cptr - line);
1556 illegal_tag(t_lineno, t_line, t_cptr);
1564 while (IS_IDENT(c));
1571 illegal_tag(t_lineno, t_line, t_cptr);
1576 return cache_tag(cache, (size_t)cinc);
1579 #if defined(YYBTYACC)
1585 while (IS_NAME2(UCH(*cptr)))
1587 return cache_tag(b, (size_t)(cptr - b));
1592 declare_tokens(int assoc)
1615 if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
1617 else if (c == '\'' || c == '"')
1623 tokenized_start(bp->name);
1628 if (bp->tag && tag != bp->tag)
1629 retyped_warning(bp->name);
1635 if (bp->prec && prec != bp->prec)
1636 reprec_warning(bp->name);
1637 bp->assoc = (Assoc_t)assoc;
1645 if (isdigit(UCH(c)))
1647 value = get_number();
1648 if (bp->value != UNDEFINED && value != bp->value)
1649 revalued_warning(bp->name);
1659 * %expect requires special handling
1660 * as it really isn't part of the yacc
1661 * grammar only a flag for yacc proper.
1664 declare_expect(int assoc)
1668 if (assoc != EXPECT && assoc != EXPECT_RR)
1672 * Stay away from nextc - doesn't
1673 * detect EOL and will read to EOF.
1681 if (isdigit(UCH(c)))
1683 if (assoc == EXPECT)
1684 SRexpect = get_number();
1686 RRexpect = get_number();
1690 * Looking for number before EOL.
1691 * Spaces, tabs, and numbers are ok,
1692 * words, punc., etc. are syntax errors.
1694 else if (c == '\n' || isalpha(UCH(c)) || !isspace(UCH(c)))
1696 syntax_error(lineno, line, cptr);
1707 #if defined(YYBTYACC)
1709 declare_argtypes(bucket *bp)
1711 char *tags[MAXARGS];
1715 retyped_warning(bp->name);
1716 cptr++; /* skip open paren */
1723 syntax_error(lineno, line, cptr);
1724 tags[args++] = get_tag();
1731 cptr++; /* skip close paren */
1733 bp->argnames = TMALLOC(char *, args);
1734 NO_SPACE(bp->argnames);
1735 bp->argtags = CALLOC(sizeof(char *), args + 1);
1736 NO_SPACE(bp->argtags);
1739 bp->argtags[args] = tags[args];
1740 bp->argnames[args] = NULL;
1763 if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
1766 #if defined(YYBTYACC)
1767 if (nextc() == L_PAREN)
1768 declare_argtypes(bp);
1773 else if (c == '\'' || c == '"')
1776 #if defined(YYBTYACC)
1785 if (bp->tag && tag != bp->tag)
1786 retyped_warning(bp->name);
1801 if (!isalpha(UCH(c)) && c != '_' && c != '.' && c != '$')
1802 syntax_error(lineno, line, cptr);
1804 if (bp->class == TERM)
1805 terminal_start(bp->name);
1806 if (goal && goal != bp)
1807 restarted_warning();
1812 read_declarations(void)
1814 cache_size = CACHE_SIZE;
1815 cache = TMALLOC(char, cache_size);
1826 syntax_error(lineno, line, cptr);
1827 switch (k = keyword())
1885 #if defined(YYBTYACC)
1894 case INITIAL_ACTION:
1895 copy_initial_action();
1899 case NONPOSIX_DEBUG:
1904 /* noop for bison compatibility. byacc is already designed to be posix
1905 * yacc compatible. */
1912 initialize_grammar(void)
1917 pitem = TMALLOC(bucket *, maxitems);
1928 plhs = TMALLOC(bucket *, maxrules);
1935 rprec = TMALLOC(Value_t, maxrules);
1942 rassoc = TMALLOC(Assoc_t, maxrules);
1954 pitem = TREALLOC(bucket *, pitem, maxitems);
1963 plhs = TREALLOC(bucket *, plhs, maxrules);
1966 rprec = TREALLOC(Value_t, rprec, maxrules);
1969 rassoc = TREALLOC(Assoc_t, rassoc, maxrules);
1973 /* set immediately prior to where copy_args() could be called, and incremented by
1974 the various routines that will rescan the argument list as appropriate */
1975 static int rescan_lineno;
1976 #if defined(YYBTYACC)
1979 copy_args(int *alen)
1981 struct mstring *s = msnew();
1982 int depth = 0, len = 1;
1986 a.a_lineno = lineno;
1987 a.a_line = dup_line();
1988 a.a_cptr = a.a_line + (cptr - line - 1);
1990 while ((c = *cptr++) != R_PAREN || depth || quote)
1992 if (c == ',' && !quote && !depth)
2005 unterminated_string(&a);
2007 unterminated_arglist(&a);
2024 else if (c == R_PAREN)
2026 else if (c == '\"' || c == '\'')
2037 parse_id(char *p, char **save)
2041 while (isspace(UCH(*p)))
2044 if (!isalpha(UCH(*p)) && *p != '_')
2047 while (IS_NAME2(UCH(*p)))
2051 *save = cache_tag(b, (size_t)(p - b));
2057 parse_int(char *p, int *save)
2059 int neg = 0, val = 0;
2061 while (isspace(UCH(*p)))
2069 if (!isdigit(UCH(*p)))
2071 while (isdigit(UCH(*p)))
2072 val = val * 10 + *p++ - '0';
2081 parse_arginfo(bucket *a, char *args, int argslen)
2083 char *p = args, *tmp;
2088 if (a->args != argslen)
2089 arg_number_disagree_warning(rescan_lineno, a->name);
2094 if ((a->args = argslen) == 0)
2096 a->argnames = TMALLOC(char *, argslen);
2097 NO_SPACE(a->argnames);
2098 a->argtags = TMALLOC(char *, argslen);
2099 NO_SPACE(a->argtags);
2103 for (i = 0; i < argslen; i++)
2105 while (isspace(UCH(*p)))
2110 while (isspace(UCH(*p)))
2116 if (!(p = parse_id(p + 1, &tmp)))
2118 while (isspace(UCH(*p)))
2125 if (a->argtags[i] != tmp)
2126 arg_type_disagree_warning(rescan_lineno, i + 1, a->name);
2129 a->argtags[i] = tmp;
2132 a->argtags[i] = NULL;
2133 if (!(p = parse_id(p, &a->argnames[i])))
2135 while (isspace(UCH(*p)))
2145 compile_arg(char **theptr, char *yyvaltag)
2148 struct mstring *c = msnew();
2150 Value_t *offsets = NULL, maxoffset;
2155 for (i = nitems - 1; pitem[i]; --i)
2158 if (pitem[i]->class != ARGUMENT)
2165 offsets = TMALLOC(Value_t, maxoffset + 1);
2168 for (j = 0, i++; i < nitems; i++)
2169 if (pitem[i]->class != ARGUMENT)
2170 offsets[++j] = (Value_t)(i - nitems + 1);
2172 rhs = pitem + nitems - 1;
2175 msprintf(c, "yyval.%s = ", yyvaltag);
2177 msprintf(c, "yyval = ");
2184 if (!(p = parse_id(++p, &tag)) || *p++ != '>')
2185 illegal_tag(rescan_lineno, NULL, NULL);
2186 if (isdigit(UCH(*p)) || *p == '-')
2189 if (!(p = parse_int(p, &val)))
2190 dollar_error(rescan_lineno, NULL, NULL);
2193 else if (val > maxoffset)
2195 dollar_warning(rescan_lineno, val);
2196 i = val - maxoffset;
2198 else if (maxoffset > 0)
2201 if (!tag && !(tag = rhs[i]->tag) && havetags)
2202 untyped_rhs(val, rhs[i]->name);
2204 msprintf(c, "yystack.l_mark[%d]", i);
2206 msprintf(c, ".%s", tag);
2210 else if (isalpha(UCH(*p)) || *p == '_')
2213 if (!(p = parse_id(p, &arg)))
2214 dollar_error(rescan_lineno, NULL, NULL);
2215 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2216 if (arg == plhs[nrules]->argnames[i])
2219 unknown_arg_warning(rescan_lineno, "$", arg, NULL, NULL);
2221 tag = plhs[nrules]->argtags[i];
2222 msprintf(c, "yystack.l_mark[%d]",
2223 i - plhs[nrules]->args + 1 - n);
2225 msprintf(c, ".%s", tag);
2227 untyped_arg_warning(rescan_lineno, "$", arg);
2230 dollar_error(rescan_lineno, NULL, NULL);
2234 at_error(rescan_lineno, NULL, NULL);
2250 can_elide_arg(char **theptr, char *yyvaltag)
2255 Value_t *offsets = NULL, maxoffset = 0;
2263 if (!(p = parse_id(++p, &tag)) || *p++ != '>')
2266 for (i = nitems - 1; pitem[i]; --i)
2269 if (pitem[i]->class != ARGUMENT)
2276 offsets = TMALLOC(Value_t, maxoffset + 1);
2279 for (j = 0, i++; i < nitems; i++)
2280 if (pitem[i]->class != ARGUMENT)
2281 offsets[++j] = (Value_t)(i - nitems + 1);
2283 rhs = pitem + nitems - 1;
2285 if (isdigit(UCH(*p)) || *p == '-')
2288 if (!(p = parse_int(p, &val)))
2294 else if (val > maxoffset)
2305 else if (isalpha(UCH(*p)) || *p == '_')
2308 if (!(p = parse_id(p, &arg)))
2313 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2314 if (arg == plhs[nrules]->argnames[i])
2319 tag = plhs[nrules]->argtags[i];
2320 rv = plhs[nrules]->args + n - i;
2323 if (tag && yyvaltag)
2325 if (strcmp(tag, yyvaltag))
2328 else if (tag || yyvaltag)
2332 if (p == 0 || *p || rv <= 0)
2338 #define ARG_CACHE_SIZE 1024
2339 static struct arg_cache
2341 struct arg_cache *next;
2345 *arg_cache[ARG_CACHE_SIZE];
2348 lookup_arg_cache(char *code)
2350 struct arg_cache *entry;
2352 entry = arg_cache[strnshash(code) % ARG_CACHE_SIZE];
2355 if (!strnscmp(entry->code, code))
2357 entry = entry->next;
2363 insert_arg_cache(char *code, int rule)
2365 struct arg_cache *entry = NEW(struct arg_cache);
2369 i = strnshash(code) % ARG_CACHE_SIZE;
2372 entry->next = arg_cache[i];
2373 arg_cache[i] = entry;
2377 clean_arg_cache(void)
2379 struct arg_cache *e, *t;
2382 for (i = 0; i < ARG_CACHE_SIZE; i++)
2384 for (e = arg_cache[i]; (t = e); e = e->next, FREE(t))
2386 arg_cache[i] = NULL;
2389 #endif /* defined(YYBTYACC) */
2392 advance_to_start(void)
2397 #if defined(YYBTYACC)
2428 syntax_error(lineno, line, s_cptr);
2433 if (!isalpha(UCH(c)) && c != '_' && c != '.' && c != '_')
2434 syntax_error(lineno, line, cptr);
2438 if (bp->class == TERM)
2439 terminal_start(bp->name);
2447 rescan_lineno = lineno; /* line# for possible inherited args rescan */
2448 #if defined(YYBTYACC)
2452 args = copy_args(&argslen);
2458 syntax_error(lineno, line, cptr);
2459 start_rule(bp, s_lineno);
2460 #if defined(YYBTYACC)
2461 parse_arginfo(bp, args, argslen);
2467 start_rule(bucket *bp, int s_lineno)
2469 if (bp->class == TERM)
2470 terminal_lhs(s_lineno);
2471 bp->class = NONTERM;
2474 if (nrules >= maxrules)
2477 rprec[nrules] = UNDEFINED;
2478 rassoc[nrules] = TOKEN;
2484 if (!last_was_action && plhs[nrules]->tag)
2486 if (pitem[nitems - 1])
2490 for (i = nitems - 1; (i > 0) && pitem[i]; --i)
2492 if (pitem[i + 1] == 0 || pitem[i + 1]->tag != plhs[nrules]->tag)
2493 default_action_warning(plhs[nrules]->name);
2496 default_action_warning(plhs[nrules]->name);
2499 last_was_action = 0;
2500 if (nitems >= maxitems)
2508 insert_empty_rule(void)
2513 assert(cache_size >= CACHE_SIZE);
2514 sprintf(cache, "$$%d", ++gensym);
2515 bp = make_bucket(cache);
2516 last_symbol->next = bp;
2518 bp->tag = plhs[nrules]->tag;
2520 #if defined(YYBTYACC)
2524 nitems = (Value_t)(nitems + 2);
2525 if (nitems > maxitems)
2527 bpp = pitem + nitems - 1;
2529 while ((bpp[0] = bpp[-1]) != 0)
2532 if (++nrules >= maxrules)
2534 plhs[nrules] = plhs[nrules - 1];
2535 plhs[nrules - 1] = bp;
2536 rprec[nrules] = rprec[nrules - 1];
2537 rprec[nrules - 1] = 0;
2538 rassoc[nrules] = rassoc[nrules - 1];
2539 rassoc[nrules - 1] = TOKEN;
2542 #if defined(YYBTYACC)
2544 insert_arg_rule(char *arg, char *tag)
2546 int line_number = rescan_lineno;
2547 char *code = compile_arg(&arg, tag);
2548 int rule = lookup_arg_cache(code);
2549 FILE *f = action_file;
2554 insert_arg_cache(code, rule);
2555 trialaction = 1; /* arg rules always run in trial mode */
2556 begin_case(f, rule - 2);
2557 fprintf_lineno(f, line_number, input_file_name);
2558 fprintf(f, "%s;", code);
2560 insert_empty_rule();
2561 plhs[rule]->tag = cache_tag(tag, strlen(tag));
2562 plhs[rule]->class = ARGUMENT;
2566 if (++nitems > maxitems)
2568 pitem[nitems - 1] = plhs[rule];
2580 int s_lineno = lineno;
2581 #if defined(YYBTYACC)
2587 if (c == '\'' || c == '"')
2593 rescan_lineno = lineno; /* line# for possible inherited args rescan */
2594 #if defined(YYBTYACC)
2598 args = copy_args(&argslen);
2606 start_rule(bp, s_lineno);
2607 #if defined(YYBTYACC)
2608 parse_arginfo(bp, args, argslen);
2614 if (last_was_action)
2615 insert_empty_rule();
2616 last_was_action = 0;
2618 #if defined(YYBTYACC)
2621 if (argslen == 0 && bp->args > 0 && pitem[nitems - 1] == NULL)
2624 if (plhs[nrules]->args != bp->args)
2625 wrong_number_args_warning("default ", bp->name);
2626 for (i = bp->args - 1; i >= 0; i--)
2627 if (plhs[nrules]->argtags[i] != bp->argtags[i])
2628 wrong_type_for_arg_warning(i + 1, bp->name);
2630 else if (bp->args != argslen)
2631 wrong_number_args_warning("", bp->name);
2636 int elide_cnt = can_elide_arg(&ap, bp->argtags[0]);
2638 if (elide_cnt > argslen)
2642 for (i = 1; i < elide_cnt; i++)
2643 if (can_elide_arg(&ap, bp->argtags[i]) != elide_cnt - i)
2651 assert(i == elide_cnt);
2658 for (; i < argslen; i++)
2659 ap = insert_arg_rule(ap, bp->argtags[i]);
2662 #endif /* defined(YYBTYACC) */
2664 if (++nitems > maxitems)
2666 pitem[nitems - 1] = bp;
2675 #if defined(YYBTYACC)
2679 FILE *f = action_file;
2681 Value_t *offsets = NULL, maxoffset;
2684 a.a_lineno = lineno;
2685 a.a_line = dup_line();
2686 a.a_cptr = a.a_line + (cptr - line);
2688 if (last_was_action)
2689 insert_empty_rule();
2690 last_was_action = 1;
2691 #if defined(YYBTYACC)
2692 trialaction = (*cptr == L_BRAC);
2695 begin_case(f, nrules - 2);
2696 #if defined(YYBTYACC)
2700 fprintf(f, " if (!yytrial)\n");
2703 fprintf_lineno(f, lineno, input_file_name);
2707 /* avoid putting curly-braces in first column, to ease editing */
2708 if (*after_blanks(cptr) == L_CURL)
2711 cptr = after_blanks(cptr);
2716 for (i = nitems - 1; pitem[i]; --i)
2719 if (pitem[i]->class != ARGUMENT)
2724 offsets = TMALLOC(Value_t, maxoffset + 1);
2727 for (j = 0, i++; i < nitems; i++)
2729 if (pitem[i]->class != ARGUMENT)
2731 offsets[++j] = (Value_t)(i - nitems + 1);
2735 rhs = pitem + nitems - 1;
2744 int d_lineno = lineno;
2745 char *d_line = dup_line();
2746 char *d_cptr = d_line + (cptr - line);
2753 fprintf(f, "yyval.%s", tag);
2758 else if (isdigit(UCH(c)))
2762 fprintf(f, "yystack.l_mark[%d].%s", -n, tag);
2763 else if (i > maxoffset)
2765 dollar_warning(d_lineno, i);
2766 fprintf(f, "yystack.l_mark[%ld].%s",
2767 (long)(i - maxoffset), tag);
2770 fprintf(f, "yystack.l_mark[%ld].%s",
2771 (long)offsets[i], tag);
2775 else if (c == '-' && isdigit(UCH(cptr[1])))
2778 i = -get_number() - n;
2779 fprintf(f, "yystack.l_mark[%d].%s", i, tag);
2783 #if defined(YYBTYACC)
2784 else if (isalpha(UCH(c)) || c == '_')
2786 char *arg = scan_id();
2787 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2788 if (arg == plhs[nrules]->argnames[i])
2791 unknown_arg_warning(d_lineno, "$", arg, d_line, d_cptr);
2792 fprintf(f, "yystack.l_mark[%d].%s",
2793 i - plhs[nrules]->args + 1 - n, tag);
2799 dollar_error(d_lineno, d_line, d_cptr);
2801 else if (cptr[1] == '$')
2805 tag = plhs[nrules]->tag;
2808 fprintf(f, "yyval.%s", tag);
2811 fprintf(f, "yyval");
2813 #if defined(YYBTYACC)
2818 else if (isdigit(UCH(cptr[1])))
2822 if (havetags && offsets)
2824 if (i <= 0 || i > maxoffset)
2826 tag = rhs[offsets[i]]->tag;
2828 untyped_rhs(i, rhs[offsets[i]]->name);
2829 fprintf(f, "yystack.l_mark[%ld].%s", (long)offsets[i], tag);
2834 fprintf(f, "yystack.l_mark[%d]", -n);
2835 else if (i > maxoffset)
2837 dollar_warning(lineno, i);
2838 fprintf(f, "yystack.l_mark[%ld]", (long)(i - maxoffset));
2841 fprintf(f, "yystack.l_mark[%ld]", (long)offsets[i]);
2845 else if (cptr[1] == '-')
2851 fprintf(f, "yystack.l_mark[%d]", -i - n);
2854 #if defined(YYBTYACC)
2855 else if (isalpha(UCH(cptr[1])) || cptr[1] == '_')
2860 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2861 if (arg == plhs[nrules]->argnames[i])
2864 unknown_arg_warning(lineno, "$", arg, line, cptr);
2865 tag = (i < 0 ? NULL : plhs[nrules]->argtags[i]);
2866 fprintf(f, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1 - n);
2868 fprintf(f, ".%s", tag);
2870 untyped_arg_warning(lineno, "$", arg);
2875 #if defined(YYBTYACC)
2880 int l_lineno = lineno;
2881 char *l_line = dup_line();
2882 char *l_cptr = l_line + (cptr - line);
2883 syntax_error(l_lineno, l_line, l_cptr);
2887 fprintf(f, "yyloc");
2891 else if (isdigit(UCH(cptr[1])))
2896 fprintf(f, "yystack.p_mark[%d]", -n);
2897 else if (i > maxoffset)
2899 at_warning(lineno, i);
2900 fprintf(f, "yystack.p_mark[%d]", i - maxoffset);
2903 fprintf(f, "yystack.p_mark[%d]", offsets[i]);
2906 else if (cptr[1] == '-')
2910 fprintf(f, "yystack.p_mark[%d]", -i - n);
2922 while (IS_NAME2(c));
2926 #if defined(YYBTYACC)
2929 if (trialaction && c == L_BRAC && depth == 0)
2935 if (trialaction && c == R_BRAC && depth == 1)
2940 if (c == L_BRAC && !haveyyval)
2944 if (c == L_CURL && !haveyyval)
2946 fprintf(f, " if (!yytrial)\n");
2947 fprintf_lineno(f, lineno, input_file_name);
2966 unterminated_action(&a);
2977 #if defined(YYBTYACC)
2996 #if defined(YYBTYACC)
3000 if (c == L_BRAC && !haveyyval)
3005 if (c == L_CURL && !haveyyval)
3007 fprintf(f, " if (!yytrial)\n");
3008 fprintf_lineno(f, lineno, input_file_name);
3022 char *s = copy_string(c);
3030 char *s = copy_comment();
3041 #if defined(YYBTYACC)
3043 get_code(struct ainfo *a, const char *loc)
3048 struct mstring *code_mstr = msnew();
3051 msprintf(code_mstr, line_format, lineno, input_file_name);
3053 cptr = after_blanks(cptr);
3054 if (*cptr == L_CURL)
3055 /* avoid putting curly-braces in first column, to ease editing */
3056 mputc(code_mstr, '\t');
3058 syntax_error(lineno, line, cptr);
3060 a->a_lineno = lineno;
3061 a->a_line = dup_line();
3062 a->a_cptr = a->a_line + (cptr - line);
3071 int d_lineno = lineno;
3072 char *d_line = dup_line();
3073 char *d_cptr = d_line + (cptr - line);
3080 msprintf(code_mstr, "(*val).%s", tag);
3086 dollar_error(d_lineno, d_line, d_cptr);
3088 else if (cptr[1] == '$')
3090 /* process '$$' later; replacement is context dependent */
3091 msprintf(code_mstr, "$$");
3096 if (c == '@' && cptr[1] == '$')
3100 int l_lineno = lineno;
3101 char *l_line = dup_line();
3102 char *l_cptr = l_line + (cptr - line);
3103 syntax_error(l_lineno, l_line, l_cptr);
3105 msprintf(code_mstr, "%s", loc);
3113 mputc(code_mstr, c);
3116 while (IS_NAME2(c));
3120 mputc(code_mstr, c);
3127 unterminated_action(a);
3141 char *s = copy_string(c);
3142 msprintf(code_mstr, "%s", s);
3149 char *s = copy_comment();
3150 msprintf(code_mstr, "%s", s);
3159 return msdone(code_mstr);
3163 copy_initial_action(void)
3167 initial_action = get_code(&a, "yyloc");
3172 copy_destructor(void)
3178 code_text = get_code(&a, "(*loc)");
3188 { /* "no semantic type" default destructor */
3190 if ((bp = default_destructor[UNTYPED_DEFAULT]) == NULL)
3192 static char untyped_default[] = "<>";
3193 bp = make_bucket("untyped default");
3194 bp->tag = untyped_default;
3195 default_destructor[UNTYPED_DEFAULT] = bp;
3197 if (bp->destructor != NULL)
3198 destructor_redeclared_warning(&a);
3200 /* replace "$$" with "(*val)" in destructor code */
3201 bp->destructor = process_destructor_XX(code_text, NULL);
3203 else if (cptr[1] == '*' && cptr[2] == '>')
3204 { /* "no per-symbol or per-type" default destructor */
3206 if ((bp = default_destructor[TYPED_DEFAULT]) == NULL)
3208 static char typed_default[] = "<*>";
3209 bp = make_bucket("typed default");
3210 bp->tag = typed_default;
3211 default_destructor[TYPED_DEFAULT] = bp;
3213 if (bp->destructor != NULL)
3214 destructor_redeclared_warning(&a);
3217 /* postpone re-processing destructor $$s until end of grammar spec */
3218 bp->destructor = TMALLOC(char, strlen(code_text) + 1);
3219 NO_SPACE(bp->destructor);
3220 strcpy(bp->destructor, code_text);
3224 { /* "semantic type" default destructor */
3225 char *tag = get_tag();
3226 bp = lookup_type_destructor(tag);
3227 if (bp->destructor != NULL)
3228 destructor_redeclared_warning(&a);
3230 /* replace "$$" with "(*val).tag" in destructor code */
3231 bp->destructor = process_destructor_XX(code_text, tag);
3234 else if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
3235 { /* "symbol" destructor */
3237 if (bp->destructor != NULL)
3238 destructor_redeclared_warning(&a);
3241 /* postpone re-processing destructor $$s until end of grammar spec */
3242 bp->destructor = TMALLOC(char, strlen(code_text) + 1);
3243 NO_SPACE(bp->destructor);
3244 strcpy(bp->destructor, code_text);
3255 process_destructor_XX(char *code, char *tag)
3260 struct mstring *new_code = msnew();
3261 char *codeptr = code;
3264 loop: /* step thru code */
3266 if (c == '$' && codeptr[1] == '$')
3270 msprintf(new_code, "(*val)");
3272 msprintf(new_code, "(*val).%s", tag);
3282 while (IS_NAME2(c));
3296 return msdone(new_code);
3324 if (c == '*' && *codeptr == '/')
3326 mputc(new_code, '/');
3338 #endif /* defined(YYBTYACC) */
3347 if (c == '%' || c == '\\')
3355 else if ((c == 'p' || c == 'P') &&
3356 ((c = cptr[2]) == 'r' || c == 'R') &&
3357 ((c = cptr[3]) == 'e' || c == 'E') &&
3358 ((c = cptr[4]) == 'c' || c == 'C') &&
3359 ((c = cptr[5], !IS_IDENT(c))))
3361 else if ((c == 'e' || c == 'E') &&
3362 ((c = cptr[2]) == 'm' || c == 'M') &&
3363 ((c = cptr[3]) == 'p' || c == 'P') &&
3364 ((c = cptr[4]) == 't' || c == 'T') &&
3365 ((c = cptr[5]) == 'y' || c == 'Y') &&
3366 ((c = cptr[6], !IS_IDENT(c))))
3372 syntax_error(lineno, line, cptr);
3375 if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
3377 else if (c == '\'' || c == '"')
3381 syntax_error(lineno, line, cptr);
3385 if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
3388 rprec[nrules] = bp->prec;
3389 rassoc[nrules] = bp->assoc;
3396 initialize_grammar();
3414 else if (c == L_CURL || c == '='
3415 #if defined(YYBTYACC)
3416 || (backtrack && c == L_BRAC)
3425 start_rule(plhs[nrules - 1], 0);
3434 syntax_error(lineno, line, cptr);
3437 #if defined(YYBTYACC)
3439 start_requires_args(goal->name);
3451 for (i = 0; i < ntags; ++i)
3453 assert(tag_table[i]);
3466 name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
3467 for (bp = first_symbol; bp; bp = bp->next)
3468 name_pool_size += strlen(bp->name) + 1;
3470 name_pool = TMALLOC(char, name_pool_size);
3471 NO_SPACE(name_pool);
3473 strcpy(name_pool, "$accept");
3474 strcpy(name_pool + 8, "$end");
3476 for (bp = first_symbol; bp; bp = bp->next)
3481 while ((*t++ = *s++) != 0)
3493 if (goal->class == UNKNOWN)
3494 undefined_goal(goal->name);
3496 for (bp = first_symbol; bp; bp = bp->next)
3498 if (bp->class == UNKNOWN)
3500 undefined_symbol_warning(bp->name);
3507 protect_string(char *src, char **des)
3520 if ('\\' == *s || '"' == *s)
3526 *des = d = TMALLOC(char, len);
3532 if ('\\' == *s || '"' == *s)
3546 #if defined(YYBTYACC)
3547 Value_t max_tok_pval;
3552 for (bp = first_symbol; bp; bp = bp->next)
3555 if (bp->class == TERM)
3558 start_symbol = (Value_t)ntokens;
3559 nvars = (Value_t)(nsyms - ntokens);
3561 symbol_name = TMALLOC(char *, nsyms);
3562 NO_SPACE(symbol_name);
3564 symbol_value = TMALLOC(Value_t, nsyms);
3565 NO_SPACE(symbol_value);
3567 symbol_prec = TMALLOC(Value_t, nsyms);
3568 NO_SPACE(symbol_prec);
3570 symbol_assoc = TMALLOC(char, nsyms);
3571 NO_SPACE(symbol_assoc);
3573 #if defined(YYBTYACC)
3574 symbol_pval = TMALLOC(Value_t, nsyms);
3575 NO_SPACE(symbol_pval);
3579 symbol_destructor = CALLOC(sizeof(char *), nsyms);
3580 NO_SPACE(symbol_destructor);
3582 symbol_type_tag = CALLOC(sizeof(char *), nsyms);
3583 NO_SPACE(symbol_type_tag);
3587 v = TMALLOC(bucket *, nsyms);
3591 v[start_symbol] = 0;
3594 j = (Value_t)(start_symbol + 1);
3595 for (bp = first_symbol; bp; bp = bp->next)
3597 if (bp->class == TERM)
3602 assert(i == ntokens && j == nsyms);
3604 for (i = 1; i < ntokens; ++i)
3607 goal->index = (Index_t)(start_symbol + 1);
3608 k = (Value_t)(start_symbol + 2);
3618 for (i = (Value_t)(start_symbol + 1); i < nsyms; ++i)
3628 for (i = 1; i < ntokens; ++i)
3633 for (j = k++; j > 0 && symbol_value[j - 1] > n; --j)
3634 symbol_value[j] = symbol_value[j - 1];
3635 symbol_value[j] = n;
3641 if (v[1]->value == UNDEFINED)
3646 for (i = 2; i < ntokens; ++i)
3648 if (v[i]->value == UNDEFINED)
3650 while (j < k && n == symbol_value[j])
3652 while (++j < k && n == symbol_value[j])
3661 symbol_name[0] = name_pool + 8;
3662 symbol_value[0] = 0;
3664 symbol_assoc[0] = TOKEN;
3665 #if defined(YYBTYACC)
3669 for (i = 1; i < ntokens; ++i)
3671 symbol_name[i] = v[i]->name;
3672 symbol_value[i] = v[i]->value;
3673 symbol_prec[i] = v[i]->prec;
3674 symbol_assoc[i] = v[i]->assoc;
3675 #if defined(YYBTYACC)
3676 symbol_pval[i] = v[i]->value;
3677 if (symbol_pval[i] > max_tok_pval)
3678 max_tok_pval = symbol_pval[i];
3681 symbol_destructor[i] = v[i]->destructor;
3682 symbol_type_tag[i] = v[i]->tag;
3686 symbol_name[start_symbol] = name_pool;
3687 symbol_value[start_symbol] = -1;
3688 symbol_prec[start_symbol] = 0;
3689 symbol_assoc[start_symbol] = TOKEN;
3690 #if defined(YYBTYACC)
3691 symbol_pval[start_symbol] = (Value_t)(max_tok_pval + 1);
3693 for (++i; i < nsyms; ++i)
3696 symbol_name[k] = v[i]->name;
3697 symbol_value[k] = v[i]->value;
3698 symbol_prec[k] = v[i]->prec;
3699 symbol_assoc[k] = v[i]->assoc;
3700 #if defined(YYBTYACC)
3701 symbol_pval[k] = (Value_t)((max_tok_pval + 1) + v[i]->value + 1);
3704 symbol_destructor[k] = v[i]->destructor;
3705 symbol_type_tag[k] = v[i]->tag;
3712 symbol_pname = TMALLOC(char *, nsyms);
3713 NO_SPACE(symbol_pname);
3715 for (i = 0; i < nsyms; ++i)
3716 protect_string(symbol_name[i], &(symbol_pname[i]));
3728 ritem = TMALLOC(Value_t, nitems);
3731 rlhs = TMALLOC(Value_t, nrules);
3734 rrhs = TMALLOC(Value_t, nrules + 1);
3737 rprec = TREALLOC(Value_t, rprec, nrules);
3740 rassoc = TREALLOC(Assoc_t, rassoc, nrules);
3744 ritem[1] = goal->index;
3749 rlhs[2] = start_symbol;
3755 for (i = 3; i < nrules; ++i)
3760 #if defined(YYBTYACC)
3761 if (plhs[i]->args > 0)
3763 if (plhs[i]->argnames)
3765 FREE(plhs[i]->argnames);
3766 plhs[i]->argnames = NULL;
3768 if (plhs[i]->argtags)
3770 FREE(plhs[i]->argtags);
3771 plhs[i]->argtags = NULL;
3774 #endif /* defined(YYBTYACC) */
3775 rlhs[i] = plhs[i]->index;
3781 ritem[j] = pitem[j]->index;
3782 if (pitem[j]->class == TERM)
3784 prec2 = pitem[j]->prec;
3785 assoc = pitem[j]->assoc;
3789 ritem[j] = (Value_t)-i;
3791 if (rprec[i] == UNDEFINED)
3801 #if defined(YYBTYACC)
3810 size_t j, spacing = 0;
3811 FILE *f = verbose_file;
3817 for (i = 2; i < nrules; ++i)
3819 if (rlhs[i] != rlhs[i - 1])
3823 fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
3824 spacing = strlen(symbol_name[rlhs[i]]) + 1;
3828 fprintf(f, "%4d ", i - 2);
3835 while (ritem[k] >= 0)
3837 fprintf(f, " %s", symbol_name[ritem[k]]);
3845 #if defined(YYBTYACC)
3847 finalize_destructors(void)
3852 for (i = 2; i < nsyms; ++i)
3854 char *tag = symbol_type_tag[i];
3856 if (symbol_destructor[i] == NULL)
3859 { /* use <> destructor, if there is one */
3860 if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
3862 symbol_destructor[i] = TMALLOC(char,
3863 strlen(bp->destructor) + 1);
3864 NO_SPACE(symbol_destructor[i]);
3865 strcpy(symbol_destructor[i], bp->destructor);
3869 { /* use type destructor for this tag, if there is one */
3870 bp = lookup_type_destructor(tag);
3871 if (bp->destructor != NULL)
3873 symbol_destructor[i] = TMALLOC(char,
3874 strlen(bp->destructor) + 1);
3875 NO_SPACE(symbol_destructor[i]);
3876 strcpy(symbol_destructor[i], bp->destructor);
3879 { /* use <*> destructor, if there is one */
3880 if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
3881 /* replace "$$" with "(*val).tag" in destructor code */
3882 symbol_destructor[i]
3883 = process_destructor_XX(bp->destructor, tag);
3888 { /* replace "$$" with "(*val)[.tag]" in destructor code */
3889 char *destructor_source = symbol_destructor[i];
3890 symbol_destructor[i]
3891 = process_destructor_XX(destructor_source, tag);
3892 FREE(destructor_source);
3895 /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
3896 DO_FREE(symbol_type_tag); /* no longer needed */
3897 if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
3900 /* 'bp->tag' is a static value, don't free */
3901 FREE(bp->destructor);
3904 if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
3907 /* 'bp->tag' is a static value, don't free */
3908 FREE(bp->destructor);
3911 if ((bp = default_destructor[TYPE_SPECIFIED]) != NULL)
3918 /* 'bp->tag' freed by 'free_tags()' */
3919 FREE(bp->destructor);
3924 #endif /* defined(YYBTYACC) */
3929 write_section(code_file, banner);
3930 create_symbol_table();
3931 read_declarations();
3933 free_symbol_table();
3940 #if defined(YYBTYACC)
3942 finalize_destructors();
3949 free_declarations(param *list)
3953 param *next = list->next;
3966 lex_param = free_declarations(lex_param);
3967 parse_param = free_declarations(parse_param);
3977 DO_FREE(symbol_name);
3978 DO_FREE(symbol_prec);
3979 DO_FREE(symbol_assoc);
3980 DO_FREE(symbol_value);
3981 #if defined(YYBTYACC)
3982 DO_FREE(symbol_pval);
3983 DO_FREE(symbol_destructor);
3984 DO_FREE(symbol_type_tag);