1 /* $Id: reader.c,v 1.58 2014/10/06 22:15:08 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 accomodate 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_destructor(void);
26 static char *process_destructor_XX(char *code
, char *tag
);
30 static int cinc
, cache_size
;
33 static int tagmax
, havetags
;
34 static char **tag_table
;
44 static char last_was_action
;
47 static bucket
**pitem
;
52 static size_t name_pool_size
;
53 static char *name_pool
;
55 char line_format
[] = "#line %d \"%s\"\n";
61 int destructor
= 0; /* =1 if at least one %destructor */
63 static bucket
*default_destructor
[3] =
66 #define UNTYPED_DEFAULT 0
67 #define TYPED_DEFAULT 1
68 #define TYPE_SPECIFIED 2
71 lookup_type_destructor(char *tag
)
73 const char fmt
[] = "%.*s destructor";
74 char name
[1024] = "\0";
75 bucket
*bp
, **bpp
= &default_destructor
[TYPE_SPECIFIED
];
77 while ((bp
= *bpp
) != NULL
)
84 sprintf(name
, fmt
, (int)(sizeof(name
) - sizeof(fmt
)), tag
);
85 *bpp
= bp
= make_bucket(name
);
90 #endif /* defined(YYBTYACC) */
96 if (cinc
>= cache_size
)
99 cache
= TREALLOC(char, cache
, cache_size
);
102 cache
[cinc
] = (char)c
;
109 FILE *f
= input_file
;
113 if (saw_eof
|| (c
= getc(f
)) == EOF
)
125 if (line
== 0 || linesize
!= (LINESIZE
+ 1))
129 linesize
= LINESIZE
+ 1;
130 line
= TMALLOC(char, linesize
);
141 if ((i
+ 3) >= linesize
)
143 linesize
+= LINESIZE
;
144 line
= TREALLOC(char, line
, linesize
);
170 p
= TMALLOC(char, s
- line
+ 1);
175 while ((*t
++ = *s
++) != '\n')
185 int st_lineno
= lineno
;
186 char *st_line
= dup_line();
187 char *st_cptr
= st_line
+ (cptr
- line
);
192 if (*s
== '*' && s
[1] == '/')
202 unterminated_comment(st_lineno
, st_line
, st_cptr
);
235 else if (s
[1] == '/')
260 switch (ch
= next_inline())
287 static struct keyword
293 { "binary", NONASSOC
},
294 #if defined(YYBTYACC)
295 { "destructor", DESTRUCTOR
},
297 { "expect", EXPECT
},
298 { "expect-rr", EXPECT_RR
},
301 { "lex-param", LEX_PARAM
},
302 #if defined(YYBTYACC)
303 { "locations", LOCATIONS
},
305 { "nonassoc", NONASSOC
},
306 { "parse-param", PARSE_PARAM
},
307 { "pure-parser", PURE_PARSER
},
312 { "token-table", TOKEN_TABLE
},
315 { "yacc", POSIX_YACC
},
320 compare_keys(const void *a
, const void *b
)
322 const struct keyword
*p
= (const struct keyword
*)a
;
323 const struct keyword
*q
= (const struct keyword
*)b
;
324 return strcmp(p
->name
, q
->name
);
355 /* treat keywords spelled with '_' as if it were '-' */
366 if ((key
= bsearch(cache
, keywords
,
367 sizeof(keywords
) / sizeof(*key
),
368 sizeof(*key
), compare_keys
)))
376 if (c
== '%' || c
== '\\')
387 syntax_error(lineno
, line
, t_cptr
);
394 FILE *f
= output_file
;
400 syntax_error(lineno
, line
, cptr
);
402 fprintf(f
, "#ident \"");
422 copy_string(int quote
)
424 struct mstring
*temp
= msnew();
426 int s_lineno
= lineno
;
427 char *s_line
= dup_line();
428 char *s_cptr
= s_line
+ (cptr
- line
- 1);
440 unterminated_string(s_lineno
, s_line
, s_cptr
);
449 unterminated_string(s_lineno
, s_line
, s_cptr
);
458 struct mstring
*temp
= msnew();
465 while ((c
= *++cptr
) != '\n')
468 if (c
== '*' && cptr
[1] == '/')
476 int c_lineno
= lineno
;
477 char *c_line
= dup_line();
478 char *c_cptr
= c_line
+ (cptr
- line
- 1);
486 if (c
== '*' && *cptr
== '/')
497 unterminated_comment(c_lineno
, c_line
, c_cptr
);
509 int need_newline
= 0;
510 int t_lineno
= lineno
;
511 char *t_line
= dup_line();
512 char *t_cptr
= t_line
+ (cptr
- line
- 2);
518 unterminated_text(t_lineno
, t_line
, t_cptr
);
521 fprintf(f
, line_format
, lineno
, input_file_name
);
533 unterminated_text(t_lineno
, t_line
, t_cptr
);
539 char *s
= copy_string(c
);
549 char *s
= copy_comment();
576 puts_both(const char *s
)
580 fputs(s
, union_file
);
596 int u_lineno
= lineno
;
597 char *u_line
= dup_line();
598 char *u_cptr
= u_line
+ (cptr
- line
- 6);
601 over_unionized(cptr
- 6);
605 fprintf(text_file
, line_format
, lineno
, input_file_name
);
607 puts_both("#ifdef YYSTYPE\n");
608 puts_both("#undef YYSTYPE_IS_DECLARED\n");
609 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
610 puts_both("#endif\n");
611 puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
612 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
613 puts_both("typedef union");
624 unterminated_union(u_lineno
, u_line
, u_cptr
);
634 puts_both(" YYSTYPE;\n");
635 puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
644 char *s
= copy_string(c
);
652 char *s
= copy_comment();
664 after_blanks(char *s
)
666 while (*s
!= '\0' && isspace(UCH(*s
)))
672 * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
673 * single space. Return index to last character in the buffer.
676 trim_blanks(char *buffer
)
681 char *s
= after_blanks(d
);
683 while ((*d
++ = *s
++) != '\0')
689 while ((--d
!= buffer
) && isspace(UCH(*d
)))
692 for (s
= d
= buffer
; (*d
++ = *s
++) != '\0';)
694 if (isspace(UCH(*s
)))
697 while (isspace(UCH(*s
)))
706 return (int)strlen(buffer
) - 1;
710 * Scan forward in the current line-buffer looking for a right-curly bracket.
712 * Parameters begin with a left-curly bracket, and continue until there are no
713 * more interesting characters after the last right-curly bracket on the
714 * current line. Bison documents parameters as separated like this:
715 * {type param1} {type2 param2}
716 * but also accepts commas (although some versions of bison mishandle this)
717 * {type param1, type2 param2}
727 switch (next_inline())
746 save_param(int k
, char *buffer
, int name
, int type2
)
750 p
= TMALLOC(param
, 1);
753 p
->type2
= strdup(buffer
+ type2
);
755 buffer
[type2
] = '\0';
756 (void)trim_blanks(p
->type2
);
758 p
->name
= strdup(buffer
+ name
);
761 (void)trim_blanks(p
->name
);
763 p
->type
= strdup(buffer
);
765 (void)trim_blanks(p
->type
);
789 * Keep a linked list of parameters. This may be multi-line, if the trailing
790 * right-curly bracket is absent.
801 int st_lineno
= lineno
;
835 if ((curly
== 1) && (cptr
== line
))
845 if (curly
== 0 && !isspace(UCH(c
)))
853 buf_size
= (size_t) linesize
;
854 buf
= TMALLOC(char, buf_size
);
862 buf_size
+= (size_t) linesize
;
863 buf
= TREALLOC(char, buf
, buf_size
);
868 if ((state
== 2) && (c
== L_CURL
))
872 else if ((state
== 2) && isspace(UCH(c
)))
876 else if ((c
!= L_CURL
) && (c
!= R_CURL
))
883 while (curly
< 2 || more_curly());
896 i
= trim_blanks(buf
);
901 char *parms
= (comma
+ 1);
902 comma
= strchr(parms
, ',');
906 (void)trim_blanks(parms
);
907 i
= (int)strlen(parms
) - 1;
916 while (i
>= 0 && level
> 0 && parms
[i
] != '[')
920 else if (parms
[i
] == '[')
933 while (i
> 0 && (isalnum(UCH(parms
[i
])) || UCH(parms
[i
]) == '_'))
936 if (!isspace(UCH(parms
[i
])) && parms
[i
] != '*')
941 save_param(k
, parms
, name
, type2
);
949 syntax_error(lineno
, line
, cptr
);
955 if (c
>= '0' && c
<= '9')
957 if (c
>= 'A' && c
<= 'F')
958 return (c
- 'A' + 10);
959 if (c
>= 'a' && c
<= 'f')
960 return (c
- 'a' + 10);
972 int s_lineno
= lineno
;
973 char *s_line
= dup_line();
974 char *s_cptr
= s_line
+ (cptr
- line
);
984 unterminated_string(s_lineno
, s_line
, s_cptr
);
987 char *c_cptr
= cptr
- 1;
995 unterminated_string(s_lineno
, s_line
, s_cptr
);
1010 n
= (n
<< 3) + (c
- '0');
1014 n
= (n
<< 3) + (c
- '0');
1019 illegal_character(c_cptr
);
1026 if (n
< 0 || n
>= 16)
1027 illegal_character(c_cptr
);
1032 if (i
< 0 || i
>= 16)
1037 illegal_character(c_cptr
);
1070 s
= TMALLOC(char, n
);
1073 for (i
= 0; i
< n
; ++i
)
1082 for (i
= 0; i
< n
; ++i
)
1085 if (c
== '\\' || c
== cache
[0])
1090 else if (isprint(c
))
1119 cachec(((c
>> 6) & 7) + '0');
1120 cachec(((c
>> 3) & 7) + '0');
1121 cachec((c
& 7) + '0');
1135 if (n
== 1 && bp
->value
== UNDEFINED
)
1136 bp
->value
= UCH(*s
);
1143 is_reserved(char *name
)
1147 if (strcmp(name
, ".") == 0 ||
1148 strcmp(name
, "$accept") == 0 ||
1149 strcmp(name
, "$end") == 0)
1152 if (name
[0] == '$' && name
[1] == '$' && isdigit(UCH(name
[2])))
1155 while (isdigit(UCH(*s
)))
1170 for (c
= *cptr
; IS_IDENT(c
); c
= *++cptr
)
1174 if (is_reserved(cache
))
1175 used_reserved(cache
);
1177 return (lookup(cache
));
1187 for (c
= *cptr
; isdigit(c
); c
= *++cptr
)
1188 n
= (Value_t
) (10 * n
+ (c
- '0'));
1194 cache_tag(char *tag
, size_t len
)
1199 for (i
= 0; i
< ntags
; ++i
)
1201 if (strncmp(tag
, tag_table
[i
], len
) == 0 &&
1202 tag_table
[i
][len
] == NUL
)
1203 return (tag_table
[i
]);
1206 if (ntags
>= tagmax
)
1211 ? TREALLOC(char *, tag_table
, tagmax
)
1212 : TMALLOC(char *, tagmax
));
1213 NO_SPACE(tag_table
);
1216 s
= TMALLOC(char, len
+ 1);
1219 strncpy(s
, tag
, len
);
1221 tag_table
[ntags
++] = s
;
1229 int t_lineno
= lineno
;
1230 char *t_line
= dup_line();
1231 char *t_cptr
= t_line
+ (cptr
- line
);
1237 if (!isalpha(c
) && c
!= '_' && c
!= '$')
1238 illegal_tag(t_lineno
, t_line
, t_cptr
);
1246 while (IS_IDENT(c
));
1253 illegal_tag(t_lineno
, t_line
, t_cptr
);
1258 return cache_tag(cache
, (size_t) cinc
);
1261 #if defined(YYBTYACC)
1267 while (isalnum(*cptr
) || *cptr
== '_' || *cptr
== '$')
1269 return cache_tag(b
, (size_t) (cptr
- b
));
1274 declare_tokens(int assoc
)
1297 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1299 else if (c
== '\'' || c
== '"')
1305 tokenized_start(bp
->name
);
1310 if (bp
->tag
&& tag
!= bp
->tag
)
1311 retyped_warning(bp
->name
);
1317 if (bp
->prec
&& prec
!= bp
->prec
)
1318 reprec_warning(bp
->name
);
1319 bp
->assoc
= (Assoc_t
) assoc
;
1329 value
= get_number();
1330 if (bp
->value
!= UNDEFINED
&& value
!= bp
->value
)
1331 revalued_warning(bp
->name
);
1341 * %expect requires special handling
1342 * as it really isn't part of the yacc
1343 * grammar only a flag for yacc proper.
1346 declare_expect(int assoc
)
1350 if (assoc
!= EXPECT
&& assoc
!= EXPECT_RR
)
1354 * Stay away from nextc - doesn't
1355 * detect EOL and will read to EOF.
1365 if (assoc
== EXPECT
)
1366 SRexpect
= get_number();
1368 RRexpect
= get_number();
1372 * Looking for number before EOL.
1373 * Spaces, tabs, and numbers are ok,
1374 * words, punc., etc. are syntax errors.
1376 else if (c
== '\n' || isalpha(c
) || !isspace(c
))
1378 syntax_error(lineno
, line
, cptr
);
1389 #if defined(YYBTYACC)
1391 declare_argtypes(bucket
*bp
)
1393 char *tags
[MAXARGS
];
1397 retyped_warning(bp
->name
);
1398 cptr
++; /* skip open paren */
1405 syntax_error(lineno
, line
, cptr
);
1406 tags
[args
++] = get_tag();
1413 cptr
++; /* skip close paren */
1415 bp
->argnames
= TMALLOC(char *, args
);
1416 NO_SPACE(bp
->argnames
);
1417 bp
->argtags
= CALLOC(sizeof(char *), args
+ 1);
1418 NO_SPACE(bp
->argtags
);
1421 bp
->argtags
[args
] = tags
[args
];
1422 bp
->argnames
[args
] = NULL
;
1445 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1448 #if defined(YYBTYACC)
1449 if (nextc() == L_PAREN
)
1450 declare_argtypes(bp
);
1455 else if (c
== '\'' || c
== '"')
1458 #if defined(YYBTYACC)
1467 if (bp
->tag
&& tag
!= bp
->tag
)
1468 retyped_warning(bp
->name
);
1483 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '$')
1484 syntax_error(lineno
, line
, cptr
);
1486 if (bp
->class == TERM
)
1487 terminal_start(bp
->name
);
1488 if (goal
&& goal
!= bp
)
1489 restarted_warning();
1494 read_declarations(void)
1499 cache
= TMALLOC(char, cache_size
);
1508 syntax_error(lineno
, line
, cptr
);
1509 switch (k
= keyword())
1559 #if defined(YYBTYACC)
1571 /* noop for bison compatibility. byacc is already designed to be posix
1572 * yacc compatible. */
1579 initialize_grammar(void)
1584 pitem
= TMALLOC(bucket
*, maxitems
);
1595 plhs
= TMALLOC(bucket
*, maxrules
);
1602 rprec
= TMALLOC(Value_t
, maxrules
);
1609 rassoc
= TMALLOC(Assoc_t
, maxrules
);
1621 pitem
= TREALLOC(bucket
*, pitem
, maxitems
);
1630 plhs
= TREALLOC(bucket
*, plhs
, maxrules
);
1633 rprec
= TREALLOC(Value_t
, rprec
, maxrules
);
1636 rassoc
= TREALLOC(Assoc_t
, rassoc
, maxrules
);
1640 /* set immediately prior to where copy_args() could be called, and incremented by
1641 the various routines that will rescan the argument list as appropriate */
1642 static int rescan_lineno
;
1643 #if defined(YYBTYACC)
1646 copy_args(int *alen
)
1648 struct mstring
*s
= msnew();
1649 int depth
= 0, len
= 1;
1651 int a_lineno
= lineno
;
1652 char *a_line
= dup_line();
1653 char *a_cptr
= a_line
+ (cptr
- line
- 1);
1655 while ((c
= *cptr
++) != R_PAREN
|| depth
|| quote
)
1657 if (c
== ',' && !quote
&& !depth
)
1670 unterminated_string(a_lineno
, a_line
, a_cptr
);
1672 unterminated_arglist(a_lineno
, a_line
, a_cptr
);
1689 else if (c
== R_PAREN
)
1691 else if (c
== '\"' || c
== '\'')
1702 parse_id(char *p
, char **save
)
1709 if (!isalpha(*p
) && *p
!= '_')
1712 while (isalnum(*p
) || *p
== '_' || *p
== '$')
1716 *save
= cache_tag(b
, (size_t) (p
- b
));
1722 parse_int(char *p
, int *save
)
1724 int neg
= 0, val
= 0;
1737 val
= val
* 10 + *p
++ - '0';
1746 parse_arginfo(bucket
*a
, char *args
, int argslen
)
1748 char *p
= args
, *tmp
;
1753 if (a
->args
!= argslen
)
1754 arg_number_disagree_warning(rescan_lineno
, a
->name
);
1759 if ((a
->args
= argslen
) == 0)
1761 a
->argnames
= TMALLOC(char *, argslen
);
1762 NO_SPACE(a
->argnames
);
1763 a
->argtags
= TMALLOC(char *, argslen
);
1764 NO_SPACE(a
->argtags
);
1768 for (i
= 0; i
< argslen
; i
++)
1781 if (!(p
= parse_id(p
+ 1, &tmp
)))
1790 if (a
->argtags
[i
] != tmp
)
1791 arg_type_disagree_warning(rescan_lineno
, i
+ 1, a
->name
);
1794 a
->argtags
[i
] = tmp
;
1797 a
->argtags
[i
] = NULL
;
1798 if (!(p
= parse_id(p
, &a
->argnames
[i
])))
1810 compile_arg(char **theptr
, char *yyvaltag
)
1813 struct mstring
*c
= msnew();
1815 Value_t
*offsets
= NULL
, maxoffset
;
1820 for (i
= nitems
- 1; pitem
[i
]; --i
)
1823 if (pitem
[i
]->class != ARGUMENT
)
1828 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
1831 for (j
= 0, i
++; i
< nitems
; i
++)
1832 if (pitem
[i
]->class != ARGUMENT
)
1833 offsets
[++j
] = (Value_t
) (i
- nitems
+ 1);
1835 rhs
= pitem
+ nitems
- 1;
1838 msprintf(c
, "yyval.%s = ", yyvaltag
);
1840 msprintf(c
, "yyval = ");
1847 if (!(p
= parse_id(++p
, &tag
)) || *p
++ != '>')
1848 illegal_tag(rescan_lineno
, NULL
, NULL
);
1849 if (isdigit(*p
) || *p
== '-')
1852 if (!(p
= parse_int(p
, &val
)))
1853 dollar_error(rescan_lineno
, NULL
, NULL
);
1856 else if (val
> maxoffset
)
1858 dollar_warning(rescan_lineno
, val
);
1859 i
= val
- maxoffset
;
1861 else if (maxoffset
> 0)
1864 if (!tag
&& !(tag
= rhs
[i
]->tag
) && havetags
)
1865 untyped_rhs(val
, rhs
[i
]->name
);
1867 msprintf(c
, "yystack.l_mark[%d]", i
);
1869 msprintf(c
, ".%s", tag
);
1873 else if (isalpha(*p
) || *p
== '_')
1876 if (!(p
= parse_id(p
, &arg
)))
1877 dollar_error(rescan_lineno
, NULL
, NULL
);
1878 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
1879 if (arg
== plhs
[nrules
]->argnames
[i
])
1882 unknown_arg_warning(rescan_lineno
, "$", arg
, NULL
, NULL
);
1884 tag
= plhs
[nrules
]->argtags
[i
];
1885 msprintf(c
, "yystack.l_mark[%d]", i
- plhs
[nrules
]->args
+ 1
1888 msprintf(c
, ".%s", tag
);
1890 untyped_arg_warning(rescan_lineno
, "$", arg
);
1893 dollar_error(rescan_lineno
, NULL
, NULL
);
1897 at_error(rescan_lineno
, NULL
, NULL
);
1912 #define ARG_CACHE_SIZE 1024
1913 static struct arg_cache
1915 struct arg_cache
*next
;
1919 *arg_cache
[ARG_CACHE_SIZE
];
1922 lookup_arg_cache(char *code
)
1924 struct arg_cache
*entry
;
1926 entry
= arg_cache
[strnshash(code
) % ARG_CACHE_SIZE
];
1929 if (!strnscmp(entry
->code
, code
))
1931 entry
= entry
->next
;
1937 insert_arg_cache(char *code
, int rule
)
1939 struct arg_cache
*entry
= NEW(struct arg_cache
);
1943 i
= strnshash(code
) % ARG_CACHE_SIZE
;
1946 entry
->next
= arg_cache
[i
];
1947 arg_cache
[i
] = entry
;
1951 clean_arg_cache(void)
1953 struct arg_cache
*e
, *t
;
1956 for (i
= 0; i
< ARG_CACHE_SIZE
; i
++)
1958 for (e
= arg_cache
[i
]; (t
= e
); e
= e
->next
, FREE(t
))
1960 arg_cache
[i
] = NULL
;
1966 advance_to_start(void)
1972 #if defined(YYBTYACC)
1997 syntax_error(lineno
, line
, s_cptr
);
2002 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '_')
2003 syntax_error(lineno
, line
, cptr
);
2007 if (bp
->class == TERM
)
2008 terminal_start(bp
->name
);
2016 rescan_lineno
= lineno
; /* line# for possible inherited args rescan */
2017 #if defined(YYBTYACC)
2021 args
= copy_args(&argslen
);
2027 syntax_error(lineno
, line
, cptr
);
2028 start_rule(bp
, s_lineno
);
2029 #if defined(YYBTYACC)
2030 parse_arginfo(bp
, args
, argslen
);
2036 start_rule(bucket
*bp
, int s_lineno
)
2038 if (bp
->class == TERM
)
2039 terminal_lhs(s_lineno
);
2040 bp
->class = NONTERM
;
2043 if (nrules
>= maxrules
)
2046 rprec
[nrules
] = UNDEFINED
;
2047 rassoc
[nrules
] = TOKEN
;
2055 if (!last_was_action
&& plhs
[nrules
]->tag
)
2057 if (pitem
[nitems
- 1])
2059 for (i
= nitems
- 1; (i
> 0) && pitem
[i
]; --i
)
2061 if (pitem
[i
+ 1] == 0 || pitem
[i
+ 1]->tag
!= plhs
[nrules
]->tag
)
2062 default_action_warning();
2066 default_action_warning();
2070 last_was_action
= 0;
2071 if (nitems
>= maxitems
)
2079 insert_empty_rule(void)
2084 sprintf(cache
, "$$%d", ++gensym
);
2085 bp
= make_bucket(cache
);
2086 last_symbol
->next
= bp
;
2088 bp
->tag
= plhs
[nrules
]->tag
;
2090 #if defined(YYBTYACC)
2094 nitems
= (Value_t
) (nitems
+ 2);
2095 if (nitems
> maxitems
)
2097 bpp
= pitem
+ nitems
- 1;
2099 while ((bpp
[0] = bpp
[-1]) != 0)
2102 if (++nrules
>= maxrules
)
2104 plhs
[nrules
] = plhs
[nrules
- 1];
2105 plhs
[nrules
- 1] = bp
;
2106 rprec
[nrules
] = rprec
[nrules
- 1];
2107 rprec
[nrules
- 1] = 0;
2108 rassoc
[nrules
] = rassoc
[nrules
- 1];
2109 rassoc
[nrules
- 1] = TOKEN
;
2112 #if defined(YYBTYACC)
2114 insert_arg_rule(char *arg
, char *tag
)
2116 int line_number
= rescan_lineno
;
2117 char *code
= compile_arg(&arg
, tag
);
2118 int rule
= lookup_arg_cache(code
);
2119 FILE *f
= action_file
;
2124 insert_arg_cache(code
, rule
);
2125 fprintf(f
, "case %d:\n", rule
- 2);
2127 fprintf(f
, line_format
, line_number
, input_file_name
);
2128 fprintf(f
, "%s;\n", code
);
2129 fprintf(f
, "break;\n");
2130 insert_empty_rule();
2131 plhs
[rule
]->tag
= tag
;
2132 plhs
[rule
]->class = ARGUMENT
;
2136 if (++nitems
> maxitems
)
2138 pitem
[nitems
- 1] = plhs
[rule
];
2150 int s_lineno
= lineno
;
2151 #if defined(YYBTYACC)
2157 if (c
== '\'' || c
== '"')
2163 rescan_lineno
= lineno
; /* line# for possible inherited args rescan */
2164 #if defined(YYBTYACC)
2168 args
= copy_args(&argslen
);
2176 start_rule(bp
, s_lineno
);
2177 #if defined(YYBTYACC)
2178 parse_arginfo(bp
, args
, argslen
);
2184 if (last_was_action
)
2185 insert_empty_rule();
2186 last_was_action
= 0;
2188 #if defined(YYBTYACC)
2191 if (argslen
== 0 && bp
->args
> 0 && pitem
[nitems
- 1] == NULL
)
2194 if (plhs
[nrules
]->args
!= bp
->args
)
2195 wrong_number_args_warning("default ", bp
->name
);
2196 for (i
= bp
->args
- 1; i
>= 0; i
--)
2197 if (plhs
[nrules
]->argtags
[i
] != bp
->argtags
[i
])
2198 wrong_type_for_arg_warning(i
+ 1, bp
->name
);
2200 else if (bp
->args
!= argslen
)
2201 wrong_number_args_warning("", bp
->name
);
2202 if (bp
->args
> 0 && argslen
> 0)
2206 for (ap
= args
, i
= 0; i
< argslen
; i
++)
2207 ap
= insert_arg_rule(ap
, bp
->argtags
[i
]);
2210 #endif /* defined(YYBTYACC) */
2212 if (++nitems
> maxitems
)
2214 pitem
[nitems
- 1] = bp
;
2223 #if defined(YYBTYACC)
2224 int trialaction
= 0;
2228 FILE *f
= action_file
;
2229 int a_lineno
= lineno
;
2230 char *a_line
= dup_line();
2231 char *a_cptr
= a_line
+ (cptr
- line
);
2232 Value_t
*offsets
= NULL
, maxoffset
;
2235 if (last_was_action
)
2236 insert_empty_rule();
2237 last_was_action
= 1;
2239 fprintf(f
, "case %d:\n", nrules
- 2);
2240 #if defined(YYBTYACC)
2243 if (*cptr
!= L_BRAC
)
2244 fprintf(f
, " if (!yytrial)\n");
2250 fprintf(f
, line_format
, lineno
, input_file_name
);
2254 /* avoid putting curly-braces in first column, to ease editing */
2255 if (*after_blanks(cptr
) == L_CURL
)
2258 cptr
= after_blanks(cptr
);
2263 for (i
= nitems
- 1; pitem
[i
]; --i
)
2266 if (pitem
[i
]->class != ARGUMENT
)
2271 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
2274 for (j
= 0, i
++; i
< nitems
; i
++)
2276 if (pitem
[i
]->class != ARGUMENT
)
2278 offsets
[++j
] = (Value_t
) (i
- nitems
+ 1);
2282 rhs
= pitem
+ nitems
- 1;
2291 int d_lineno
= lineno
;
2292 char *d_line
= dup_line();
2293 char *d_cptr
= d_line
+ (cptr
- line
);
2300 fprintf(f
, "yyval.%s", tag
);
2305 else if (isdigit(c
))
2309 fprintf(f
, "yystack.l_mark[%d].%s", -n
, tag
);
2310 else if (i
> maxoffset
)
2312 dollar_warning(d_lineno
, i
);
2313 fprintf(f
, "yystack.l_mark[%d].%s", i
- maxoffset
, tag
);
2316 fprintf(f
, "yystack.l_mark[%d].%s", offsets
[i
], tag
);
2320 else if (c
== '-' && isdigit(UCH(cptr
[1])))
2323 i
= -get_number() - n
;
2324 fprintf(f
, "yystack.l_mark[%d].%s", i
, tag
);
2328 #if defined(YYBTYACC)
2329 else if (isalpha(c
) || c
== '_')
2331 char *arg
= scan_id();
2332 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2333 if (arg
== plhs
[nrules
]->argnames
[i
])
2336 unknown_arg_warning(d_lineno
, "$", arg
, d_line
, d_cptr
);
2337 fprintf(f
, "yystack.l_mark[%d].%s", i
- plhs
[nrules
]->args
+
2344 dollar_error(d_lineno
, d_line
, d_cptr
);
2346 else if (cptr
[1] == '$')
2350 tag
= plhs
[nrules
]->tag
;
2353 fprintf(f
, "yyval.%s", tag
);
2356 fprintf(f
, "yyval");
2358 #if defined(YYBTYACC)
2363 else if (isdigit(UCH(cptr
[1])))
2367 if (havetags
&& offsets
)
2369 if (i
<= 0 || i
> maxoffset
)
2371 tag
= rhs
[offsets
[i
]]->tag
;
2373 untyped_rhs(i
, rhs
[offsets
[i
]]->name
);
2374 fprintf(f
, "yystack.l_mark[%d].%s", offsets
[i
], tag
);
2379 fprintf(f
, "yystack.l_mark[%d]", -n
);
2380 else if (i
> maxoffset
)
2382 dollar_warning(lineno
, i
);
2383 fprintf(f
, "yystack.l_mark[%d]", i
- maxoffset
);
2386 fprintf(f
, "yystack.l_mark[%d]", offsets
[i
]);
2390 else if (cptr
[1] == '-')
2396 fprintf(f
, "yystack.l_mark[%d]", -i
- n
);
2399 #if defined(YYBTYACC)
2400 else if (isalpha(cptr
[1]) || cptr
[1] == '_')
2405 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2406 if (arg
== plhs
[nrules
]->argnames
[i
])
2409 unknown_arg_warning(lineno
, "$", arg
, line
, cptr
);
2410 tag
= (i
< 0 ? NULL
: plhs
[nrules
]->argtags
[i
]);
2411 fprintf(f
, "yystack.l_mark[%d]", i
- plhs
[nrules
]->args
+ 1 - n
);
2413 fprintf(f
, ".%s", tag
);
2415 untyped_arg_warning(lineno
, "$", arg
);
2420 #if defined(YYBTYACC)
2425 int l_lineno
= lineno
;
2426 char *l_line
= dup_line();
2427 char *l_cptr
= l_line
+ (cptr
- line
);
2428 syntax_error(l_lineno
, l_line
, l_cptr
);
2432 fprintf(f
, "yyloc");
2436 else if (isdigit(UCH(cptr
[1])))
2441 fprintf(f
, "yystack.p_mark[%d]", -n
);
2442 else if (i
> maxoffset
)
2444 at_warning(lineno
, i
);
2445 fprintf(f
, "yystack.p_mark[%d]", i
- maxoffset
);
2448 fprintf(f
, "yystack.p_mark[%d]", offsets
[i
]);
2453 if (isalpha(c
) || c
== '_' || c
== '$')
2460 while (isalnum(c
) || c
== '_' || c
== '$');
2464 #if defined(YYBTYACC)
2467 if (trialaction
&& c
== L_BRAC
&& depth
== 0)
2473 if (trialaction
&& c
== R_BRAC
&& depth
== 1)
2478 if (c
== L_BRAC
&& !haveyyval
)
2482 if (c
== L_CURL
&& !haveyyval
)
2484 fprintf(f
, " if (!yytrial)\n");
2486 fprintf(f
, line_format
, lineno
, input_file_name
);
2490 fprintf(f
, "\nbreak;\n");
2505 unterminated_action(a_lineno
, a_line
, a_cptr
);
2510 fprintf(f
, "\nbreak;\n");
2516 #if defined(YYBTYACC)
2535 #if defined(YYBTYACC)
2539 if (c
== L_BRAC
&& !haveyyval
)
2544 if (c
== L_CURL
&& !haveyyval
)
2546 fprintf(f
, " if (!yytrial)\n");
2548 fprintf(f
, line_format
, lineno
, input_file_name
);
2553 fprintf(f
, "\nbreak;\n");
2562 char *s
= copy_string(c
);
2570 char *s
= copy_comment();
2581 #if defined(YYBTYACC)
2583 copy_destructor(void)
2589 struct mstring
*destructor_text
= msnew();
2596 msprintf(destructor_text
, line_format
, lineno
, input_file_name
);
2598 cptr
= after_blanks(cptr
);
2599 if (*cptr
== L_CURL
)
2600 /* avoid putting curly-braces in first column, to ease editing */
2601 mputc(destructor_text
, '\t');
2603 syntax_error(lineno
, line
, cptr
);
2606 a_line
= dup_line();
2607 a_cptr
= a_line
+ (cptr
- line
);
2616 int d_lineno
= lineno
;
2617 char *d_line
= dup_line();
2618 char *d_cptr
= d_line
+ (cptr
- line
);
2625 msprintf(destructor_text
, "(*val).%s", tag
);
2631 dollar_error(d_lineno
, d_line
, d_cptr
);
2633 else if (cptr
[1] == '$')
2635 /* process '$$' later; replacement is context dependent */
2636 msprintf(destructor_text
, "$$");
2641 if (c
== '@' && cptr
[1] == '$')
2645 int l_lineno
= lineno
;
2646 char *l_line
= dup_line();
2647 char *l_cptr
= l_line
+ (cptr
- line
);
2648 syntax_error(l_lineno
, l_line
, l_cptr
);
2650 msprintf(destructor_text
, "(*loc)");
2654 if (isalpha(c
) || c
== '_' || c
== '$')
2658 mputc(destructor_text
, c
);
2661 while (isalnum(c
) || c
== '_' || c
== '$');
2665 mputc(destructor_text
, c
);
2672 unterminated_action(a_lineno
, a_line
, a_cptr
);
2681 goto process_symbols
;
2686 char *s
= copy_string(c
);
2687 msprintf(destructor_text
, "%s", s
);
2694 char *s
= copy_comment();
2695 msprintf(destructor_text
, "%s", s
);
2704 code_text
= msdone(destructor_text
);
2713 { /* "no semantic type" default destructor */
2715 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) == NULL
)
2717 static char untyped_default
[] = "<>";
2718 bp
= make_bucket("untyped default");
2719 bp
->tag
= untyped_default
;
2720 default_destructor
[UNTYPED_DEFAULT
] = bp
;
2722 if (bp
->destructor
!= NULL
)
2723 destructor_redeclared_warning(a_lineno
, a_line
, a_cptr
);
2725 /* replace "$$" with "(*val)" in destructor code */
2726 bp
->destructor
= process_destructor_XX(code_text
, NULL
);
2728 else if (cptr
[1] == '*' && cptr
[2] == '>')
2729 { /* "no per-symbol or per-type" default destructor */
2731 if ((bp
= default_destructor
[TYPED_DEFAULT
]) == NULL
)
2733 static char typed_default
[] = "<*>";
2734 bp
= make_bucket("typed default");
2735 bp
->tag
= typed_default
;
2736 default_destructor
[TYPED_DEFAULT
] = bp
;
2738 if (bp
->destructor
!= NULL
)
2739 destructor_redeclared_warning(a_lineno
, a_line
, a_cptr
);
2742 /* postpone re-processing destructor $$s until end of grammar spec */
2743 bp
->destructor
= TMALLOC(char, strlen(code_text
) + 1);
2744 NO_SPACE(bp
->destructor
);
2745 strcpy(bp
->destructor
, code_text
);
2749 { /* "semantic type" default destructor */
2751 bp
= lookup_type_destructor(tag
);
2752 if (bp
->destructor
!= NULL
)
2753 destructor_redeclared_warning(a_lineno
, a_line
, a_cptr
);
2755 /* replace "$$" with "(*val).tag" in destructor code */
2756 bp
->destructor
= process_destructor_XX(code_text
, tag
);
2759 else if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
2760 { /* "symbol" destructor */
2762 if (bp
->destructor
!= NULL
)
2763 destructor_redeclared_warning(a_lineno
, a_line
, a_cptr
);
2766 /* postpone re-processing destructor $$s until end of grammar spec */
2767 bp
->destructor
= TMALLOC(char, strlen(code_text
) + 1);
2768 NO_SPACE(bp
->destructor
);
2769 strcpy(bp
->destructor
, code_text
);
2780 process_destructor_XX(char *code
, char *tag
)
2785 struct mstring
*new_code
= msnew();
2786 char *codeptr
= code
;
2789 loop
: /* step thru code */
2791 if (c
== '$' && codeptr
[1] == '$')
2795 msprintf(new_code
, "(*val)");
2797 msprintf(new_code
, "(*val).%s", tag
);
2800 if (isalpha(c
) || c
== '_' || c
== '$')
2807 while (isalnum(c
) || c
== '_' || c
== '$');
2821 return msdone(new_code
);
2849 if (c
== '*' && *codeptr
== '/')
2851 mputc(new_code
, '/');
2863 #endif /* defined(YYBTYACC) */
2872 if (c
== '%' || c
== '\\')
2880 else if ((c
== 'p' || c
== 'P') &&
2881 ((c
= cptr
[2]) == 'r' || c
== 'R') &&
2882 ((c
= cptr
[3]) == 'e' || c
== 'E') &&
2883 ((c
= cptr
[4]) == 'c' || c
== 'C') &&
2884 ((c
= cptr
[5], !IS_IDENT(c
))))
2887 syntax_error(lineno
, line
, cptr
);
2890 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
2892 else if (c
== '\'' || c
== '"')
2896 syntax_error(lineno
, line
, cptr
);
2899 if (rprec
[nrules
] != UNDEFINED
&& bp
->prec
!= rprec
[nrules
])
2902 rprec
[nrules
] = bp
->prec
;
2903 rassoc
[nrules
] = bp
->assoc
;
2912 initialize_grammar();
2927 #if defined(YYBTYACC)
2928 else if (c
== L_CURL
|| c
== '=' || (backtrack
&& c
== L_BRAC
))
2930 else if (c
== L_CURL
|| c
== '=')
2936 start_rule(plhs
[nrules
- 1], 0);
2945 syntax_error(lineno
, line
, cptr
);
2948 #if defined(YYBTYACC)
2950 start_requires_args(goal
->name
);
2962 for (i
= 0; i
< ntags
; ++i
)
2964 assert(tag_table
[i
]);
2976 name_pool_size
= 13; /* 13 == sizeof("$end") + sizeof("$accept") */
2977 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
2978 name_pool_size
+= strlen(bp
->name
) + 1;
2980 name_pool
= TMALLOC(char, name_pool_size
);
2981 NO_SPACE(name_pool
);
2983 strcpy(name_pool
, "$accept");
2984 strcpy(name_pool
+ 8, "$end");
2986 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
2990 while ((*t
++ = *s
++) != 0)
3002 if (goal
->class == UNKNOWN
)
3003 undefined_goal(goal
->name
);
3005 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3007 if (bp
->class == UNKNOWN
)
3009 undefined_symbol_warning(bp
->name
);
3016 protect_string(char *src
, char **des
)
3029 if ('\\' == *s
|| '"' == *s
)
3035 *des
= d
= TMALLOC(char, len
);
3041 if ('\\' == *s
|| '"' == *s
)
3055 #if defined(YYBTYACC)
3056 Value_t max_tok_pval
;
3061 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3064 if (bp
->class == TERM
)
3067 start_symbol
= (Value_t
) ntokens
;
3068 nvars
= (Value_t
) (nsyms
- ntokens
);
3070 symbol_name
= TMALLOC(char *, nsyms
);
3071 NO_SPACE(symbol_name
);
3073 symbol_value
= TMALLOC(Value_t
, nsyms
);
3074 NO_SPACE(symbol_value
);
3076 symbol_prec
= TMALLOC(Value_t
, nsyms
);
3077 NO_SPACE(symbol_prec
);
3079 symbol_assoc
= TMALLOC(char, nsyms
);
3080 NO_SPACE(symbol_assoc
);
3082 #if defined(YYBTYACC)
3083 symbol_pval
= TMALLOC(Value_t
, nsyms
);
3084 NO_SPACE(symbol_pval
);
3088 symbol_destructor
= CALLOC(sizeof(char *), nsyms
);
3089 NO_SPACE(symbol_destructor
);
3091 symbol_type_tag
= CALLOC(sizeof(char *), nsyms
);
3092 NO_SPACE(symbol_type_tag
);
3096 v
= TMALLOC(bucket
*, nsyms
);
3100 v
[start_symbol
] = 0;
3103 j
= (Value_t
) (start_symbol
+ 1);
3104 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3106 if (bp
->class == TERM
)
3111 assert(i
== ntokens
&& j
== nsyms
);
3113 for (i
= 1; i
< ntokens
; ++i
)
3116 goal
->index
= (Index_t
) (start_symbol
+ 1);
3117 k
= (Value_t
) (start_symbol
+ 2);
3127 for (i
= (Value_t
) (start_symbol
+ 1); i
< nsyms
; ++i
)
3137 for (i
= 1; i
< ntokens
; ++i
)
3142 for (j
= k
++; j
> 0 && symbol_value
[j
- 1] > n
; --j
)
3143 symbol_value
[j
] = symbol_value
[j
- 1];
3144 symbol_value
[j
] = n
;
3150 if (v
[1]->value
== UNDEFINED
)
3155 for (i
= 2; i
< ntokens
; ++i
)
3157 if (v
[i
]->value
== UNDEFINED
)
3159 while (j
< k
&& n
== symbol_value
[j
])
3161 while (++j
< k
&& n
== symbol_value
[j
])
3170 symbol_name
[0] = name_pool
+ 8;
3171 symbol_value
[0] = 0;
3173 symbol_assoc
[0] = TOKEN
;
3174 #if defined(YYBTYACC)
3178 for (i
= 1; i
< ntokens
; ++i
)
3180 symbol_name
[i
] = v
[i
]->name
;
3181 symbol_value
[i
] = v
[i
]->value
;
3182 symbol_prec
[i
] = v
[i
]->prec
;
3183 symbol_assoc
[i
] = v
[i
]->assoc
;
3184 #if defined(YYBTYACC)
3185 symbol_pval
[i
] = v
[i
]->value
;
3186 if (symbol_pval
[i
] > max_tok_pval
)
3187 max_tok_pval
= symbol_pval
[i
];
3190 symbol_destructor
[i
] = v
[i
]->destructor
;
3191 symbol_type_tag
[i
] = v
[i
]->tag
;
3195 symbol_name
[start_symbol
] = name_pool
;
3196 symbol_value
[start_symbol
] = -1;
3197 symbol_prec
[start_symbol
] = 0;
3198 symbol_assoc
[start_symbol
] = TOKEN
;
3199 #if defined(YYBTYACC)
3200 symbol_pval
[start_symbol
] = (Value_t
) (max_tok_pval
+ 1);
3202 for (++i
; i
< nsyms
; ++i
)
3205 symbol_name
[k
] = v
[i
]->name
;
3206 symbol_value
[k
] = v
[i
]->value
;
3207 symbol_prec
[k
] = v
[i
]->prec
;
3208 symbol_assoc
[k
] = v
[i
]->assoc
;
3209 #if defined(YYBTYACC)
3210 symbol_pval
[k
] = (Value_t
) ((max_tok_pval
+ 1) + v
[i
]->value
+ 1);
3213 symbol_destructor
[k
] = v
[i
]->destructor
;
3214 symbol_type_tag
[k
] = v
[i
]->tag
;
3221 symbol_pname
= TMALLOC(char *, nsyms
);
3222 NO_SPACE(symbol_pname
);
3224 for (i
= 0; i
< nsyms
; ++i
)
3225 protect_string(symbol_name
[i
], &(symbol_pname
[i
]));
3239 ritem
= TMALLOC(Value_t
, nitems
);
3242 rlhs
= TMALLOC(Value_t
, nrules
);
3245 rrhs
= TMALLOC(Value_t
, nrules
+ 1);
3248 rprec
= TREALLOC(Value_t
, rprec
, nrules
);
3251 rassoc
= TREALLOC(Assoc_t
, rassoc
, nrules
);
3255 ritem
[1] = goal
->index
;
3260 rlhs
[2] = start_symbol
;
3266 for (i
= 3; i
< nrules
; ++i
)
3268 #if defined(YYBTYACC)
3269 if (plhs
[i
]->args
> 0)
3271 if (plhs
[i
]->argnames
)
3273 FREE(plhs
[i
]->argnames
);
3274 plhs
[i
]->argnames
= NULL
;
3276 if (plhs
[i
]->argtags
)
3278 FREE(plhs
[i
]->argtags
);
3279 plhs
[i
]->argtags
= NULL
;
3282 #endif /* defined(YYBTYACC) */
3283 rlhs
[i
] = plhs
[i
]->index
;
3289 ritem
[j
] = pitem
[j
]->index
;
3290 if (pitem
[j
]->class == TERM
)
3292 prec2
= pitem
[j
]->prec
;
3293 assoc
= pitem
[j
]->assoc
;
3297 ritem
[j
] = (Value_t
) - i
;
3299 if (rprec
[i
] == UNDEFINED
)
3309 #if defined(YYBTYACC)
3318 size_t j
, spacing
= 0;
3319 FILE *f
= verbose_file
;
3325 for (i
= 2; i
< nrules
; ++i
)
3327 if (rlhs
[i
] != rlhs
[i
- 1])
3331 fprintf(f
, "%4d %s :", i
- 2, symbol_name
[rlhs
[i
]]);
3332 spacing
= strlen(symbol_name
[rlhs
[i
]]) + 1;
3336 fprintf(f
, "%4d ", i
- 2);
3343 while (ritem
[k
] >= 0)
3345 fprintf(f
, " %s", symbol_name
[ritem
[k
]]);
3353 #if defined(YYBTYACC)
3355 finalize_destructors(void)
3361 for (i
= 2; i
< nsyms
; ++i
)
3363 tag
= symbol_type_tag
[i
];
3364 if (symbol_destructor
[i
] == NULL
)
3367 { /* use <> destructor, if there is one */
3368 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) != NULL
)
3370 symbol_destructor
[i
] = TMALLOC(char,
3371 strlen(bp
->destructor
) + 1);
3372 NO_SPACE(symbol_destructor
[i
]);
3373 strcpy(symbol_destructor
[i
], bp
->destructor
);
3377 { /* use type destructor for this tag, if there is one */
3378 bp
= lookup_type_destructor(tag
);
3379 if (bp
->destructor
!= NULL
)
3381 symbol_destructor
[i
] = TMALLOC(char,
3382 strlen(bp
->destructor
) + 1);
3383 NO_SPACE(symbol_destructor
[i
]);
3384 strcpy(symbol_destructor
[i
], bp
->destructor
);
3387 { /* use <*> destructor, if there is one */
3388 if ((bp
= default_destructor
[TYPED_DEFAULT
]) != NULL
)
3389 /* replace "$$" with "(*val).tag" in destructor code */
3390 symbol_destructor
[i
]
3391 = process_destructor_XX(bp
->destructor
, tag
);
3396 { /* replace "$$" with "(*val)[.tag]" in destructor code */
3397 symbol_destructor
[i
]
3398 = process_destructor_XX(symbol_destructor
[i
], tag
);
3401 /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
3402 DO_FREE(symbol_type_tag
); /* no longer needed */
3403 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) != NULL
)
3406 /* 'bp->tag' is a static value, don't free */
3407 FREE(bp
->destructor
);
3410 if ((bp
= default_destructor
[TYPED_DEFAULT
]) != NULL
)
3413 /* 'bp->tag' is a static value, don't free */
3414 FREE(bp
->destructor
);
3417 if ((bp
= default_destructor
[TYPE_SPECIFIED
]) != NULL
)
3424 /* 'bp->tag' freed by 'free_tags()' */
3425 FREE(bp
->destructor
);
3430 #endif /* defined(YYBTYACC) */
3435 write_section(code_file
, banner
);
3436 create_symbol_table();
3437 read_declarations();
3439 free_symbol_table();
3446 #if defined(YYBTYACC)
3448 finalize_destructors();
3455 free_declarations(param
* list
)
3459 param
*next
= list
->next
;
3472 lex_param
= free_declarations(lex_param
);
3473 parse_param
= free_declarations(parse_param
);
3483 DO_FREE(symbol_name
);
3484 DO_FREE(symbol_prec
);
3485 DO_FREE(symbol_assoc
);
3486 DO_FREE(symbol_value
);
3487 #if defined(YYBTYACC)
3488 DO_FREE(symbol_pval
);
3489 DO_FREE(symbol_destructor
);
3490 DO_FREE(symbol_type_tag
);