1 /* $Id: reader.c,v 1.79 2020/03/30 23:54:13 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 static void start_rule(bucket *bp, int s_lineno);
25 static void copy_initial_action(void);
26 static void copy_destructor(void);
27 static char *process_destructor_XX(char *code, char *tag);
30 #define CACHE_SIZE 256
32 static int cinc, cache_size;
35 static int tagmax, havetags;
36 static char **tag_table;
46 static char last_was_action;
48 static int trialaction;
52 static bucket **pitem;
57 static size_t name_pool_size;
58 static char *name_pool;
60 char line_format[] = "#line %d \"%s\"\n";
65 static const char *code_keys[] =
67 "", "requires", "provides", "top", "imports",
70 struct code_lines code_lines[CODE_MAX];
73 int destructor = 0; /* =1 if at least one %destructor */
75 static bucket *default_destructor[3] =
78 #define UNTYPED_DEFAULT 0
79 #define TYPED_DEFAULT 1
80 #define TYPE_SPECIFIED 2
83 lookup_type_destructor(char *tag)
85 const char fmt[] = "%.*s destructor";
86 char name[1024] = "\0";
87 bucket *bp, **bpp = &default_destructor[TYPE_SPECIFIED];
89 while ((bp = *bpp) != NULL)
96 sprintf(name, fmt, (int)(sizeof(name) - sizeof(fmt)), tag);
97 *bpp = bp = make_bucket(name);
102 #endif /* defined(YYBTYACC) */
108 if (cinc >= cache_size)
110 cache_size += CACHE_SIZE;
111 cache = TREALLOC(char, cache, cache_size);
114 cache[cinc] = (char)c;
133 * Expect this pattern:
134 * /^[[:space:]]*#[[:space:]]*
137 * ([[:space:]]*|[[:space:]]+"[^"]+")/
142 #define UNLESS(what) if (what) { ld = ldERR; break; }
147 LINE_DIR ld = ldSPC1;
148 for (n = 0; (ld <= ldOK) && (line[n] != '\0'); ++n)
150 int ch = UCH(line[n]);
154 if (isspace(UCH(ch)))
163 if (isspace(UCH(ch)))
169 UNLESS(strncmp(line + n, "line", 4));
177 UNLESS(!isspace(UCH(line[n])));
181 if (isspace(UCH(ch)))
186 UNLESS(!isdigit(UCH(ch)));
191 if (isdigit(UCH(ch)))
196 UNLESS(!isspace(UCH(ch)));
200 if (isspace(UCH(ch)))
206 UNLESS(line[n + 1] == '"');
226 size_t need = (size_t) (name_end - name_1st);
227 if ((long)need > (long)input_file_name_len)
229 input_file_name_len = ((need + 1) * 3) / 2;
230 input_file_name = TREALLOC(char, input_file_name, input_file_name_len);
231 NO_SPACE(input_file_name);
235 memcpy(input_file_name, line + name_1st + 1, need - 1);
236 input_file_name[need - 1] = '\0';
240 input_file_name[0] = '\0';
244 if (ld >= ldNUM && ld < ldERR)
248 lineno = (int)strtol(line + line_1st, NULL, 10) - 1;
263 FILE *f = input_file;
269 if (saw_eof || (c = getc(f)) == EOF)
281 if (line == NULL || linesize != (LINESIZE + 1))
285 linesize = LINESIZE + 1;
286 line = TMALLOC(char, linesize);
297 if ((i + 3) >= linesize)
299 linesize += LINESIZE;
300 line = TREALLOC(char, line, linesize);
313 while (line_directive());
328 p = TMALLOC(char, s - line + 1);
333 while ((*t++ = *s++) != '\n')
344 a.a_line = dup_line();
345 a.a_cptr = a.a_line + (cptr - line);
350 if (*s == '*' && s[1] == '/')
360 unterminated_comment(&a);
393 else if (s[1] == '/')
418 switch (ch = next_inline())
445 static struct keyword
451 { "binary", NONASSOC },
453 { "debug", XXXDEBUG },
454 #if defined(YYBTYACC)
455 { "destructor", DESTRUCTOR },
457 { "error-verbose",ERROR_VERBOSE },
458 { "expect", EXPECT },
459 { "expect-rr", EXPECT_RR },
461 #if defined(YYBTYACC)
462 { "initial-action", INITIAL_ACTION },
465 { "lex-param", LEX_PARAM },
466 #if defined(YYBTYACC)
467 { "locations", LOCATIONS },
469 { "nonassoc", NONASSOC },
470 { "parse-param", PARSE_PARAM },
471 { "pure-parser", PURE_PARSER },
476 { "token-table", TOKEN_TABLE },
479 { "yacc", POSIX_YACC },
484 compare_keys(const void *a, const void *b)
486 const struct keyword *p = (const struct keyword *)a;
487 const struct keyword *q = (const struct keyword *)b;
488 return strcmp(p->name, q->name);
510 else if (isdigit(UCH(c))
519 /* treat keywords spelled with '_' as if it were '-' */
530 if ((key = bsearch(cache, keywords,
531 sizeof(keywords) / sizeof(*key),
532 sizeof(*key), compare_keys)))
540 if (c == '%' || c == '\\')
551 syntax_error(lineno, line, t_cptr);
559 FILE *f = output_file;
565 syntax_error(lineno, line, cptr);
567 fprintf(f, "#ident \"");
587 copy_string(int quote)
589 struct mstring *temp = msnew();
593 a.a_line = dup_line();
594 a.a_cptr = a.a_line + (cptr - line - 1);
606 unterminated_string(&a);
615 unterminated_string(&a);
624 struct mstring *temp = msnew();
631 while ((c = *++cptr) != '\n')
634 if (c == '*' && cptr[1] == '/')
644 a.a_line = dup_line();
645 a.a_cptr = a.a_line + (cptr - line - 1);
653 if (c == '*' && *cptr == '/')
664 unterminated_comment(&a);
674 const char *key = code_keys[pos];
675 while (*cptr && *key)
676 if (*key++ != *cptr++)
678 if (*key || (!isspace(UCH(*cptr)) && *cptr != L_CURL))
691 int pos = CODE_HEADER;
692 struct mstring *code_mstr;
694 /* read %code <keyword> { */
706 if (pos == CODE_HEADER)
726 if (pos == -1 || !check_key(pos))
728 syntax_error(lineno, line, cptr);
734 cptr++; /* skip initial curl */
735 while (*cptr && isspace(UCH(*cptr))) /* skip space */
737 curl = 1; /* nesting count */
740 code_lines[pos].name = code_keys[pos];
741 if ((cline = (int)code_lines[pos].num) != 0)
743 code_mstr = msrenew(code_lines[pos].lines);
750 msprintf(code_mstr, line_format, lineno, input_file_name);
776 mputc(code_mstr, '\n');
779 code_lines[pos].lines = msdone(code_mstr);
780 code_lines[pos].num = (size_t) cline;
797 int need_newline = 0;
800 a.a_line = dup_line();
801 a.a_cptr = a.a_line + (cptr - line - 2);
807 unterminated_text(&a);
810 fprintf(f, line_format, lineno, input_file_name);
822 unterminated_text(&a);
828 char *s = copy_string(c);
838 char *s = copy_comment();
865 puts_both(const char *s)
869 fputs(s, union_file);
887 a.a_line = dup_line();
888 a.a_cptr = a.a_line + (cptr - line - 6);
891 over_unionized(cptr - 6);
894 puts_both("#ifdef YYSTYPE\n");
895 puts_both("#undef YYSTYPE_IS_DECLARED\n");
896 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
897 puts_both("#endif\n");
898 puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
899 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
902 fprintf(text_file, line_format, lineno, input_file_name);
903 puts_both("typedef union");
914 unterminated_union(&a);
924 puts_both(" YYSTYPE;\n");
925 puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
934 char *s = copy_string(c);
942 char *s = copy_comment();
954 after_blanks(char *s)
956 while (*s != '\0' && isspace(UCH(*s)))
962 * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
963 * single space. Return index to last character in the buffer.
966 trim_blanks(char *buffer)
971 char *s = after_blanks(d);
973 while ((*d++ = *s++) != '\0')
979 while ((--d != buffer) && isspace(UCH(*d)))
982 for (s = d = buffer; (*d++ = *s++) != '\0';)
984 if (isspace(UCH(*s)))
987 while (isspace(UCH(*s)))
996 return (int)strlen(buffer) - 1;
1000 * Scan forward in the current line-buffer looking for a right-curly bracket.
1002 * Parameters begin with a left-curly bracket, and continue until there are no
1003 * more interesting characters after the last right-curly bracket on the
1004 * current line. Bison documents parameters as separated like this:
1005 * {type param1} {type2 param2}
1006 * but also accepts commas (although some versions of bison mishandle this)
1007 * {type param1, type2 param2}
1017 switch (next_inline())
1036 save_param(int k, char *buffer, int name, int type2)
1040 p = TMALLOC(param, 1);
1043 p->type2 = strdup(buffer + type2);
1045 buffer[type2] = '\0';
1046 (void)trim_blanks(p->type2);
1048 p->name = strdup(buffer + name);
1050 buffer[name] = '\0';
1051 (void)trim_blanks(p->name);
1053 p->type = strdup(buffer);
1055 (void)trim_blanks(p->type);
1079 * Keep a linked list of parameters. This may be multi-line, if the trailing
1080 * right-curly bracket is absent.
1090 size_t buf_size = 0;
1091 int st_lineno = lineno;
1125 if ((curly == 1) && (cptr == line))
1135 if (curly == 0 && !isspace(UCH(c)))
1143 buf_size = (size_t) linesize;
1144 buf = TMALLOC(char, buf_size);
1152 buf_size += (size_t) linesize;
1153 buf = TREALLOC(char, buf, buf_size);
1158 if ((state == 2) && (c == L_CURL))
1162 else if ((state == 2) && isspace(UCH(c)))
1166 else if ((c != L_CURL) && (c != R_CURL))
1173 while (curly < 2 || more_curly());
1186 (void)trim_blanks(buf);
1191 char *parms = (comma + 1);
1192 comma = strchr(parms, ',');
1196 (void)trim_blanks(parms);
1197 i = (int)strlen(parms) - 1;
1203 if (parms[i] == ']')
1206 while (i >= 0 && level > 0 && parms[i] != '[')
1208 if (parms[i] == ']')
1210 else if (parms[i] == '[')
1223 while (i > 0 && (isalnum(UCH(parms[i])) || UCH(parms[i]) == '_'))
1226 if (!isspace(UCH(parms[i])) && parms[i] != '*')
1231 save_param(k, parms, name, type2);
1239 syntax_error(lineno, line, cptr);
1245 if (c >= '0' && c <= '9')
1247 if (c >= 'A' && c <= 'F')
1248 return (c - 'A' + 10);
1249 if (c >= 'a' && c <= 'f')
1250 return (c - 'a' + 10);
1263 a.a_lineno = lineno;
1264 a.a_line = dup_line();
1265 a.a_cptr = a.a_line + (cptr - line);
1275 unterminated_string(&a);
1278 char *c_cptr = cptr - 1;
1286 unterminated_string(&a);
1301 n = (n << 3) + (c - '0');
1305 n = (n << 3) + (c - '0');
1310 illegal_character(c_cptr);
1317 if (n < 0 || n >= 16)
1318 illegal_character(c_cptr);
1323 if (i < 0 || i >= 16)
1328 illegal_character(c_cptr);
1361 s = TMALLOC(char, n);
1364 for (i = 0; i < n; ++i)
1373 for (i = 0; i < n; ++i)
1376 if (c == '\\' || c == cache[0])
1381 else if (isprint(UCH(c)))
1410 cachec(((c >> 6) & 7) + '0');
1411 cachec(((c >> 3) & 7) + '0');
1412 cachec((c & 7) + '0');
1426 if (n == 1 && bp->value == UNDEFINED)
1427 bp->value = UCH(*s);
1434 is_reserved(char *name)
1438 if (strcmp(name, ".") == 0 ||
1439 strcmp(name, "$accept") == 0 ||
1440 strcmp(name, "$end") == 0)
1443 if (name[0] == '$' && name[1] == '$' && isdigit(UCH(name[2])))
1446 while (isdigit(UCH(*s)))
1461 for (c = *cptr; IS_IDENT(c); c = *++cptr)
1465 if (is_reserved(cache))
1466 used_reserved(cache);
1468 return (lookup(cache));
1479 for (c = *cptr; isdigit(UCH(c)); c = *++cptr)
1481 n = (10 * n + (c - '0'));
1484 syntax_error(lineno, line, base);
1489 return (Value_t)(n);
1493 cache_tag(char *tag, size_t len)
1498 for (i = 0; i < ntags; ++i)
1500 if (strncmp(tag, tag_table[i], len) == 0 &&
1501 tag_table[i][len] == NUL)
1502 return (tag_table[i]);
1505 if (ntags >= tagmax)
1510 ? TREALLOC(char *, tag_table, tagmax)
1511 : TMALLOC(char *, tagmax));
1512 NO_SPACE(tag_table);
1515 s = TMALLOC(char, len + 1);
1518 strncpy(s, tag, len);
1520 tag_table[ntags++] = s;
1528 int t_lineno = lineno;
1529 char *t_line = dup_line();
1530 char *t_cptr = t_line + (cptr - line);
1537 illegal_tag(t_lineno, t_line, t_cptr);
1545 while (IS_IDENT(c));
1552 illegal_tag(t_lineno, t_line, t_cptr);
1557 return cache_tag(cache, (size_t) cinc);
1560 #if defined(YYBTYACC)
1566 while (IS_NAME2(UCH(*cptr)))
1568 return cache_tag(b, (size_t) (cptr - b));
1573 declare_tokens(int assoc)
1596 if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
1598 else if (c == '\'' || c == '"')
1604 tokenized_start(bp->name);
1609 if (bp->tag && tag != bp->tag)
1610 retyped_warning(bp->name);
1616 if (bp->prec && prec != bp->prec)
1617 reprec_warning(bp->name);
1618 bp->assoc = (Assoc_t)assoc;
1626 if (isdigit(UCH(c)))
1628 value = get_number();
1629 if (bp->value != UNDEFINED && value != bp->value)
1630 revalued_warning(bp->name);
1640 * %expect requires special handling
1641 * as it really isn't part of the yacc
1642 * grammar only a flag for yacc proper.
1645 declare_expect(int assoc)
1649 if (assoc != EXPECT && assoc != EXPECT_RR)
1653 * Stay away from nextc - doesn't
1654 * detect EOL and will read to EOF.
1662 if (isdigit(UCH(c)))
1664 if (assoc == EXPECT)
1665 SRexpect = get_number();
1667 RRexpect = get_number();
1671 * Looking for number before EOL.
1672 * Spaces, tabs, and numbers are ok,
1673 * words, punc., etc. are syntax errors.
1675 else if (c == '\n' || isalpha(UCH(c)) || !isspace(UCH(c)))
1677 syntax_error(lineno, line, cptr);
1688 #if defined(YYBTYACC)
1690 declare_argtypes(bucket *bp)
1692 char *tags[MAXARGS];
1696 retyped_warning(bp->name);
1697 cptr++; /* skip open paren */
1704 syntax_error(lineno, line, cptr);
1705 tags[args++] = get_tag();
1712 cptr++; /* skip close paren */
1714 bp->argnames = TMALLOC(char *, args);
1715 NO_SPACE(bp->argnames);
1716 bp->argtags = CALLOC(sizeof(char *), args + 1);
1717 NO_SPACE(bp->argtags);
1720 bp->argtags[args] = tags[args];
1721 bp->argnames[args] = NULL;
1744 if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
1747 #if defined(YYBTYACC)
1748 if (nextc() == L_PAREN)
1749 declare_argtypes(bp);
1754 else if (c == '\'' || c == '"')
1757 #if defined(YYBTYACC)
1766 if (bp->tag && tag != bp->tag)
1767 retyped_warning(bp->name);
1782 if (!isalpha(UCH(c)) && c != '_' && c != '.' && c != '$')
1783 syntax_error(lineno, line, cptr);
1785 if (bp->class == TERM)
1786 terminal_start(bp->name);
1787 if (goal && goal != bp)
1788 restarted_warning();
1793 read_declarations(void)
1797 cache_size = CACHE_SIZE;
1798 cache = TMALLOC(char, cache_size);
1807 syntax_error(lineno, line, cptr);
1808 switch (k = keyword())
1866 #if defined(YYBTYACC)
1875 case INITIAL_ACTION:
1876 copy_initial_action();
1885 /* noop for bison compatibility. byacc is already designed to be posix
1886 * yacc compatible. */
1893 initialize_grammar(void)
1898 pitem = TMALLOC(bucket *, maxitems);
1909 plhs = TMALLOC(bucket *, maxrules);
1916 rprec = TMALLOC(Value_t, maxrules);
1923 rassoc = TMALLOC(Assoc_t, maxrules);
1935 pitem = TREALLOC(bucket *, pitem, maxitems);
1944 plhs = TREALLOC(bucket *, plhs, maxrules);
1947 rprec = TREALLOC(Value_t, rprec, maxrules);
1950 rassoc = TREALLOC(Assoc_t, rassoc, maxrules);
1954 /* set immediately prior to where copy_args() could be called, and incremented by
1955 the various routines that will rescan the argument list as appropriate */
1956 static int rescan_lineno;
1957 #if defined(YYBTYACC)
1960 copy_args(int *alen)
1962 struct mstring *s = msnew();
1963 int depth = 0, len = 1;
1967 a.a_lineno = lineno;
1968 a.a_line = dup_line();
1969 a.a_cptr = a.a_line + (cptr - line - 1);
1971 while ((c = *cptr++) != R_PAREN || depth || quote)
1973 if (c == ',' && !quote && !depth)
1986 unterminated_string(&a);
1988 unterminated_arglist(&a);
2005 else if (c == R_PAREN)
2007 else if (c == '\"' || c == '\'')
2018 parse_id(char *p, char **save)
2022 while (isspace(UCH(*p)))
2025 if (!isalpha(UCH(*p)) && *p != '_')
2028 while (IS_NAME2(UCH(*p)))
2032 *save = cache_tag(b, (size_t) (p - b));
2038 parse_int(char *p, int *save)
2040 int neg = 0, val = 0;
2042 while (isspace(UCH(*p)))
2050 if (!isdigit(UCH(*p)))
2052 while (isdigit(UCH(*p)))
2053 val = val * 10 + *p++ - '0';
2062 parse_arginfo(bucket *a, char *args, int argslen)
2064 char *p = args, *tmp;
2069 if (a->args != argslen)
2070 arg_number_disagree_warning(rescan_lineno, a->name);
2075 if ((a->args = argslen) == 0)
2077 a->argnames = TMALLOC(char *, argslen);
2078 NO_SPACE(a->argnames);
2079 a->argtags = TMALLOC(char *, argslen);
2080 NO_SPACE(a->argtags);
2084 for (i = 0; i < argslen; i++)
2086 while (isspace(UCH(*p)))
2091 while (isspace(UCH(*p)))
2097 if (!(p = parse_id(p + 1, &tmp)))
2099 while (isspace(UCH(*p)))
2106 if (a->argtags[i] != tmp)
2107 arg_type_disagree_warning(rescan_lineno, i + 1, a->name);
2110 a->argtags[i] = tmp;
2113 a->argtags[i] = NULL;
2114 if (!(p = parse_id(p, &a->argnames[i])))
2116 while (isspace(UCH(*p)))
2126 compile_arg(char **theptr, char *yyvaltag)
2129 struct mstring *c = msnew();
2131 Value_t *offsets = NULL, maxoffset;
2136 for (i = nitems - 1; pitem[i]; --i)
2139 if (pitem[i]->class != ARGUMENT)
2144 offsets = TMALLOC(Value_t, maxoffset + 1);
2147 for (j = 0, i++; i < nitems; i++)
2148 if (pitem[i]->class != ARGUMENT)
2149 offsets[++j] = (Value_t)(i - nitems + 1);
2151 rhs = pitem + nitems - 1;
2154 msprintf(c, "yyval.%s = ", yyvaltag);
2156 msprintf(c, "yyval = ");
2163 if (!(p = parse_id(++p, &tag)) || *p++ != '>')
2164 illegal_tag(rescan_lineno, NULL, NULL);
2165 if (isdigit(UCH(*p)) || *p == '-')
2168 if (!(p = parse_int(p, &val)))
2169 dollar_error(rescan_lineno, NULL, NULL);
2172 else if (val > maxoffset)
2174 dollar_warning(rescan_lineno, val);
2175 i = val - maxoffset;
2177 else if (maxoffset > 0)
2180 if (!tag && !(tag = rhs[i]->tag) && havetags)
2181 untyped_rhs(val, rhs[i]->name);
2183 msprintf(c, "yystack.l_mark[%d]", i);
2185 msprintf(c, ".%s", tag);
2189 else if (isalpha(UCH(*p)) || *p == '_')
2192 if (!(p = parse_id(p, &arg)))
2193 dollar_error(rescan_lineno, NULL, NULL);
2194 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2195 if (arg == plhs[nrules]->argnames[i])
2198 unknown_arg_warning(rescan_lineno, "$", arg, NULL, NULL);
2200 tag = plhs[nrules]->argtags[i];
2201 msprintf(c, "yystack.l_mark[%d]",
2202 i - plhs[nrules]->args + 1 - n);
2204 msprintf(c, ".%s", tag);
2206 untyped_arg_warning(rescan_lineno, "$", arg);
2209 dollar_error(rescan_lineno, NULL, NULL);
2213 at_error(rescan_lineno, NULL, NULL);
2229 can_elide_arg(char **theptr, char *yyvaltag)
2234 Value_t *offsets = NULL, maxoffset = 0;
2242 if (!(p = parse_id(++p, &tag)) || *p++ != '>')
2245 for (i = nitems - 1; pitem[i]; --i)
2248 if (pitem[i]->class != ARGUMENT)
2253 offsets = TMALLOC(Value_t, maxoffset + 1);
2256 for (j = 0, i++; i < nitems; i++)
2257 if (pitem[i]->class != ARGUMENT)
2258 offsets[++j] = (Value_t)(i - nitems + 1);
2260 rhs = pitem + nitems - 1;
2262 if (isdigit(UCH(*p)) || *p == '-')
2265 if (!(p = parse_int(p, &val)))
2271 else if (val > maxoffset)
2282 else if (isalpha(UCH(*p)) || *p == '_')
2285 if (!(p = parse_id(p, &arg)))
2290 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2291 if (arg == plhs[nrules]->argnames[i])
2296 tag = plhs[nrules]->argtags[i];
2297 rv = plhs[nrules]->args + n - i;
2300 if (tag && yyvaltag)
2302 if (strcmp(tag, yyvaltag))
2305 else if (tag || yyvaltag)
2309 if (p == 0 || *p || rv <= 0)
2315 #define ARG_CACHE_SIZE 1024
2316 static struct arg_cache
2318 struct arg_cache *next;
2322 *arg_cache[ARG_CACHE_SIZE];
2325 lookup_arg_cache(char *code)
2327 struct arg_cache *entry;
2329 entry = arg_cache[strnshash(code) % ARG_CACHE_SIZE];
2332 if (!strnscmp(entry->code, code))
2334 entry = entry->next;
2340 insert_arg_cache(char *code, int rule)
2342 struct arg_cache *entry = NEW(struct arg_cache);
2346 i = strnshash(code) % ARG_CACHE_SIZE;
2349 entry->next = arg_cache[i];
2350 arg_cache[i] = entry;
2354 clean_arg_cache(void)
2356 struct arg_cache *e, *t;
2359 for (i = 0; i < ARG_CACHE_SIZE; i++)
2361 for (e = arg_cache[i]; (t = e); e = e->next, FREE(t))
2363 arg_cache[i] = NULL;
2366 #endif /* defined(YYBTYACC) */
2369 advance_to_start(void)
2375 #if defined(YYBTYACC)
2404 syntax_error(lineno, line, s_cptr);
2409 if (!isalpha(UCH(c)) && c != '_' && c != '.' && c != '_')
2410 syntax_error(lineno, line, cptr);
2414 if (bp->class == TERM)
2415 terminal_start(bp->name);
2423 rescan_lineno = lineno; /* line# for possible inherited args rescan */
2424 #if defined(YYBTYACC)
2428 args = copy_args(&argslen);
2434 syntax_error(lineno, line, cptr);
2435 start_rule(bp, s_lineno);
2436 #if defined(YYBTYACC)
2437 parse_arginfo(bp, args, argslen);
2443 start_rule(bucket *bp, int s_lineno)
2445 if (bp->class == TERM)
2446 terminal_lhs(s_lineno);
2447 bp->class = NONTERM;
2450 if (nrules >= maxrules)
2453 rprec[nrules] = UNDEFINED;
2454 rassoc[nrules] = TOKEN;
2462 if (!last_was_action && plhs[nrules]->tag)
2464 if (pitem[nitems - 1])
2466 for (i = nitems - 1; (i > 0) && pitem[i]; --i)
2468 if (pitem[i + 1] == 0 || pitem[i + 1]->tag != plhs[nrules]->tag)
2469 default_action_warning(plhs[nrules]->name);
2472 default_action_warning(plhs[nrules]->name);
2475 last_was_action = 0;
2476 if (nitems >= maxitems)
2484 insert_empty_rule(void)
2489 assert(cache_size >= CACHE_SIZE);
2490 sprintf(cache, "$$%d", ++gensym);
2491 bp = make_bucket(cache);
2492 last_symbol->next = bp;
2494 bp->tag = plhs[nrules]->tag;
2496 #if defined(YYBTYACC)
2500 nitems = (Value_t)(nitems + 2);
2501 if (nitems > maxitems)
2503 bpp = pitem + nitems - 1;
2505 while ((bpp[0] = bpp[-1]) != 0)
2508 if (++nrules >= maxrules)
2510 plhs[nrules] = plhs[nrules - 1];
2511 plhs[nrules - 1] = bp;
2512 rprec[nrules] = rprec[nrules - 1];
2513 rprec[nrules - 1] = 0;
2514 rassoc[nrules] = rassoc[nrules - 1];
2515 rassoc[nrules - 1] = TOKEN;
2518 #if defined(YYBTYACC)
2520 insert_arg_rule(char *arg, char *tag)
2522 int line_number = rescan_lineno;
2523 char *code = compile_arg(&arg, tag);
2524 int rule = lookup_arg_cache(code);
2525 FILE *f = action_file;
2530 insert_arg_cache(code, rule);
2531 trialaction = 1; /* arg rules always run in trial mode */
2532 fprintf(f, "case %d:\n", rule - 2);
2534 fprintf(f, line_format, line_number, input_file_name);
2535 fprintf(f, "%s;\n", code);
2536 fprintf(f, "break;\n");
2537 insert_empty_rule();
2538 plhs[rule]->tag = cache_tag(tag, strlen(tag));
2539 plhs[rule]->class = ARGUMENT;
2543 if (++nitems > maxitems)
2545 pitem[nitems - 1] = plhs[rule];
2557 int s_lineno = lineno;
2558 #if defined(YYBTYACC)
2564 if (c == '\'' || c == '"')
2570 rescan_lineno = lineno; /* line# for possible inherited args rescan */
2571 #if defined(YYBTYACC)
2575 args = copy_args(&argslen);
2583 start_rule(bp, s_lineno);
2584 #if defined(YYBTYACC)
2585 parse_arginfo(bp, args, argslen);
2591 if (last_was_action)
2592 insert_empty_rule();
2593 last_was_action = 0;
2595 #if defined(YYBTYACC)
2598 if (argslen == 0 && bp->args > 0 && pitem[nitems - 1] == NULL)
2601 if (plhs[nrules]->args != bp->args)
2602 wrong_number_args_warning("default ", bp->name);
2603 for (i = bp->args - 1; i >= 0; i--)
2604 if (plhs[nrules]->argtags[i] != bp->argtags[i])
2605 wrong_type_for_arg_warning(i + 1, bp->name);
2607 else if (bp->args != argslen)
2608 wrong_number_args_warning("", bp->name);
2613 int elide_cnt = can_elide_arg(&ap, bp->argtags[0]);
2615 if (elide_cnt > argslen)
2619 for (i = 1; i < elide_cnt; i++)
2620 if (can_elide_arg(&ap, bp->argtags[i]) != elide_cnt - i)
2628 assert(i == elide_cnt);
2635 for (; i < argslen; i++)
2636 ap = insert_arg_rule(ap, bp->argtags[i]);
2639 #endif /* defined(YYBTYACC) */
2641 if (++nitems > maxitems)
2643 pitem[nitems - 1] = bp;
2652 #if defined(YYBTYACC)
2656 FILE *f = action_file;
2658 Value_t *offsets = NULL, maxoffset;
2661 a.a_lineno = lineno;
2662 a.a_line = dup_line();
2663 a.a_cptr = a.a_line + (cptr - line);
2665 if (last_was_action)
2666 insert_empty_rule();
2667 last_was_action = 1;
2668 #if defined(YYBTYACC)
2669 trialaction = (*cptr == L_BRAC);
2672 fprintf(f, "case %d:\n", nrules - 2);
2673 #if defined(YYBTYACC)
2677 fprintf(f, " if (!yytrial)\n");
2681 fprintf(f, line_format, lineno, input_file_name);
2685 /* avoid putting curly-braces in first column, to ease editing */
2686 if (*after_blanks(cptr) == L_CURL)
2689 cptr = after_blanks(cptr);
2694 for (i = nitems - 1; pitem[i]; --i)
2697 if (pitem[i]->class != ARGUMENT)
2702 offsets = TMALLOC(Value_t, maxoffset + 1);
2705 for (j = 0, i++; i < nitems; i++)
2707 if (pitem[i]->class != ARGUMENT)
2709 offsets[++j] = (Value_t)(i - nitems + 1);
2713 rhs = pitem + nitems - 1;
2722 int d_lineno = lineno;
2723 char *d_line = dup_line();
2724 char *d_cptr = d_line + (cptr - line);
2731 fprintf(f, "yyval.%s", tag);
2736 else if (isdigit(UCH(c)))
2740 fprintf(f, "yystack.l_mark[%d].%s", -n, tag);
2741 else if (i > maxoffset)
2743 dollar_warning(d_lineno, i);
2744 fprintf(f, "yystack.l_mark[%d].%s", i - maxoffset, tag);
2747 fprintf(f, "yystack.l_mark[%d].%s", offsets[i], tag);
2751 else if (c == '-' && isdigit(UCH(cptr[1])))
2754 i = -get_number() - n;
2755 fprintf(f, "yystack.l_mark[%d].%s", i, tag);
2759 #if defined(YYBTYACC)
2760 else if (isalpha(UCH(c)) || c == '_')
2762 char *arg = scan_id();
2763 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2764 if (arg == plhs[nrules]->argnames[i])
2767 unknown_arg_warning(d_lineno, "$", arg, d_line, d_cptr);
2768 fprintf(f, "yystack.l_mark[%d].%s",
2769 i - plhs[nrules]->args + 1 - n, tag);
2775 dollar_error(d_lineno, d_line, d_cptr);
2777 else if (cptr[1] == '$')
2781 tag = plhs[nrules]->tag;
2784 fprintf(f, "yyval.%s", tag);
2787 fprintf(f, "yyval");
2789 #if defined(YYBTYACC)
2794 else if (isdigit(UCH(cptr[1])))
2798 if (havetags && offsets)
2800 if (i <= 0 || i > maxoffset)
2802 tag = rhs[offsets[i]]->tag;
2804 untyped_rhs(i, rhs[offsets[i]]->name);
2805 fprintf(f, "yystack.l_mark[%d].%s", offsets[i], tag);
2810 fprintf(f, "yystack.l_mark[%d]", -n);
2811 else if (i > maxoffset)
2813 dollar_warning(lineno, i);
2814 fprintf(f, "yystack.l_mark[%d]", i - maxoffset);
2817 fprintf(f, "yystack.l_mark[%d]", offsets[i]);
2821 else if (cptr[1] == '-')
2827 fprintf(f, "yystack.l_mark[%d]", -i - n);
2830 #if defined(YYBTYACC)
2831 else if (isalpha(UCH(cptr[1])) || cptr[1] == '_')
2836 for (i = plhs[nrules]->args - 1; i >= 0; i--)
2837 if (arg == plhs[nrules]->argnames[i])
2840 unknown_arg_warning(lineno, "$", arg, line, cptr);
2841 tag = (i < 0 ? NULL : plhs[nrules]->argtags[i]);
2842 fprintf(f, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1 - n);
2844 fprintf(f, ".%s", tag);
2846 untyped_arg_warning(lineno, "$", arg);
2851 #if defined(YYBTYACC)
2856 int l_lineno = lineno;
2857 char *l_line = dup_line();
2858 char *l_cptr = l_line + (cptr - line);
2859 syntax_error(l_lineno, l_line, l_cptr);
2863 fprintf(f, "yyloc");
2867 else if (isdigit(UCH(cptr[1])))
2872 fprintf(f, "yystack.p_mark[%d]", -n);
2873 else if (i > maxoffset)
2875 at_warning(lineno, i);
2876 fprintf(f, "yystack.p_mark[%d]", i - maxoffset);
2879 fprintf(f, "yystack.p_mark[%d]", offsets[i]);
2882 else if (cptr[1] == '-')
2886 fprintf(f, "yystack.p_mark[%d]", -i - n);
2898 while (IS_NAME2(c));
2902 #if defined(YYBTYACC)
2905 if (trialaction && c == L_BRAC && depth == 0)
2911 if (trialaction && c == R_BRAC && depth == 1)
2916 if (c == L_BRAC && !haveyyval)
2920 if (c == L_CURL && !haveyyval)
2922 fprintf(f, " if (!yytrial)\n");
2924 fprintf(f, line_format, lineno, input_file_name);
2928 fprintf(f, "\nbreak;\n");
2943 unterminated_action(&a);
2948 fprintf(f, "\nbreak;\n");
2954 #if defined(YYBTYACC)
2973 #if defined(YYBTYACC)
2977 if (c == L_BRAC && !haveyyval)
2982 if (c == L_CURL && !haveyyval)
2984 fprintf(f, " if (!yytrial)\n");
2986 fprintf(f, line_format, lineno, input_file_name);
2991 fprintf(f, "\nbreak;\n");
3000 char *s = copy_string(c);
3008 char *s = copy_comment();
3019 #if defined(YYBTYACC)
3021 get_code(struct ainfo *a, const char *loc)
3026 struct mstring *code_mstr = msnew();
3029 msprintf(code_mstr, line_format, lineno, input_file_name);
3031 cptr = after_blanks(cptr);
3032 if (*cptr == L_CURL)
3033 /* avoid putting curly-braces in first column, to ease editing */
3034 mputc(code_mstr, '\t');
3036 syntax_error(lineno, line, cptr);
3038 a->a_lineno = lineno;
3039 a->a_line = dup_line();
3040 a->a_cptr = a->a_line + (cptr - line);
3049 int d_lineno = lineno;
3050 char *d_line = dup_line();
3051 char *d_cptr = d_line + (cptr - line);
3058 msprintf(code_mstr, "(*val).%s", tag);
3064 dollar_error(d_lineno, d_line, d_cptr);
3066 else if (cptr[1] == '$')
3068 /* process '$$' later; replacement is context dependent */
3069 msprintf(code_mstr, "$$");
3074 if (c == '@' && cptr[1] == '$')
3078 int l_lineno = lineno;
3079 char *l_line = dup_line();
3080 char *l_cptr = l_line + (cptr - line);
3081 syntax_error(l_lineno, l_line, l_cptr);
3083 msprintf(code_mstr, "%s", loc);
3091 mputc(code_mstr, c);
3094 while (IS_NAME2(c));
3098 mputc(code_mstr, c);
3105 unterminated_action(a);
3119 char *s = copy_string(c);
3120 msprintf(code_mstr, "%s", s);
3127 char *s = copy_comment();
3128 msprintf(code_mstr, "%s", s);
3137 return msdone(code_mstr);
3141 copy_initial_action(void)
3145 initial_action = get_code(&a, "yyloc");
3150 copy_destructor(void)
3157 code_text = get_code(&a, "(*loc)");
3167 { /* "no semantic type" default destructor */
3169 if ((bp = default_destructor[UNTYPED_DEFAULT]) == NULL)
3171 static char untyped_default[] = "<>";
3172 bp = make_bucket("untyped default");
3173 bp->tag = untyped_default;
3174 default_destructor[UNTYPED_DEFAULT] = bp;
3176 if (bp->destructor != NULL)
3177 destructor_redeclared_warning(&a);
3179 /* replace "$$" with "(*val)" in destructor code */
3180 bp->destructor = process_destructor_XX(code_text, NULL);
3182 else if (cptr[1] == '*' && cptr[2] == '>')
3183 { /* "no per-symbol or per-type" default destructor */
3185 if ((bp = default_destructor[TYPED_DEFAULT]) == NULL)
3187 static char typed_default[] = "<*>";
3188 bp = make_bucket("typed default");
3189 bp->tag = typed_default;
3190 default_destructor[TYPED_DEFAULT] = bp;
3192 if (bp->destructor != NULL)
3193 destructor_redeclared_warning(&a);
3196 /* postpone re-processing destructor $$s until end of grammar spec */
3197 bp->destructor = TMALLOC(char, strlen(code_text) + 1);
3198 NO_SPACE(bp->destructor);
3199 strcpy(bp->destructor, code_text);
3203 { /* "semantic type" default destructor */
3204 char *tag = get_tag();
3205 bp = lookup_type_destructor(tag);
3206 if (bp->destructor != NULL)
3207 destructor_redeclared_warning(&a);
3209 /* replace "$$" with "(*val).tag" in destructor code */
3210 bp->destructor = process_destructor_XX(code_text, tag);
3213 else if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
3214 { /* "symbol" destructor */
3216 if (bp->destructor != NULL)
3217 destructor_redeclared_warning(&a);
3220 /* postpone re-processing destructor $$s until end of grammar spec */
3221 bp->destructor = TMALLOC(char, strlen(code_text) + 1);
3222 NO_SPACE(bp->destructor);
3223 strcpy(bp->destructor, code_text);
3234 process_destructor_XX(char *code, char *tag)
3239 struct mstring *new_code = msnew();
3240 char *codeptr = code;
3243 loop: /* step thru code */
3245 if (c == '$' && codeptr[1] == '$')
3249 msprintf(new_code, "(*val)");
3251 msprintf(new_code, "(*val).%s", tag);
3261 while (IS_NAME2(c));
3275 return msdone(new_code);
3303 if (c == '*' && *codeptr == '/')
3305 mputc(new_code, '/');
3317 #endif /* defined(YYBTYACC) */
3326 if (c == '%' || c == '\\')
3334 else if ((c == 'p' || c == 'P') &&
3335 ((c = cptr[2]) == 'r' || c == 'R') &&
3336 ((c = cptr[3]) == 'e' || c == 'E') &&
3337 ((c = cptr[4]) == 'c' || c == 'C') &&
3338 ((c = cptr[5], !IS_IDENT(c))))
3341 syntax_error(lineno, line, cptr);
3344 if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
3346 else if (c == '\'' || c == '"')
3350 syntax_error(lineno, line, cptr);
3354 if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
3357 rprec[nrules] = bp->prec;
3358 rassoc[nrules] = bp->assoc;
3367 initialize_grammar();
3382 #if defined(YYBTYACC)
3383 else if (c == L_CURL || c == '=' || (backtrack && c == L_BRAC))
3385 else if (c == L_CURL || c == '=')
3391 start_rule(plhs[nrules - 1], 0);
3400 syntax_error(lineno, line, cptr);
3403 #if defined(YYBTYACC)
3405 start_requires_args(goal->name);
3417 for (i = 0; i < ntags; ++i)
3419 assert(tag_table[i]);
3431 name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
3432 for (bp = first_symbol; bp; bp = bp->next)
3433 name_pool_size += strlen(bp->name) + 1;
3435 name_pool = TMALLOC(char, name_pool_size);
3436 NO_SPACE(name_pool);
3438 strcpy(name_pool, "$accept");
3439 strcpy(name_pool + 8, "$end");
3441 for (bp = first_symbol; bp; bp = bp->next)
3445 while ((*t++ = *s++) != 0)
3457 if (goal->class == UNKNOWN)
3458 undefined_goal(goal->name);
3460 for (bp = first_symbol; bp; bp = bp->next)
3462 if (bp->class == UNKNOWN)
3464 undefined_symbol_warning(bp->name);
3471 protect_string(char *src, char **des)
3484 if ('\\' == *s || '"' == *s)
3490 *des = d = TMALLOC(char, len);
3496 if ('\\' == *s || '"' == *s)
3510 #if defined(YYBTYACC)
3511 Value_t max_tok_pval;
3516 for (bp = first_symbol; bp; bp = bp->next)
3519 if (bp->class == TERM)
3522 start_symbol = (Value_t)ntokens;
3523 nvars = (Value_t)(nsyms - ntokens);
3525 symbol_name = TMALLOC(char *, nsyms);
3526 NO_SPACE(symbol_name);
3528 symbol_value = TMALLOC(Value_t, nsyms);
3529 NO_SPACE(symbol_value);
3531 symbol_prec = TMALLOC(Value_t, nsyms);
3532 NO_SPACE(symbol_prec);
3534 symbol_assoc = TMALLOC(char, nsyms);
3535 NO_SPACE(symbol_assoc);
3537 #if defined(YYBTYACC)
3538 symbol_pval = TMALLOC(Value_t, nsyms);
3539 NO_SPACE(symbol_pval);
3543 symbol_destructor = CALLOC(sizeof(char *), nsyms);
3544 NO_SPACE(symbol_destructor);
3546 symbol_type_tag = CALLOC(sizeof(char *), nsyms);
3547 NO_SPACE(symbol_type_tag);
3551 v = TMALLOC(bucket *, nsyms);
3555 v[start_symbol] = 0;
3558 j = (Value_t)(start_symbol + 1);
3559 for (bp = first_symbol; bp; bp = bp->next)
3561 if (bp->class == TERM)
3566 assert(i == ntokens && j == nsyms);
3568 for (i = 1; i < ntokens; ++i)
3571 goal->index = (Index_t)(start_symbol + 1);
3572 k = (Value_t)(start_symbol + 2);
3582 for (i = (Value_t)(start_symbol + 1); i < nsyms; ++i)
3592 for (i = 1; i < ntokens; ++i)
3597 for (j = k++; j > 0 && symbol_value[j - 1] > n; --j)
3598 symbol_value[j] = symbol_value[j - 1];
3599 symbol_value[j] = n;
3605 if (v[1]->value == UNDEFINED)
3610 for (i = 2; i < ntokens; ++i)
3612 if (v[i]->value == UNDEFINED)
3614 while (j < k && n == symbol_value[j])
3616 while (++j < k && n == symbol_value[j])
3625 symbol_name[0] = name_pool + 8;
3626 symbol_value[0] = 0;
3628 symbol_assoc[0] = TOKEN;
3629 #if defined(YYBTYACC)
3633 for (i = 1; i < ntokens; ++i)
3635 symbol_name[i] = v[i]->name;
3636 symbol_value[i] = v[i]->value;
3637 symbol_prec[i] = v[i]->prec;
3638 symbol_assoc[i] = v[i]->assoc;
3639 #if defined(YYBTYACC)
3640 symbol_pval[i] = v[i]->value;
3641 if (symbol_pval[i] > max_tok_pval)
3642 max_tok_pval = symbol_pval[i];
3645 symbol_destructor[i] = v[i]->destructor;
3646 symbol_type_tag[i] = v[i]->tag;
3650 symbol_name[start_symbol] = name_pool;
3651 symbol_value[start_symbol] = -1;
3652 symbol_prec[start_symbol] = 0;
3653 symbol_assoc[start_symbol] = TOKEN;
3654 #if defined(YYBTYACC)
3655 symbol_pval[start_symbol] = (Value_t)(max_tok_pval + 1);
3657 for (++i; i < nsyms; ++i)
3660 symbol_name[k] = v[i]->name;
3661 symbol_value[k] = v[i]->value;
3662 symbol_prec[k] = v[i]->prec;
3663 symbol_assoc[k] = v[i]->assoc;
3664 #if defined(YYBTYACC)
3665 symbol_pval[k] = (Value_t)((max_tok_pval + 1) + v[i]->value + 1);
3668 symbol_destructor[k] = v[i]->destructor;
3669 symbol_type_tag[k] = v[i]->tag;
3676 symbol_pname = TMALLOC(char *, nsyms);
3677 NO_SPACE(symbol_pname);
3679 for (i = 0; i < nsyms; ++i)
3680 protect_string(symbol_name[i], &(symbol_pname[i]));
3694 ritem = TMALLOC(Value_t, nitems);
3697 rlhs = TMALLOC(Value_t, nrules);
3700 rrhs = TMALLOC(Value_t, nrules + 1);
3703 rprec = TREALLOC(Value_t, rprec, nrules);
3706 rassoc = TREALLOC(Assoc_t, rassoc, nrules);
3710 ritem[1] = goal->index;
3715 rlhs[2] = start_symbol;
3721 for (i = 3; i < nrules; ++i)
3723 #if defined(YYBTYACC)
3724 if (plhs[i]->args > 0)
3726 if (plhs[i]->argnames)
3728 FREE(plhs[i]->argnames);
3729 plhs[i]->argnames = NULL;
3731 if (plhs[i]->argtags)
3733 FREE(plhs[i]->argtags);
3734 plhs[i]->argtags = NULL;
3737 #endif /* defined(YYBTYACC) */
3738 rlhs[i] = plhs[i]->index;
3744 ritem[j] = pitem[j]->index;
3745 if (pitem[j]->class == TERM)
3747 prec2 = pitem[j]->prec;
3748 assoc = pitem[j]->assoc;
3752 ritem[j] = (Value_t)-i;
3754 if (rprec[i] == UNDEFINED)
3764 #if defined(YYBTYACC)
3773 size_t j, spacing = 0;
3774 FILE *f = verbose_file;
3780 for (i = 2; i < nrules; ++i)
3782 if (rlhs[i] != rlhs[i - 1])
3786 fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
3787 spacing = strlen(symbol_name[rlhs[i]]) + 1;
3791 fprintf(f, "%4d ", i - 2);
3798 while (ritem[k] >= 0)
3800 fprintf(f, " %s", symbol_name[ritem[k]]);
3808 #if defined(YYBTYACC)
3810 finalize_destructors(void)
3816 for (i = 2; i < nsyms; ++i)
3818 tag = symbol_type_tag[i];
3819 if (symbol_destructor[i] == NULL)
3822 { /* use <> destructor, if there is one */
3823 if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
3825 symbol_destructor[i] = TMALLOC(char,
3826 strlen(bp->destructor) + 1);
3827 NO_SPACE(symbol_destructor[i]);
3828 strcpy(symbol_destructor[i], bp->destructor);
3832 { /* use type destructor for this tag, if there is one */
3833 bp = lookup_type_destructor(tag);
3834 if (bp->destructor != NULL)
3836 symbol_destructor[i] = TMALLOC(char,
3837 strlen(bp->destructor) + 1);
3838 NO_SPACE(symbol_destructor[i]);
3839 strcpy(symbol_destructor[i], bp->destructor);
3842 { /* use <*> destructor, if there is one */
3843 if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
3844 /* replace "$$" with "(*val).tag" in destructor code */
3845 symbol_destructor[i]
3846 = process_destructor_XX(bp->destructor, tag);
3851 { /* replace "$$" with "(*val)[.tag]" in destructor code */
3852 symbol_destructor[i]
3853 = process_destructor_XX(symbol_destructor[i], tag);
3856 /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
3857 DO_FREE(symbol_type_tag); /* no longer needed */
3858 if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
3861 /* 'bp->tag' is a static value, don't free */
3862 FREE(bp->destructor);
3865 if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
3868 /* 'bp->tag' is a static value, don't free */
3869 FREE(bp->destructor);
3872 if ((bp = default_destructor[TYPE_SPECIFIED]) != NULL)
3879 /* 'bp->tag' freed by 'free_tags()' */
3880 FREE(bp->destructor);
3885 #endif /* defined(YYBTYACC) */
3890 write_section(code_file, banner);
3891 create_symbol_table();
3892 read_declarations();
3894 free_symbol_table();
3901 #if defined(YYBTYACC)
3903 finalize_destructors();
3910 free_declarations(param *list)
3914 param *next = list->next;
3927 lex_param = free_declarations(lex_param);
3928 parse_param = free_declarations(parse_param);
3938 DO_FREE(symbol_name);
3939 DO_FREE(symbol_prec);
3940 DO_FREE(symbol_assoc);
3941 DO_FREE(symbol_value);
3942 #if defined(YYBTYACC)
3943 DO_FREE(symbol_pval);
3944 DO_FREE(symbol_destructor);
3945 DO_FREE(symbol_type_tag);