1 /* $NetBSD: reader.c,v 1.12 2015/01/04 19:30:26 joerg Exp $ */
3 /* Id: reader.c,v 1.58 2014/10/06 22:15:08 tom Exp */
8 __RCSID("$NetBSD: reader.c,v 1.12 2015/01/04 19:30:26 joerg Exp $");
10 /* The line size must be a positive integer. One hundred was chosen */
11 /* because few lines in Yacc input grammars exceed 100 characters. */
12 /* Note that if a line exceeds LINESIZE characters, the line buffer */
13 /* will be expanded to accomodate it. */
24 /* the maximum number of arguments (inherited attributes) to a non-terminal */
25 /* this is a hard limit, but seems more than adequate */
28 static void start_rule(bucket
*bp
, int s_lineno
);
30 static void copy_initial_action(void);
31 static void copy_destructor(void);
32 static char *process_destructor_XX(char *code
, char *tag
);
36 static int cinc
, cache_size
;
39 static int tagmax
, havetags
;
40 static char **tag_table
;
50 static char last_was_action
;
53 static bucket
**pitem
;
58 static size_t name_pool_size
;
59 static char *name_pool
;
61 char line_format
[] = "#line %d \"%s\"\n";
67 int destructor
= 0; /* =1 if at least one %destructor */
69 static bucket
*default_destructor
[3] =
72 #define UNTYPED_DEFAULT 0
73 #define TYPED_DEFAULT 1
74 #define TYPE_SPECIFIED 2
77 lookup_type_destructor(char *tag
)
79 const char fmt
[] = "%.*s destructor";
80 char name
[1024] = "\0";
81 bucket
*bp
, **bpp
= &default_destructor
[TYPE_SPECIFIED
];
83 while ((bp
= *bpp
) != NULL
)
90 sprintf(name
, fmt
, (int)(sizeof(name
) - sizeof(fmt
)), tag
);
91 *bpp
= bp
= make_bucket(name
);
96 #endif /* defined(YYBTYACC) */
102 if (cinc
>= cache_size
)
105 cache
= TREALLOC(char, cache
, cache_size
);
108 cache
[cinc
] = (char)c
;
115 FILE *f
= input_file
;
119 if (saw_eof
|| (c
= getc(f
)) == EOF
)
131 if (line
== 0 || linesize
!= (LINESIZE
+ 1))
135 linesize
= LINESIZE
+ 1;
136 line
= TMALLOC(char, linesize
);
147 if ((i
+ 3) >= linesize
)
149 linesize
+= LINESIZE
;
150 line
= TREALLOC(char, line
, linesize
);
176 p
= TMALLOC(char, s
- line
+ 1);
181 while ((*t
++ = *s
++) != '\n')
192 a
.a_line
= dup_line();
193 a
.a_cptr
= a
.a_line
+ (cptr
- line
);
198 if (*s
== '*' && s
[1] == '/')
208 unterminated_comment(&a
);
241 else if (s
[1] == '/')
266 switch (ch
= next_inline())
293 static struct keyword
299 { "binary", NONASSOC
},
300 { "debug", XXXDEBUG
},
301 #if defined(YYBTYACC)
302 { "destructor", DESTRUCTOR
},
304 { "error-verbose",ERROR_VERBOSE
},
305 { "expect", EXPECT
},
306 { "expect-rr", EXPECT_RR
},
308 #if defined(YYBTYACC)
309 { "initial-action", INITIAL_ACTION
},
312 { "lex-param", LEX_PARAM
},
313 #if defined(YYBTYACC)
314 { "locations", LOCATIONS
},
316 { "nonassoc", NONASSOC
},
317 { "parse-param", PARSE_PARAM
},
318 { "pure-parser", PURE_PARSER
},
323 { "token-table", TOKEN_TABLE
},
326 { "yacc", POSIX_YACC
},
331 compare_keys(const void *a
, const void *b
)
333 const struct keyword
*p
= (const struct keyword
*)a
;
334 const struct keyword
*q
= (const struct keyword
*)b
;
335 return strcmp(p
->name
, q
->name
);
366 /* treat keywords spelled with '_' as if it were '-' */
377 if ((key
= bsearch(cache
, keywords
,
378 sizeof(keywords
) / sizeof(*key
),
379 sizeof(*key
), compare_keys
)))
387 if (c
== '%' || c
== '\\')
398 syntax_error(lineno
, line
, t_cptr
);
406 FILE *f
= output_file
;
412 syntax_error(lineno
, line
, cptr
);
414 fprintf(f
, "#ident \"");
434 copy_string(int quote
)
436 struct mstring
*temp
= msnew();
440 a
.a_line
= dup_line();
441 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 1);
453 unterminated_string(&a
);
462 unterminated_string(&a
);
471 struct mstring
*temp
= msnew();
478 while ((c
= *++cptr
) != '\n')
481 if (c
== '*' && cptr
[1] == '/')
491 a
.a_line
= dup_line();
492 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 1);
500 if (c
== '*' && *cptr
== '/')
511 unterminated_comment(&a
);
523 int need_newline
= 0;
526 a
.a_line
= dup_line();
527 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 2);
533 unterminated_text(&a
);
536 fprintf(f
, line_format
, lineno
, input_file_name
);
548 unterminated_text(&a
);
554 char *s
= copy_string(c
);
564 char *s
= copy_comment();
591 puts_both(const char *s
)
595 fputs(s
, union_file
);
613 a
.a_line
= dup_line();
614 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 6);
617 over_unionized(cptr
- 6);
621 fprintf(text_file
, line_format
, lineno
, input_file_name
);
623 puts_both("#ifdef YYSTYPE\n");
624 puts_both("#undef YYSTYPE_IS_DECLARED\n");
625 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
626 puts_both("#endif\n");
627 puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
628 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
629 puts_both("typedef union");
640 unterminated_union(&a
);
650 puts_both(" YYSTYPE;\n");
651 puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
660 char *s
= copy_string(c
);
668 char *s
= copy_comment();
680 after_blanks(char *s
)
682 while (*s
!= '\0' && isspace(UCH(*s
)))
688 * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
689 * single space. Return index to last character in the buffer.
692 trim_blanks(char *buffer
)
697 char *s
= after_blanks(d
);
699 while ((*d
++ = *s
++) != '\0')
705 while ((--d
!= buffer
) && isspace(UCH(*d
)))
708 for (s
= d
= buffer
; (*d
++ = *s
++) != '\0';)
710 if (isspace(UCH(*s
)))
713 while (isspace(UCH(*s
)))
722 return (int)strlen(buffer
) - 1;
726 * Scan forward in the current line-buffer looking for a right-curly bracket.
728 * Parameters begin with a left-curly bracket, and continue until there are no
729 * more interesting characters after the last right-curly bracket on the
730 * current line. Bison documents parameters as separated like this:
731 * {type param1} {type2 param2}
732 * but also accepts commas (although some versions of bison mishandle this)
733 * {type param1, type2 param2}
743 switch (next_inline())
762 save_param(int k
, char *buffer
, int name
, int type2
)
766 p
= TMALLOC(param
, 1);
769 p
->type2
= strdup(buffer
+ type2
);
771 buffer
[type2
] = '\0';
772 (void)trim_blanks(p
->type2
);
774 p
->name
= strdup(buffer
+ name
);
777 (void)trim_blanks(p
->name
);
779 p
->type
= strdup(buffer
);
781 (void)trim_blanks(p
->type
);
805 * Keep a linked list of parameters. This may be multi-line, if the trailing
806 * right-curly bracket is absent.
817 int st_lineno
= lineno
;
851 if ((curly
== 1) && (cptr
== line
))
861 if (curly
== 0 && !isspace(UCH(c
)))
869 buf_size
= (size_t) linesize
;
870 buf
= TMALLOC(char, buf_size
);
878 buf_size
+= (size_t) linesize
;
879 buf
= TREALLOC(char, buf
, buf_size
);
884 if ((state
== 2) && (c
== L_CURL
))
888 else if ((state
== 2) && isspace(UCH(c
)))
892 else if ((c
!= L_CURL
) && (c
!= R_CURL
))
899 while (curly
< 2 || more_curly());
912 i
= trim_blanks(buf
);
917 char *parms
= (comma
+ 1);
918 comma
= strchr(parms
, ',');
922 (void)trim_blanks(parms
);
923 i
= (int)strlen(parms
) - 1;
932 while (i
>= 0 && level
> 0 && parms
[i
] != '[')
936 else if (parms
[i
] == '[')
949 while (i
> 0 && (isalnum(UCH(parms
[i
])) || UCH(parms
[i
]) == '_'))
952 if (!isspace(UCH(parms
[i
])) && parms
[i
] != '*')
957 save_param(k
, parms
, name
, type2
);
965 syntax_error(lineno
, line
, cptr
);
971 if (c
>= '0' && c
<= '9')
973 if (c
>= 'A' && c
<= 'F')
974 return (c
- 'A' + 10);
975 if (c
>= 'a' && c
<= 'f')
976 return (c
- 'a' + 10);
990 a
.a_line
= dup_line();
991 a
.a_cptr
= a
.a_line
+ (cptr
- line
);
1001 unterminated_string(&a
);
1004 char *c_cptr
= cptr
- 1;
1012 unterminated_string(&a
);
1027 n
= (n
<< 3) + (c
- '0');
1031 n
= (n
<< 3) + (c
- '0');
1036 illegal_character(c_cptr
);
1043 if (n
< 0 || n
>= 16)
1044 illegal_character(c_cptr
);
1049 if (i
< 0 || i
>= 16)
1054 illegal_character(c_cptr
);
1087 s
= TMALLOC(char, n
);
1090 for (i
= 0; i
< n
; ++i
)
1099 for (i
= 0; i
< n
; ++i
)
1102 if (c
== '\\' || c
== cache
[0])
1107 else if (isprint(c
))
1136 cachec(((c
>> 6) & 7) + '0');
1137 cachec(((c
>> 3) & 7) + '0');
1138 cachec((c
& 7) + '0');
1152 if (n
== 1 && bp
->value
== UNDEFINED
)
1153 bp
->value
= UCH(*s
);
1160 is_reserved(char *name
)
1164 if (strcmp(name
, ".") == 0 ||
1165 strcmp(name
, "$accept") == 0 ||
1166 strcmp(name
, "$end") == 0)
1169 if (name
[0] == '$' && name
[1] == '$' && isdigit(UCH(name
[2])))
1172 while (isdigit(UCH(*s
)))
1187 for (c
= *cptr
; IS_IDENT(c
); c
= *++cptr
)
1191 if (is_reserved(cache
))
1192 used_reserved(cache
);
1194 return (lookup(cache
));
1204 for (c
= *cptr
; isdigit(c
); c
= *++cptr
)
1205 n
= (Value_t
) (10 * n
+ (c
- '0'));
1211 cache_tag(char *tag
, size_t len
)
1216 for (i
= 0; i
< ntags
; ++i
)
1218 if (strncmp(tag
, tag_table
[i
], len
) == 0 &&
1219 tag_table
[i
][len
] == NUL
)
1220 return (tag_table
[i
]);
1223 if (ntags
>= tagmax
)
1228 ? TREALLOC(char *, tag_table
, tagmax
)
1229 : TMALLOC(char *, tagmax
));
1230 NO_SPACE(tag_table
);
1233 s
= TMALLOC(char, len
+ 1);
1236 strncpy(s
, tag
, len
);
1238 tag_table
[ntags
++] = s
;
1246 int t_lineno
= lineno
;
1247 char *t_line
= dup_line();
1248 char *t_cptr
= t_line
+ (cptr
- line
);
1254 if (!isalpha(c
) && c
!= '_' && c
!= '$')
1255 illegal_tag(t_lineno
, t_line
, t_cptr
);
1263 while (IS_IDENT(c
));
1270 illegal_tag(t_lineno
, t_line
, t_cptr
);
1275 return cache_tag(cache
, (size_t) cinc
);
1278 #if defined(YYBTYACC)
1284 while (isalnum((unsigned char)*cptr
) || *cptr
== '_' || *cptr
== '$')
1286 return cache_tag(b
, (size_t) (cptr
- b
));
1291 declare_tokens(int assoc
)
1314 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1316 else if (c
== '\'' || c
== '"')
1322 tokenized_start(bp
->name
);
1327 if (bp
->tag
&& tag
!= bp
->tag
)
1328 retyped_warning(bp
->name
);
1334 if (bp
->prec
&& prec
!= bp
->prec
)
1335 reprec_warning(bp
->name
);
1336 bp
->assoc
= (Assoc_t
) assoc
;
1346 value
= get_number();
1347 if (bp
->value
!= UNDEFINED
&& value
!= bp
->value
)
1348 revalued_warning(bp
->name
);
1358 * %expect requires special handling
1359 * as it really isn't part of the yacc
1360 * grammar only a flag for yacc proper.
1363 declare_expect(int assoc
)
1367 if (assoc
!= EXPECT
&& assoc
!= EXPECT_RR
)
1371 * Stay away from nextc - doesn't
1372 * detect EOL and will read to EOF.
1382 if (assoc
== EXPECT
)
1383 SRexpect
= get_number();
1385 RRexpect
= get_number();
1389 * Looking for number before EOL.
1390 * Spaces, tabs, and numbers are ok,
1391 * words, punc., etc. are syntax errors.
1393 else if (c
== '\n' || isalpha(c
) || !isspace(c
))
1395 syntax_error(lineno
, line
, cptr
);
1406 #if defined(YYBTYACC)
1408 declare_argtypes(bucket
*bp
)
1410 char *tags
[MAXARGS
];
1414 retyped_warning(bp
->name
);
1415 cptr
++; /* skip open paren */
1422 syntax_error(lineno
, line
, cptr
);
1423 tags
[args
++] = get_tag();
1430 cptr
++; /* skip close paren */
1432 bp
->argnames
= TMALLOC(char *, args
);
1433 NO_SPACE(bp
->argnames
);
1434 bp
->argtags
= CALLOC(sizeof(char *), args
+ 1);
1435 NO_SPACE(bp
->argtags
);
1438 bp
->argtags
[args
] = tags
[args
];
1439 bp
->argnames
[args
] = NULL
;
1462 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1465 #if defined(YYBTYACC)
1466 if (nextc() == L_PAREN
)
1467 declare_argtypes(bp
);
1472 else if (c
== '\'' || c
== '"')
1475 #if defined(YYBTYACC)
1484 if (bp
->tag
&& tag
!= bp
->tag
)
1485 retyped_warning(bp
->name
);
1500 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '$')
1501 syntax_error(lineno
, line
, cptr
);
1503 if (bp
->class == TERM
)
1504 terminal_start(bp
->name
);
1505 if (goal
&& goal
!= bp
)
1506 restarted_warning();
1511 read_declarations(void)
1516 cache
= TMALLOC(char, cache_size
);
1525 syntax_error(lineno
, line
, cptr
);
1526 switch (k
= keyword())
1580 #if defined(YYBTYACC)
1589 case INITIAL_ACTION
:
1590 copy_initial_action();
1599 /* noop for bison compatibility. byacc is already designed to be posix
1600 * yacc compatible. */
1607 initialize_grammar(void)
1612 pitem
= TMALLOC(bucket
*, maxitems
);
1623 plhs
= TMALLOC(bucket
*, maxrules
);
1630 rprec
= TMALLOC(Value_t
, maxrules
);
1637 rassoc
= TMALLOC(Assoc_t
, maxrules
);
1649 pitem
= TREALLOC(bucket
*, pitem
, maxitems
);
1658 plhs
= TREALLOC(bucket
*, plhs
, maxrules
);
1661 rprec
= TREALLOC(Value_t
, rprec
, maxrules
);
1664 rassoc
= TREALLOC(Assoc_t
, rassoc
, maxrules
);
1668 /* set immediately prior to where copy_args() could be called, and incremented by
1669 the various routines that will rescan the argument list as appropriate */
1670 static int rescan_lineno
;
1671 #if defined(YYBTYACC)
1674 copy_args(int *alen
)
1676 struct mstring
*s
= msnew();
1677 int depth
= 0, len
= 1;
1681 a
.a_lineno
= lineno
;
1682 a
.a_line
= dup_line();
1683 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 1);
1685 while ((c
= *cptr
++) != R_PAREN
|| depth
|| quote
)
1687 if (c
== ',' && !quote
&& !depth
)
1700 unterminated_string(&a
);
1702 unterminated_arglist(&a
);
1719 else if (c
== R_PAREN
)
1721 else if (c
== '\"' || c
== '\'')
1732 parse_id(char *p
, char **save
)
1736 while (isspace((unsigned char)*p
))
1739 if (!isalpha((unsigned char)*p
) && *p
!= '_')
1742 while (isalnum((unsigned char)*p
) || *p
== '_' || *p
== '$')
1746 *save
= cache_tag(b
, (size_t) (p
- b
));
1752 parse_int(char *p
, int *save
)
1754 int neg
= 0, val
= 0;
1756 while (isspace((unsigned char)*p
))
1764 if (!isdigit((unsigned char)*p
))
1766 while (isdigit((unsigned char)*p
))
1767 val
= val
* 10 + *p
++ - '0';
1776 parse_arginfo(bucket
*a
, char *args
, int argslen
)
1778 char *p
= args
, *tmp
;
1783 if (a
->args
!= argslen
)
1784 arg_number_disagree_warning(rescan_lineno
, a
->name
);
1789 if ((a
->args
= argslen
) == 0)
1791 a
->argnames
= TMALLOC(char *, argslen
);
1792 NO_SPACE(a
->argnames
);
1793 a
->argtags
= TMALLOC(char *, argslen
);
1794 NO_SPACE(a
->argtags
);
1798 for (i
= 0; i
< argslen
; i
++)
1800 while (isspace((unsigned char)*p
))
1805 while (isspace((unsigned char)*p
))
1811 if (!(p
= parse_id(p
+ 1, &tmp
)))
1813 while (isspace((unsigned char)*p
))
1820 if (a
->argtags
[i
] != tmp
)
1821 arg_type_disagree_warning(rescan_lineno
, i
+ 1, a
->name
);
1824 a
->argtags
[i
] = tmp
;
1827 a
->argtags
[i
] = NULL
;
1828 if (!(p
= parse_id(p
, &a
->argnames
[i
])))
1830 while (isspace((unsigned char)*p
))
1840 compile_arg(char **theptr
, char *yyvaltag
)
1843 struct mstring
*c
= msnew();
1845 Value_t
*offsets
= NULL
, maxoffset
;
1850 for (i
= nitems
- 1; pitem
[i
]; --i
)
1853 if (pitem
[i
]->class != ARGUMENT
)
1858 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
1861 for (j
= 0, i
++; i
< nitems
; i
++)
1862 if (pitem
[i
]->class != ARGUMENT
)
1863 offsets
[++j
] = (Value_t
) (i
- nitems
+ 1);
1865 rhs
= pitem
+ nitems
- 1;
1868 msprintf(c
, "yyval.%s = ", yyvaltag
);
1870 msprintf(c
, "yyval = ");
1877 if (!(p
= parse_id(++p
, &tag
)) || *p
++ != '>')
1878 illegal_tag(rescan_lineno
, NULL
, NULL
);
1879 if (isdigit((unsigned char)*p
) || *p
== '-')
1882 if (!(p
= parse_int(p
, &val
)))
1883 dollar_error(rescan_lineno
, NULL
, NULL
);
1886 else if (val
> maxoffset
)
1888 dollar_warning(rescan_lineno
, val
);
1889 i
= val
- maxoffset
;
1891 else if (maxoffset
> 0)
1894 if (!tag
&& !(tag
= rhs
[i
]->tag
) && havetags
)
1895 untyped_rhs(val
, rhs
[i
]->name
);
1897 msprintf(c
, "yystack.l_mark[%d]", i
);
1899 msprintf(c
, ".%s", tag
);
1903 else if (isalpha((unsigned char)*p
) || *p
== '_')
1906 if (!(p
= parse_id(p
, &arg
)))
1907 dollar_error(rescan_lineno
, NULL
, NULL
);
1908 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
1909 if (arg
== plhs
[nrules
]->argnames
[i
])
1912 unknown_arg_warning(rescan_lineno
, "$", arg
, NULL
, NULL
);
1914 tag
= plhs
[nrules
]->argtags
[i
];
1915 msprintf(c
, "yystack.l_mark[%d]", i
- plhs
[nrules
]->args
+ 1
1918 msprintf(c
, ".%s", tag
);
1920 untyped_arg_warning(rescan_lineno
, "$", arg
);
1923 dollar_error(rescan_lineno
, NULL
, NULL
);
1927 at_error(rescan_lineno
, NULL
, NULL
);
1942 #define ARG_CACHE_SIZE 1024
1943 static struct arg_cache
1945 struct arg_cache
*next
;
1949 *arg_cache
[ARG_CACHE_SIZE
];
1952 lookup_arg_cache(char *code
)
1954 struct arg_cache
*entry
;
1956 entry
= arg_cache
[strnshash(code
) % ARG_CACHE_SIZE
];
1959 if (!strnscmp(entry
->code
, code
))
1961 entry
= entry
->next
;
1967 insert_arg_cache(char *code
, int rule
)
1969 struct arg_cache
*entry
= NEW(struct arg_cache
);
1973 i
= strnshash(code
) % ARG_CACHE_SIZE
;
1976 entry
->next
= arg_cache
[i
];
1977 arg_cache
[i
] = entry
;
1981 clean_arg_cache(void)
1983 struct arg_cache
*e
, *t
;
1986 for (i
= 0; i
< ARG_CACHE_SIZE
; i
++)
1988 for (e
= arg_cache
[i
]; (t
= e
); e
= e
->next
, FREE(t
))
1990 arg_cache
[i
] = NULL
;
1996 advance_to_start(void)
2002 #if defined(YYBTYACC)
2027 syntax_error(lineno
, line
, s_cptr
);
2032 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '_')
2033 syntax_error(lineno
, line
, cptr
);
2037 if (bp
->class == TERM
)
2038 terminal_start(bp
->name
);
2046 rescan_lineno
= lineno
; /* line# for possible inherited args rescan */
2047 #if defined(YYBTYACC)
2051 args
= copy_args(&argslen
);
2057 syntax_error(lineno
, line
, cptr
);
2058 start_rule(bp
, s_lineno
);
2059 #if defined(YYBTYACC)
2060 parse_arginfo(bp
, args
, argslen
);
2066 start_rule(bucket
*bp
, int s_lineno
)
2068 if (bp
->class == TERM
)
2069 terminal_lhs(s_lineno
);
2070 bp
->class = NONTERM
;
2073 if (nrules
>= maxrules
)
2076 rprec
[nrules
] = UNDEFINED
;
2077 rassoc
[nrules
] = TOKEN
;
2085 if (!last_was_action
&& plhs
[nrules
]->tag
)
2087 if (pitem
[nitems
- 1])
2089 for (i
= nitems
- 1; (i
> 0) && pitem
[i
]; --i
)
2091 if (pitem
[i
+ 1] == 0 || pitem
[i
+ 1]->tag
!= plhs
[nrules
]->tag
)
2092 default_action_warning();
2096 default_action_warning();
2100 last_was_action
= 0;
2101 if (nitems
>= maxitems
)
2109 insert_empty_rule(void)
2114 sprintf(cache
, "$$%d", ++gensym
);
2115 bp
= make_bucket(cache
);
2116 last_symbol
->next
= bp
;
2118 bp
->tag
= plhs
[nrules
]->tag
;
2120 #if defined(YYBTYACC)
2124 nitems
= (Value_t
) (nitems
+ 2);
2125 if (nitems
> maxitems
)
2127 bpp
= pitem
+ nitems
- 1;
2129 while ((bpp
[0] = bpp
[-1]) != 0)
2132 if (++nrules
>= maxrules
)
2134 plhs
[nrules
] = plhs
[nrules
- 1];
2135 plhs
[nrules
- 1] = bp
;
2136 rprec
[nrules
] = rprec
[nrules
- 1];
2137 rprec
[nrules
- 1] = 0;
2138 rassoc
[nrules
] = rassoc
[nrules
- 1];
2139 rassoc
[nrules
- 1] = TOKEN
;
2142 #if defined(YYBTYACC)
2144 insert_arg_rule(char *arg
, char *tag
)
2146 int line_number
= rescan_lineno
;
2147 char *code
= compile_arg(&arg
, tag
);
2148 int rule
= lookup_arg_cache(code
);
2149 FILE *f
= action_file
;
2154 insert_arg_cache(code
, rule
);
2155 fprintf(f
, "case %d:\n", rule
- 2);
2157 fprintf(f
, line_format
, line_number
, input_file_name
);
2158 fprintf(f
, "%s;\n", code
);
2159 fprintf(f
, "break;\n");
2160 insert_empty_rule();
2161 plhs
[rule
]->tag
= tag
;
2162 plhs
[rule
]->class = ARGUMENT
;
2166 if (++nitems
> maxitems
)
2168 pitem
[nitems
- 1] = plhs
[rule
];
2180 int s_lineno
= lineno
;
2181 #if defined(YYBTYACC)
2187 if (c
== '\'' || c
== '"')
2193 rescan_lineno
= lineno
; /* line# for possible inherited args rescan */
2194 #if defined(YYBTYACC)
2198 args
= copy_args(&argslen
);
2206 start_rule(bp
, s_lineno
);
2207 #if defined(YYBTYACC)
2208 parse_arginfo(bp
, args
, argslen
);
2214 if (last_was_action
)
2215 insert_empty_rule();
2216 last_was_action
= 0;
2218 #if defined(YYBTYACC)
2221 if (argslen
== 0 && bp
->args
> 0 && pitem
[nitems
- 1] == NULL
)
2224 if (plhs
[nrules
]->args
!= bp
->args
)
2225 wrong_number_args_warning("default ", bp
->name
);
2226 for (i
= bp
->args
- 1; i
>= 0; i
--)
2227 if (plhs
[nrules
]->argtags
[i
] != bp
->argtags
[i
])
2228 wrong_type_for_arg_warning(i
+ 1, bp
->name
);
2230 else if (bp
->args
!= argslen
)
2231 wrong_number_args_warning("", bp
->name
);
2232 if (bp
->args
> 0 && argslen
> 0)
2236 for (ap
= args
, i
= 0; i
< argslen
; i
++)
2237 ap
= insert_arg_rule(ap
, bp
->argtags
[i
]);
2240 #endif /* defined(YYBTYACC) */
2242 if (++nitems
> maxitems
)
2244 pitem
[nitems
- 1] = bp
;
2253 #if defined(YYBTYACC)
2254 int trialaction
= 0;
2258 FILE *f
= action_file
;
2260 Value_t
*offsets
= NULL
, maxoffset
;
2263 a
.a_lineno
= lineno
;
2264 a
.a_line
= dup_line();
2265 a
.a_cptr
= a
.a_line
+ (cptr
- line
);
2267 if (last_was_action
)
2268 insert_empty_rule();
2269 last_was_action
= 1;
2271 fprintf(f
, "case %d:\n", nrules
- 2);
2272 #if defined(YYBTYACC)
2275 if (*cptr
!= L_BRAC
)
2276 fprintf(f
, " if (!yytrial)\n");
2282 fprintf(f
, line_format
, lineno
, input_file_name
);
2286 /* avoid putting curly-braces in first column, to ease editing */
2287 if (*after_blanks(cptr
) == L_CURL
)
2290 cptr
= after_blanks(cptr
);
2295 for (i
= nitems
- 1; pitem
[i
]; --i
)
2298 if (pitem
[i
]->class != ARGUMENT
)
2303 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
2306 for (j
= 0, i
++; i
< nitems
; i
++)
2308 if (pitem
[i
]->class != ARGUMENT
)
2310 offsets
[++j
] = (Value_t
) (i
- nitems
+ 1);
2314 rhs
= pitem
+ nitems
- 1;
2323 int d_lineno
= lineno
;
2324 char *d_line
= dup_line();
2325 char *d_cptr
= d_line
+ (cptr
- line
);
2332 fprintf(f
, "yyval.%s", tag
);
2337 else if (isdigit(c
))
2341 fprintf(f
, "yystack.l_mark[%d].%s", -n
, tag
);
2342 else if (i
> maxoffset
)
2344 dollar_warning(d_lineno
, i
);
2345 fprintf(f
, "yystack.l_mark[%d].%s", i
- maxoffset
, tag
);
2348 fprintf(f
, "yystack.l_mark[%d].%s", offsets
[i
], tag
);
2352 else if (c
== '-' && isdigit(UCH(cptr
[1])))
2355 i
= -get_number() - n
;
2356 fprintf(f
, "yystack.l_mark[%d].%s", i
, tag
);
2360 #if defined(YYBTYACC)
2361 else if (isalpha(c
) || c
== '_')
2363 char *arg
= scan_id();
2364 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2365 if (arg
== plhs
[nrules
]->argnames
[i
])
2368 unknown_arg_warning(d_lineno
, "$", arg
, d_line
, d_cptr
);
2369 fprintf(f
, "yystack.l_mark[%d].%s", i
- plhs
[nrules
]->args
+
2376 dollar_error(d_lineno
, d_line
, d_cptr
);
2378 else if (cptr
[1] == '$')
2382 tag
= plhs
[nrules
]->tag
;
2385 fprintf(f
, "yyval.%s", tag
);
2388 fprintf(f
, "yyval");
2390 #if defined(YYBTYACC)
2395 else if (isdigit(UCH(cptr
[1])))
2399 if (havetags
&& offsets
)
2401 if (i
<= 0 || i
> maxoffset
)
2403 tag
= rhs
[offsets
[i
]]->tag
;
2405 untyped_rhs(i
, rhs
[offsets
[i
]]->name
);
2406 fprintf(f
, "yystack.l_mark[%d].%s", offsets
[i
], tag
);
2411 fprintf(f
, "yystack.l_mark[%d]", -n
);
2412 else if (i
> maxoffset
)
2414 dollar_warning(lineno
, i
);
2415 fprintf(f
, "yystack.l_mark[%d]", i
- maxoffset
);
2418 fprintf(f
, "yystack.l_mark[%d]", offsets
[i
]);
2422 else if (cptr
[1] == '-')
2428 fprintf(f
, "yystack.l_mark[%d]", -i
- n
);
2431 #if defined(YYBTYACC)
2432 else if (isalpha((unsigned char)cptr
[1]) || cptr
[1] == '_')
2437 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2438 if (arg
== plhs
[nrules
]->argnames
[i
])
2441 unknown_arg_warning(lineno
, "$", arg
, line
, cptr
);
2442 tag
= (i
< 0 ? NULL
: plhs
[nrules
]->argtags
[i
]);
2443 fprintf(f
, "yystack.l_mark[%d]", i
- plhs
[nrules
]->args
+ 1 - n
);
2445 fprintf(f
, ".%s", tag
);
2447 untyped_arg_warning(lineno
, "$", arg
);
2452 #if defined(YYBTYACC)
2457 int l_lineno
= lineno
;
2458 char *l_line
= dup_line();
2459 char *l_cptr
= l_line
+ (cptr
- line
);
2460 syntax_error(l_lineno
, l_line
, l_cptr
);
2464 fprintf(f
, "yyloc");
2468 else if (isdigit(UCH(cptr
[1])))
2473 fprintf(f
, "yystack.p_mark[%d]", -n
);
2474 else if (i
> maxoffset
)
2476 at_warning(lineno
, i
);
2477 fprintf(f
, "yystack.p_mark[%d]", i
- maxoffset
);
2480 fprintf(f
, "yystack.p_mark[%d]", offsets
[i
]);
2485 if (isalpha(c
) || c
== '_' || c
== '$')
2492 while (isalnum(c
) || c
== '_' || c
== '$');
2496 #if defined(YYBTYACC)
2499 if (trialaction
&& c
== L_BRAC
&& depth
== 0)
2505 if (trialaction
&& c
== R_BRAC
&& depth
== 1)
2510 if (c
== L_BRAC
&& !haveyyval
)
2514 if (c
== L_CURL
&& !haveyyval
)
2516 fprintf(f
, " if (!yytrial)\n");
2518 fprintf(f
, line_format
, lineno
, input_file_name
);
2522 fprintf(f
, "\nbreak;\n");
2537 unterminated_action(&a
);
2542 fprintf(f
, "\nbreak;\n");
2548 #if defined(YYBTYACC)
2567 #if defined(YYBTYACC)
2571 if (c
== L_BRAC
&& !haveyyval
)
2576 if (c
== L_CURL
&& !haveyyval
)
2578 fprintf(f
, " if (!yytrial)\n");
2580 fprintf(f
, line_format
, lineno
, input_file_name
);
2585 fprintf(f
, "\nbreak;\n");
2594 char *s
= copy_string(c
);
2602 char *s
= copy_comment();
2613 #if defined(YYBTYACC)
2615 get_code(struct ainfo
*a
, const char *loc
)
2620 struct mstring
*code_mstr
= msnew();
2623 msprintf(code_mstr
, line_format
, lineno
, input_file_name
);
2625 cptr
= after_blanks(cptr
);
2626 if (*cptr
== L_CURL
)
2627 /* avoid putting curly-braces in first column, to ease editing */
2628 mputc(code_mstr
, '\t');
2630 syntax_error(lineno
, line
, cptr
);
2632 a
->a_lineno
= lineno
;
2633 a
->a_line
= dup_line();
2634 a
->a_cptr
= a
->a_line
+ (cptr
- line
);
2643 int d_lineno
= lineno
;
2644 char *d_line
= dup_line();
2645 char *d_cptr
= d_line
+ (cptr
- line
);
2652 msprintf(code_mstr
, "(*val).%s", tag
);
2658 dollar_error(d_lineno
, d_line
, d_cptr
);
2660 else if (cptr
[1] == '$')
2662 /* process '$$' later; replacement is context dependent */
2663 msprintf(code_mstr
, "$$");
2668 if (c
== '@' && cptr
[1] == '$')
2672 int l_lineno
= lineno
;
2673 char *l_line
= dup_line();
2674 char *l_cptr
= l_line
+ (cptr
- line
);
2675 syntax_error(l_lineno
, l_line
, l_cptr
);
2677 msprintf(code_mstr
, "%s", loc
);
2681 if (isalpha(c
) || c
== '_' || c
== '$')
2685 mputc(code_mstr
, c
);
2688 while (isalnum(c
) || c
== '_' || c
== '$');
2692 mputc(code_mstr
, c
);
2699 unterminated_action(a
);
2713 char *s
= copy_string(c
);
2714 msprintf(code_mstr
, "%s", s
);
2721 char *s
= copy_comment();
2722 msprintf(code_mstr
, "%s", s
);
2731 return msdone(code_mstr
);
2735 copy_initial_action(void)
2739 initial_action
= get_code(&a
, "yyloc");
2744 copy_destructor(void)
2751 code_text
= get_code(&a
, "(*loc)");
2761 { /* "no semantic type" default destructor */
2763 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) == NULL
)
2765 static char untyped_default
[] = "<>";
2766 bp
= make_bucket("untyped default");
2767 bp
->tag
= untyped_default
;
2768 default_destructor
[UNTYPED_DEFAULT
] = bp
;
2770 if (bp
->destructor
!= NULL
)
2771 destructor_redeclared_warning(&a
);
2773 /* replace "$$" with "(*val)" in destructor code */
2774 bp
->destructor
= process_destructor_XX(code_text
, NULL
);
2776 else if (cptr
[1] == '*' && cptr
[2] == '>')
2777 { /* "no per-symbol or per-type" default destructor */
2779 if ((bp
= default_destructor
[TYPED_DEFAULT
]) == NULL
)
2781 static char typed_default
[] = "<*>";
2782 bp
= make_bucket("typed default");
2783 bp
->tag
= typed_default
;
2784 default_destructor
[TYPED_DEFAULT
] = bp
;
2786 if (bp
->destructor
!= NULL
)
2787 destructor_redeclared_warning(&a
);
2790 /* postpone re-processing destructor $$s until end of grammar spec */
2791 bp
->destructor
= TMALLOC(char, strlen(code_text
) + 1);
2792 NO_SPACE(bp
->destructor
);
2793 strcpy(bp
->destructor
, code_text
);
2797 { /* "semantic type" default destructor */
2798 char *tag
= get_tag();
2799 bp
= lookup_type_destructor(tag
);
2800 if (bp
->destructor
!= NULL
)
2801 destructor_redeclared_warning(&a
);
2803 /* replace "$$" with "(*val).tag" in destructor code */
2804 bp
->destructor
= process_destructor_XX(code_text
, tag
);
2807 else if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
2808 { /* "symbol" destructor */
2810 if (bp
->destructor
!= NULL
)
2811 destructor_redeclared_warning(&a
);
2814 /* postpone re-processing destructor $$s until end of grammar spec */
2815 bp
->destructor
= TMALLOC(char, strlen(code_text
) + 1);
2816 NO_SPACE(bp
->destructor
);
2817 strcpy(bp
->destructor
, code_text
);
2828 process_destructor_XX(char *code
, char *tag
)
2833 struct mstring
*new_code
= msnew();
2834 char *codeptr
= code
;
2837 loop
: /* step thru code */
2839 if (c
== '$' && codeptr
[1] == '$')
2843 msprintf(new_code
, "(*val)");
2845 msprintf(new_code
, "(*val).%s", tag
);
2848 if (isalpha(c
) || c
== '_' || c
== '$')
2855 while (isalnum(c
) || c
== '_' || c
== '$');
2869 return msdone(new_code
);
2897 if (c
== '*' && *codeptr
== '/')
2899 mputc(new_code
, '/');
2911 #endif /* defined(YYBTYACC) */
2920 if (c
== '%' || c
== '\\')
2928 else if ((c
== 'p' || c
== 'P') &&
2929 ((c
= cptr
[2]) == 'r' || c
== 'R') &&
2930 ((c
= cptr
[3]) == 'e' || c
== 'E') &&
2931 ((c
= cptr
[4]) == 'c' || c
== 'C') &&
2932 ((c
= cptr
[5], !IS_IDENT(c
))))
2935 syntax_error(lineno
, line
, cptr
);
2938 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
2940 else if (c
== '\'' || c
== '"')
2944 syntax_error(lineno
, line
, cptr
);
2947 if (rprec
[nrules
] != UNDEFINED
&& bp
->prec
!= rprec
[nrules
])
2950 rprec
[nrules
] = bp
->prec
;
2951 rassoc
[nrules
] = bp
->assoc
;
2960 initialize_grammar();
2975 #if defined(YYBTYACC)
2976 else if (c
== L_CURL
|| c
== '=' || (backtrack
&& c
== L_BRAC
))
2978 else if (c
== L_CURL
|| c
== '=')
2984 start_rule(plhs
[nrules
- 1], 0);
2993 syntax_error(lineno
, line
, cptr
);
2996 #if defined(YYBTYACC)
2998 start_requires_args(goal
->name
);
3010 for (i
= 0; i
< ntags
; ++i
)
3012 assert(tag_table
[i
]);
3024 name_pool_size
= 13; /* 13 == sizeof("$end") + sizeof("$accept") */
3025 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3026 name_pool_size
+= strlen(bp
->name
) + 1;
3028 name_pool
= TMALLOC(char, name_pool_size
);
3029 NO_SPACE(name_pool
);
3031 strlcpy(name_pool
, "$accept", name_pool_size
);
3032 strlcpy(name_pool
+ 8, "$end", name_pool_size
- 8);
3034 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3038 while ((*t
++ = *s
++) != 0)
3050 if (goal
->class == UNKNOWN
)
3051 undefined_goal(goal
->name
);
3053 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3055 if (bp
->class == UNKNOWN
)
3057 undefined_symbol_warning(bp
->name
);
3064 protect_string(char *src
, char **des
)
3077 if ('\\' == *s
|| '"' == *s
)
3083 *des
= d
= TMALLOC(char, len
);
3089 if ('\\' == *s
|| '"' == *s
)
3103 #if defined(YYBTYACC)
3104 Value_t max_tok_pval
;
3109 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3112 if (bp
->class == TERM
)
3115 start_symbol
= (Value_t
) ntokens
;
3116 nvars
= (Value_t
) (nsyms
- ntokens
);
3118 symbol_name
= TMALLOC(char *, nsyms
);
3119 NO_SPACE(symbol_name
);
3121 symbol_value
= TMALLOC(Value_t
, nsyms
);
3122 NO_SPACE(symbol_value
);
3124 symbol_prec
= TMALLOC(Value_t
, nsyms
);
3125 NO_SPACE(symbol_prec
);
3127 symbol_assoc
= TMALLOC(char, nsyms
);
3128 NO_SPACE(symbol_assoc
);
3130 #if defined(YYBTYACC)
3131 symbol_pval
= TMALLOC(Value_t
, nsyms
);
3132 NO_SPACE(symbol_pval
);
3136 symbol_destructor
= CALLOC(sizeof(char *), nsyms
);
3137 NO_SPACE(symbol_destructor
);
3139 symbol_type_tag
= CALLOC(sizeof(char *), nsyms
);
3140 NO_SPACE(symbol_type_tag
);
3144 v
= TMALLOC(bucket
*, nsyms
);
3148 v
[start_symbol
] = 0;
3151 j
= (Value_t
) (start_symbol
+ 1);
3152 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3154 if (bp
->class == TERM
)
3159 assert(i
== ntokens
&& j
== nsyms
);
3161 for (i
= 1; i
< ntokens
; ++i
)
3164 goal
->index
= (Index_t
) (start_symbol
+ 1);
3165 k
= (Value_t
) (start_symbol
+ 2);
3175 for (i
= (Value_t
) (start_symbol
+ 1); i
< nsyms
; ++i
)
3185 for (i
= 1; i
< ntokens
; ++i
)
3190 for (j
= k
++; j
> 0 && symbol_value
[j
- 1] > n
; --j
)
3191 symbol_value
[j
] = symbol_value
[j
- 1];
3192 symbol_value
[j
] = n
;
3198 if (v
[1]->value
== UNDEFINED
)
3203 for (i
= 2; i
< ntokens
; ++i
)
3205 if (v
[i
]->value
== UNDEFINED
)
3207 while (j
< k
&& n
== symbol_value
[j
])
3209 while (++j
< k
&& n
== symbol_value
[j
])
3218 symbol_name
[0] = name_pool
+ 8;
3219 symbol_value
[0] = 0;
3221 symbol_assoc
[0] = TOKEN
;
3222 #if defined(YYBTYACC)
3226 for (i
= 1; i
< ntokens
; ++i
)
3228 symbol_name
[i
] = v
[i
]->name
;
3229 symbol_value
[i
] = v
[i
]->value
;
3230 symbol_prec
[i
] = v
[i
]->prec
;
3231 symbol_assoc
[i
] = v
[i
]->assoc
;
3232 #if defined(YYBTYACC)
3233 symbol_pval
[i
] = v
[i
]->value
;
3234 if (symbol_pval
[i
] > max_tok_pval
)
3235 max_tok_pval
= symbol_pval
[i
];
3238 symbol_destructor
[i
] = v
[i
]->destructor
;
3239 symbol_type_tag
[i
] = v
[i
]->tag
;
3243 symbol_name
[start_symbol
] = name_pool
;
3244 symbol_value
[start_symbol
] = -1;
3245 symbol_prec
[start_symbol
] = 0;
3246 symbol_assoc
[start_symbol
] = TOKEN
;
3247 #if defined(YYBTYACC)
3248 symbol_pval
[start_symbol
] = (Value_t
) (max_tok_pval
+ 1);
3250 for (++i
; i
< nsyms
; ++i
)
3253 symbol_name
[k
] = v
[i
]->name
;
3254 symbol_value
[k
] = v
[i
]->value
;
3255 symbol_prec
[k
] = v
[i
]->prec
;
3256 symbol_assoc
[k
] = v
[i
]->assoc
;
3257 #if defined(YYBTYACC)
3258 symbol_pval
[k
] = (Value_t
) ((max_tok_pval
+ 1) + v
[i
]->value
+ 1);
3261 symbol_destructor
[k
] = v
[i
]->destructor
;
3262 symbol_type_tag
[k
] = v
[i
]->tag
;
3269 symbol_pname
= TMALLOC(char *, nsyms
);
3270 NO_SPACE(symbol_pname
);
3272 for (i
= 0; i
< nsyms
; ++i
)
3273 protect_string(symbol_name
[i
], &(symbol_pname
[i
]));
3287 ritem
= TMALLOC(Value_t
, nitems
);
3290 rlhs
= TMALLOC(Value_t
, nrules
);
3293 rrhs
= TMALLOC(Value_t
, nrules
+ 1);
3296 rprec
= TREALLOC(Value_t
, rprec
, nrules
);
3299 rassoc
= TREALLOC(Assoc_t
, rassoc
, nrules
);
3303 ritem
[1] = goal
->index
;
3308 rlhs
[2] = start_symbol
;
3314 for (i
= 3; i
< nrules
; ++i
)
3316 #if defined(YYBTYACC)
3317 if (plhs
[i
]->args
> 0)
3319 if (plhs
[i
]->argnames
)
3321 FREE(plhs
[i
]->argnames
);
3322 plhs
[i
]->argnames
= NULL
;
3324 if (plhs
[i
]->argtags
)
3326 FREE(plhs
[i
]->argtags
);
3327 plhs
[i
]->argtags
= NULL
;
3330 #endif /* defined(YYBTYACC) */
3331 rlhs
[i
] = plhs
[i
]->index
;
3337 ritem
[j
] = pitem
[j
]->index
;
3338 if (pitem
[j
]->class == TERM
)
3340 prec2
= pitem
[j
]->prec
;
3341 assoc
= pitem
[j
]->assoc
;
3345 ritem
[j
] = (Value_t
) - i
;
3347 if (rprec
[i
] == UNDEFINED
)
3357 #if defined(YYBTYACC)
3366 size_t j
, spacing
= 0;
3367 FILE *f
= verbose_file
;
3373 for (i
= 2; i
< nrules
; ++i
)
3375 if (rlhs
[i
] != rlhs
[i
- 1])
3379 fprintf(f
, "%4d %s :", i
- 2, symbol_name
[rlhs
[i
]]);
3380 spacing
= strlen(symbol_name
[rlhs
[i
]]) + 1;
3384 fprintf(f
, "%4d ", i
- 2);
3391 while (ritem
[k
] >= 0)
3393 fprintf(f
, " %s", symbol_name
[ritem
[k
]]);
3401 #if defined(YYBTYACC)
3403 finalize_destructors(void)
3409 for (i
= 2; i
< nsyms
; ++i
)
3411 tag
= symbol_type_tag
[i
];
3412 if (symbol_destructor
[i
] == NULL
)
3415 { /* use <> destructor, if there is one */
3416 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) != NULL
)
3418 symbol_destructor
[i
] = TMALLOC(char,
3419 strlen(bp
->destructor
) + 1);
3420 NO_SPACE(symbol_destructor
[i
]);
3421 strcpy(symbol_destructor
[i
], bp
->destructor
);
3425 { /* use type destructor for this tag, if there is one */
3426 bp
= lookup_type_destructor(tag
);
3427 if (bp
->destructor
!= NULL
)
3429 symbol_destructor
[i
] = TMALLOC(char,
3430 strlen(bp
->destructor
) + 1);
3431 NO_SPACE(symbol_destructor
[i
]);
3432 strcpy(symbol_destructor
[i
], bp
->destructor
);
3435 { /* use <*> destructor, if there is one */
3436 if ((bp
= default_destructor
[TYPED_DEFAULT
]) != NULL
)
3437 /* replace "$$" with "(*val).tag" in destructor code */
3438 symbol_destructor
[i
]
3439 = process_destructor_XX(bp
->destructor
, tag
);
3444 { /* replace "$$" with "(*val)[.tag]" in destructor code */
3445 symbol_destructor
[i
]
3446 = process_destructor_XX(symbol_destructor
[i
], tag
);
3449 /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
3450 DO_FREE(symbol_type_tag
); /* no longer needed */
3451 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) != NULL
)
3454 /* 'bp->tag' is a static value, don't free */
3455 FREE(bp
->destructor
);
3458 if ((bp
= default_destructor
[TYPED_DEFAULT
]) != NULL
)
3461 /* 'bp->tag' is a static value, don't free */
3462 FREE(bp
->destructor
);
3465 if ((bp
= default_destructor
[TYPE_SPECIFIED
]) != NULL
)
3472 /* 'bp->tag' freed by 'free_tags()' */
3473 FREE(bp
->destructor
);
3478 #endif /* defined(YYBTYACC) */
3483 write_section(code_file
, banner
);
3484 create_symbol_table();
3485 read_declarations();
3487 free_symbol_table();
3494 #if defined(YYBTYACC)
3496 finalize_destructors();
3503 free_declarations(param
* list
)
3507 param
*next
= list
->next
;
3520 lex_param
= free_declarations(lex_param
);
3521 parse_param
= free_declarations(parse_param
);
3531 DO_FREE(symbol_name
);
3532 DO_FREE(symbol_prec
);
3533 DO_FREE(symbol_assoc
);
3534 DO_FREE(symbol_value
);
3535 #if defined(YYBTYACC)
3536 DO_FREE(symbol_pval
);
3537 DO_FREE(symbol_destructor
);
3538 DO_FREE(symbol_type_tag
);