1 /* $Id: reader.c,v 1.73 2017/07/09 19:15:35 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_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";
66 int destructor
= 0; /* =1 if at least one %destructor */
68 static bucket
*default_destructor
[3] =
71 #define UNTYPED_DEFAULT 0
72 #define TYPED_DEFAULT 1
73 #define TYPE_SPECIFIED 2
76 lookup_type_destructor(char *tag
)
78 const char fmt
[] = "%.*s destructor";
79 char name
[1024] = "\0";
80 bucket
*bp
, **bpp
= &default_destructor
[TYPE_SPECIFIED
];
82 while ((bp
= *bpp
) != NULL
)
89 sprintf(name
, fmt
, (int)(sizeof(name
) - sizeof(fmt
)), tag
);
90 *bpp
= bp
= make_bucket(name
);
95 #endif /* defined(YYBTYACC) */
101 if (cinc
>= cache_size
)
103 cache_size
+= CACHE_SIZE
;
104 cache
= TREALLOC(char, cache
, cache_size
);
107 cache
[cinc
] = (char)c
;
126 * Expect this pattern:
127 * /^[[:space:]]*#[[:space:]]*
130 * ([[:space:]]*|[[:space:]]+"[^"]+")/
135 #define UNLESS(what) if (what) { ld = ldERR; break; }
140 LINE_DIR ld
= ldSPC1
;
141 for (n
= 0; (ld
<= ldOK
) && (line
[n
] != '\0'); ++n
)
143 int ch
= UCH(line
[n
]);
147 if (isspace(UCH(ch
)))
156 if (isspace(UCH(ch
)))
162 UNLESS(strncmp(line
+ n
, "line", 4));
170 UNLESS(!isspace(UCH(line
[n
])));
174 if (isspace(UCH(ch
)))
179 UNLESS(!isdigit(UCH(ch
)));
184 if (isdigit(UCH(ch
)))
189 UNLESS(!isspace(UCH(ch
)));
193 if (isspace(UCH(ch
)))
199 UNLESS(line
[n
+ 1] == '"');
219 size_t need
= (size_t) (name_end
- name_1st
);
220 if ((long)need
> (long)input_file_name_len
)
222 input_file_name_len
= ((need
+ 1) * 3) / 2;
223 input_file_name
= TREALLOC(char, input_file_name
, input_file_name_len
);
224 NO_SPACE(input_file_name
);
228 memcpy(input_file_name
, line
+ name_1st
+ 1, need
- 1);
229 input_file_name
[need
- 1] = '\0';
233 input_file_name
[0] = '\0';
237 if (ld
>= ldNUM
&& ld
< ldERR
)
241 lineno
= (int)strtol(line
+ line_1st
, NULL
, 10) - 1;
256 FILE *f
= input_file
;
262 if (saw_eof
|| (c
= getc(f
)) == EOF
)
274 if (line
== NULL
|| linesize
!= (LINESIZE
+ 1))
278 linesize
= LINESIZE
+ 1;
279 line
= TMALLOC(char, linesize
);
290 if ((i
+ 3) >= linesize
)
292 linesize
+= LINESIZE
;
293 line
= TREALLOC(char, line
, linesize
);
306 while (line_directive());
321 p
= TMALLOC(char, s
- line
+ 1);
326 while ((*t
++ = *s
++) != '\n')
337 a
.a_line
= dup_line();
338 a
.a_cptr
= a
.a_line
+ (cptr
- line
);
343 if (*s
== '*' && s
[1] == '/')
353 unterminated_comment(&a
);
386 else if (s
[1] == '/')
411 switch (ch
= next_inline())
438 static struct keyword
444 { "binary", NONASSOC
},
445 { "debug", XXXDEBUG
},
446 #if defined(YYBTYACC)
447 { "destructor", DESTRUCTOR
},
449 { "error-verbose",ERROR_VERBOSE
},
450 { "expect", EXPECT
},
451 { "expect-rr", EXPECT_RR
},
453 #if defined(YYBTYACC)
454 { "initial-action", INITIAL_ACTION
},
457 { "lex-param", LEX_PARAM
},
458 #if defined(YYBTYACC)
459 { "locations", LOCATIONS
},
461 { "nonassoc", NONASSOC
},
462 { "parse-param", PARSE_PARAM
},
463 { "pure-parser", PURE_PARSER
},
468 { "token-table", TOKEN_TABLE
},
471 { "yacc", POSIX_YACC
},
476 compare_keys(const void *a
, const void *b
)
478 const struct keyword
*p
= (const struct keyword
*)a
;
479 const struct keyword
*q
= (const struct keyword
*)b
;
480 return strcmp(p
->name
, q
->name
);
502 else if (isdigit(UCH(c
))
511 /* treat keywords spelled with '_' as if it were '-' */
522 if ((key
= bsearch(cache
, keywords
,
523 sizeof(keywords
) / sizeof(*key
),
524 sizeof(*key
), compare_keys
)))
532 if (c
== '%' || c
== '\\')
543 syntax_error(lineno
, line
, t_cptr
);
551 FILE *f
= output_file
;
557 syntax_error(lineno
, line
, cptr
);
559 fprintf(f
, "#ident \"");
579 copy_string(int quote
)
581 struct mstring
*temp
= msnew();
585 a
.a_line
= dup_line();
586 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 1);
598 unterminated_string(&a
);
607 unterminated_string(&a
);
616 struct mstring
*temp
= msnew();
623 while ((c
= *++cptr
) != '\n')
626 if (c
== '*' && cptr
[1] == '/')
636 a
.a_line
= dup_line();
637 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 1);
645 if (c
== '*' && *cptr
== '/')
656 unterminated_comment(&a
);
668 int need_newline
= 0;
671 a
.a_line
= dup_line();
672 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 2);
678 unterminated_text(&a
);
681 fprintf(f
, line_format
, lineno
, input_file_name
);
693 unterminated_text(&a
);
699 char *s
= copy_string(c
);
709 char *s
= copy_comment();
736 puts_both(const char *s
)
740 fputs(s
, union_file
);
758 a
.a_line
= dup_line();
759 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 6);
762 over_unionized(cptr
- 6);
765 puts_both("#ifdef YYSTYPE\n");
766 puts_both("#undef YYSTYPE_IS_DECLARED\n");
767 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
768 puts_both("#endif\n");
769 puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
770 puts_both("#define YYSTYPE_IS_DECLARED 1\n");
773 fprintf(text_file
, line_format
, lineno
, input_file_name
);
774 puts_both("typedef union");
785 unterminated_union(&a
);
795 puts_both(" YYSTYPE;\n");
796 puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
805 char *s
= copy_string(c
);
813 char *s
= copy_comment();
825 after_blanks(char *s
)
827 while (*s
!= '\0' && isspace(UCH(*s
)))
833 * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
834 * single space. Return index to last character in the buffer.
837 trim_blanks(char *buffer
)
842 char *s
= after_blanks(d
);
844 while ((*d
++ = *s
++) != '\0')
850 while ((--d
!= buffer
) && isspace(UCH(*d
)))
853 for (s
= d
= buffer
; (*d
++ = *s
++) != '\0';)
855 if (isspace(UCH(*s
)))
858 while (isspace(UCH(*s
)))
867 return (int)strlen(buffer
) - 1;
871 * Scan forward in the current line-buffer looking for a right-curly bracket.
873 * Parameters begin with a left-curly bracket, and continue until there are no
874 * more interesting characters after the last right-curly bracket on the
875 * current line. Bison documents parameters as separated like this:
876 * {type param1} {type2 param2}
877 * but also accepts commas (although some versions of bison mishandle this)
878 * {type param1, type2 param2}
888 switch (next_inline())
907 save_param(int k
, char *buffer
, int name
, int type2
)
911 p
= TMALLOC(param
, 1);
914 p
->type2
= strdup(buffer
+ type2
);
916 buffer
[type2
] = '\0';
917 (void)trim_blanks(p
->type2
);
919 p
->name
= strdup(buffer
+ name
);
922 (void)trim_blanks(p
->name
);
924 p
->type
= strdup(buffer
);
926 (void)trim_blanks(p
->type
);
950 * Keep a linked list of parameters. This may be multi-line, if the trailing
951 * right-curly bracket is absent.
962 int st_lineno
= lineno
;
996 if ((curly
== 1) && (cptr
== line
))
1006 if (curly
== 0 && !isspace(UCH(c
)))
1014 buf_size
= (size_t) linesize
;
1015 buf
= TMALLOC(char, buf_size
);
1023 buf_size
+= (size_t) linesize
;
1024 buf
= TREALLOC(char, buf
, buf_size
);
1029 if ((state
== 2) && (c
== L_CURL
))
1033 else if ((state
== 2) && isspace(UCH(c
)))
1037 else if ((c
!= L_CURL
) && (c
!= R_CURL
))
1044 while (curly
< 2 || more_curly());
1057 (void)trim_blanks(buf
);
1062 char *parms
= (comma
+ 1);
1063 comma
= strchr(parms
, ',');
1067 (void)trim_blanks(parms
);
1068 i
= (int)strlen(parms
) - 1;
1074 if (parms
[i
] == ']')
1077 while (i
>= 0 && level
> 0 && parms
[i
] != '[')
1079 if (parms
[i
] == ']')
1081 else if (parms
[i
] == '[')
1094 while (i
> 0 && (isalnum(UCH(parms
[i
])) || UCH(parms
[i
]) == '_'))
1097 if (!isspace(UCH(parms
[i
])) && parms
[i
] != '*')
1102 save_param(k
, parms
, name
, type2
);
1110 syntax_error(lineno
, line
, cptr
);
1116 if (c
>= '0' && c
<= '9')
1118 if (c
>= 'A' && c
<= 'F')
1119 return (c
- 'A' + 10);
1120 if (c
>= 'a' && c
<= 'f')
1121 return (c
- 'a' + 10);
1134 a
.a_lineno
= lineno
;
1135 a
.a_line
= dup_line();
1136 a
.a_cptr
= a
.a_line
+ (cptr
- line
);
1146 unterminated_string(&a
);
1149 char *c_cptr
= cptr
- 1;
1157 unterminated_string(&a
);
1172 n
= (n
<< 3) + (c
- '0');
1176 n
= (n
<< 3) + (c
- '0');
1181 illegal_character(c_cptr
);
1188 if (n
< 0 || n
>= 16)
1189 illegal_character(c_cptr
);
1194 if (i
< 0 || i
>= 16)
1199 illegal_character(c_cptr
);
1232 s
= TMALLOC(char, n
);
1235 for (i
= 0; i
< n
; ++i
)
1244 for (i
= 0; i
< n
; ++i
)
1247 if (c
== '\\' || c
== cache
[0])
1252 else if (isprint(UCH(c
)))
1281 cachec(((c
>> 6) & 7) + '0');
1282 cachec(((c
>> 3) & 7) + '0');
1283 cachec((c
& 7) + '0');
1297 if (n
== 1 && bp
->value
== UNDEFINED
)
1298 bp
->value
= UCH(*s
);
1305 is_reserved(char *name
)
1309 if (strcmp(name
, ".") == 0 ||
1310 strcmp(name
, "$accept") == 0 ||
1311 strcmp(name
, "$end") == 0)
1314 if (name
[0] == '$' && name
[1] == '$' && isdigit(UCH(name
[2])))
1317 while (isdigit(UCH(*s
)))
1332 for (c
= *cptr
; IS_IDENT(c
); c
= *++cptr
)
1336 if (is_reserved(cache
))
1337 used_reserved(cache
);
1339 return (lookup(cache
));
1350 for (c
= *cptr
; isdigit(UCH(c
)); c
= *++cptr
)
1352 n
= (10 * n
+ (c
- '0'));
1355 syntax_error(lineno
, line
, base
);
1361 return (Value_t
)(n
);
1365 cache_tag(char *tag
, size_t len
)
1370 for (i
= 0; i
< ntags
; ++i
)
1372 if (strncmp(tag
, tag_table
[i
], len
) == 0 &&
1373 tag_table
[i
][len
] == NUL
)
1374 return (tag_table
[i
]);
1377 if (ntags
>= tagmax
)
1382 ? TREALLOC(char *, tag_table
, tagmax
)
1383 : TMALLOC(char *, tagmax
));
1384 NO_SPACE(tag_table
);
1387 s
= TMALLOC(char, len
+ 1);
1390 strncpy(s
, tag
, len
);
1392 tag_table
[ntags
++] = s
;
1400 int t_lineno
= lineno
;
1401 char *t_line
= dup_line();
1402 char *t_cptr
= t_line
+ (cptr
- line
);
1409 illegal_tag(t_lineno
, t_line
, t_cptr
);
1417 while (IS_IDENT(c
));
1424 illegal_tag(t_lineno
, t_line
, t_cptr
);
1429 return cache_tag(cache
, (size_t) cinc
);
1432 #if defined(YYBTYACC)
1438 while (IS_NAME2(UCH(*cptr
)))
1440 return cache_tag(b
, (size_t) (cptr
- b
));
1445 declare_tokens(int assoc
)
1468 if (isalpha(UCH(c
)) || c
== '_' || c
== '.' || c
== '$')
1470 else if (c
== '\'' || c
== '"')
1476 tokenized_start(bp
->name
);
1481 if (bp
->tag
&& tag
!= bp
->tag
)
1482 retyped_warning(bp
->name
);
1488 if (bp
->prec
&& prec
!= bp
->prec
)
1489 reprec_warning(bp
->name
);
1490 bp
->assoc
= (Assoc_t
)assoc
;
1498 if (isdigit(UCH(c
)))
1500 value
= get_number();
1501 if (bp
->value
!= UNDEFINED
&& value
!= bp
->value
)
1502 revalued_warning(bp
->name
);
1512 * %expect requires special handling
1513 * as it really isn't part of the yacc
1514 * grammar only a flag for yacc proper.
1517 declare_expect(int assoc
)
1521 if (assoc
!= EXPECT
&& assoc
!= EXPECT_RR
)
1525 * Stay away from nextc - doesn't
1526 * detect EOL and will read to EOF.
1534 if (isdigit(UCH(c
)))
1536 if (assoc
== EXPECT
)
1537 SRexpect
= get_number();
1539 RRexpect
= get_number();
1543 * Looking for number before EOL.
1544 * Spaces, tabs, and numbers are ok,
1545 * words, punc., etc. are syntax errors.
1547 else if (c
== '\n' || isalpha(UCH(c
)) || !isspace(UCH(c
)))
1549 syntax_error(lineno
, line
, cptr
);
1560 #if defined(YYBTYACC)
1562 declare_argtypes(bucket
*bp
)
1564 char *tags
[MAXARGS
];
1568 retyped_warning(bp
->name
);
1569 cptr
++; /* skip open paren */
1576 syntax_error(lineno
, line
, cptr
);
1577 tags
[args
++] = get_tag();
1584 cptr
++; /* skip close paren */
1586 bp
->argnames
= TMALLOC(char *, args
);
1587 NO_SPACE(bp
->argnames
);
1588 bp
->argtags
= CALLOC(sizeof(char *), args
+ 1);
1589 NO_SPACE(bp
->argtags
);
1592 bp
->argtags
[args
] = tags
[args
];
1593 bp
->argnames
[args
] = NULL
;
1616 if (isalpha(UCH(c
)) || c
== '_' || c
== '.' || c
== '$')
1619 #if defined(YYBTYACC)
1620 if (nextc() == L_PAREN
)
1621 declare_argtypes(bp
);
1626 else if (c
== '\'' || c
== '"')
1629 #if defined(YYBTYACC)
1638 if (bp
->tag
&& tag
!= bp
->tag
)
1639 retyped_warning(bp
->name
);
1654 if (!isalpha(UCH(c
)) && c
!= '_' && c
!= '.' && c
!= '$')
1655 syntax_error(lineno
, line
, cptr
);
1657 if (bp
->class == TERM
)
1658 terminal_start(bp
->name
);
1659 if (goal
&& goal
!= bp
)
1660 restarted_warning();
1665 read_declarations(void)
1669 cache_size
= CACHE_SIZE
;
1670 cache
= TMALLOC(char, cache_size
);
1679 syntax_error(lineno
, line
, cptr
);
1680 switch (k
= keyword())
1734 #if defined(YYBTYACC)
1743 case INITIAL_ACTION
:
1744 copy_initial_action();
1753 /* noop for bison compatibility. byacc is already designed to be posix
1754 * yacc compatible. */
1761 initialize_grammar(void)
1766 pitem
= TMALLOC(bucket
*, maxitems
);
1777 plhs
= TMALLOC(bucket
*, maxrules
);
1784 rprec
= TMALLOC(Value_t
, maxrules
);
1791 rassoc
= TMALLOC(Assoc_t
, maxrules
);
1803 pitem
= TREALLOC(bucket
*, pitem
, maxitems
);
1812 plhs
= TREALLOC(bucket
*, plhs
, maxrules
);
1815 rprec
= TREALLOC(Value_t
, rprec
, maxrules
);
1818 rassoc
= TREALLOC(Assoc_t
, rassoc
, maxrules
);
1822 /* set immediately prior to where copy_args() could be called, and incremented by
1823 the various routines that will rescan the argument list as appropriate */
1824 static int rescan_lineno
;
1825 #if defined(YYBTYACC)
1828 copy_args(int *alen
)
1830 struct mstring
*s
= msnew();
1831 int depth
= 0, len
= 1;
1835 a
.a_lineno
= lineno
;
1836 a
.a_line
= dup_line();
1837 a
.a_cptr
= a
.a_line
+ (cptr
- line
- 1);
1839 while ((c
= *cptr
++) != R_PAREN
|| depth
|| quote
)
1841 if (c
== ',' && !quote
&& !depth
)
1854 unterminated_string(&a
);
1856 unterminated_arglist(&a
);
1873 else if (c
== R_PAREN
)
1875 else if (c
== '\"' || c
== '\'')
1886 parse_id(char *p
, char **save
)
1890 while (isspace(UCH(*p
)))
1893 if (!isalpha(UCH(*p
)) && *p
!= '_')
1896 while (IS_NAME2(UCH(*p
)))
1900 *save
= cache_tag(b
, (size_t) (p
- b
));
1906 parse_int(char *p
, int *save
)
1908 int neg
= 0, val
= 0;
1910 while (isspace(UCH(*p
)))
1918 if (!isdigit(UCH(*p
)))
1920 while (isdigit(UCH(*p
)))
1921 val
= val
* 10 + *p
++ - '0';
1930 parse_arginfo(bucket
*a
, char *args
, int argslen
)
1932 char *p
= args
, *tmp
;
1937 if (a
->args
!= argslen
)
1938 arg_number_disagree_warning(rescan_lineno
, a
->name
);
1943 if ((a
->args
= argslen
) == 0)
1945 a
->argnames
= TMALLOC(char *, argslen
);
1946 NO_SPACE(a
->argnames
);
1947 a
->argtags
= TMALLOC(char *, argslen
);
1948 NO_SPACE(a
->argtags
);
1952 for (i
= 0; i
< argslen
; i
++)
1954 while (isspace(UCH(*p
)))
1959 while (isspace(UCH(*p
)))
1965 if (!(p
= parse_id(p
+ 1, &tmp
)))
1967 while (isspace(UCH(*p
)))
1974 if (a
->argtags
[i
] != tmp
)
1975 arg_type_disagree_warning(rescan_lineno
, i
+ 1, a
->name
);
1978 a
->argtags
[i
] = tmp
;
1981 a
->argtags
[i
] = NULL
;
1982 if (!(p
= parse_id(p
, &a
->argnames
[i
])))
1984 while (isspace(UCH(*p
)))
1994 compile_arg(char **theptr
, char *yyvaltag
)
1997 struct mstring
*c
= msnew();
1999 Value_t
*offsets
= NULL
, maxoffset
;
2004 for (i
= nitems
- 1; pitem
[i
]; --i
)
2007 if (pitem
[i
]->class != ARGUMENT
)
2012 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
2015 for (j
= 0, i
++; i
< nitems
; i
++)
2016 if (pitem
[i
]->class != ARGUMENT
)
2017 offsets
[++j
] = (Value_t
)(i
- nitems
+ 1);
2019 rhs
= pitem
+ nitems
- 1;
2022 msprintf(c
, "yyval.%s = ", yyvaltag
);
2024 msprintf(c
, "yyval = ");
2031 if (!(p
= parse_id(++p
, &tag
)) || *p
++ != '>')
2032 illegal_tag(rescan_lineno
, NULL
, NULL
);
2033 if (isdigit(UCH(*p
)) || *p
== '-')
2036 if (!(p
= parse_int(p
, &val
)))
2037 dollar_error(rescan_lineno
, NULL
, NULL
);
2040 else if (val
> maxoffset
)
2042 dollar_warning(rescan_lineno
, val
);
2043 i
= val
- maxoffset
;
2045 else if (maxoffset
> 0)
2048 if (!tag
&& !(tag
= rhs
[i
]->tag
) && havetags
)
2049 untyped_rhs(val
, rhs
[i
]->name
);
2051 msprintf(c
, "yystack.l_mark[%d]", i
);
2053 msprintf(c
, ".%s", tag
);
2057 else if (isalpha(UCH(*p
)) || *p
== '_')
2060 if (!(p
= parse_id(p
, &arg
)))
2061 dollar_error(rescan_lineno
, NULL
, NULL
);
2062 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2063 if (arg
== plhs
[nrules
]->argnames
[i
])
2066 unknown_arg_warning(rescan_lineno
, "$", arg
, NULL
, NULL
);
2068 tag
= plhs
[nrules
]->argtags
[i
];
2069 msprintf(c
, "yystack.l_mark[%d]",
2070 i
- plhs
[nrules
]->args
+ 1 - n
);
2072 msprintf(c
, ".%s", tag
);
2074 untyped_arg_warning(rescan_lineno
, "$", arg
);
2077 dollar_error(rescan_lineno
, NULL
, NULL
);
2081 at_error(rescan_lineno
, NULL
, NULL
);
2097 can_elide_arg(char **theptr
, char *yyvaltag
)
2102 Value_t
*offsets
= NULL
, maxoffset
= 0;
2110 if (!(p
= parse_id(++p
, &tag
)) || *p
++ != '>')
2113 for (i
= nitems
- 1; pitem
[i
]; --i
)
2116 if (pitem
[i
]->class != ARGUMENT
)
2121 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
2124 for (j
= 0, i
++; i
< nitems
; i
++)
2125 if (pitem
[i
]->class != ARGUMENT
)
2126 offsets
[++j
] = (Value_t
)(i
- nitems
+ 1);
2128 rhs
= pitem
+ nitems
- 1;
2130 if (isdigit(UCH(*p
)) || *p
== '-')
2133 if (!(p
= parse_int(p
, &val
)))
2139 else if (val
> maxoffset
)
2150 else if (isalpha(UCH(*p
)) || *p
== '_')
2153 if (!(p
= parse_id(p
, &arg
)))
2155 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2156 if (arg
== plhs
[nrules
]->argnames
[i
])
2161 tag
= plhs
[nrules
]->argtags
[i
];
2162 rv
= plhs
[nrules
]->args
+ n
- i
;
2165 if (tag
&& yyvaltag
)
2167 if (strcmp(tag
, yyvaltag
))
2170 else if (tag
|| yyvaltag
)
2180 #define ARG_CACHE_SIZE 1024
2181 static struct arg_cache
2183 struct arg_cache
*next
;
2187 *arg_cache
[ARG_CACHE_SIZE
];
2190 lookup_arg_cache(char *code
)
2192 struct arg_cache
*entry
;
2194 entry
= arg_cache
[strnshash(code
) % ARG_CACHE_SIZE
];
2197 if (!strnscmp(entry
->code
, code
))
2199 entry
= entry
->next
;
2205 insert_arg_cache(char *code
, int rule
)
2207 struct arg_cache
*entry
= NEW(struct arg_cache
);
2211 i
= strnshash(code
) % ARG_CACHE_SIZE
;
2214 entry
->next
= arg_cache
[i
];
2215 arg_cache
[i
] = entry
;
2219 clean_arg_cache(void)
2221 struct arg_cache
*e
, *t
;
2224 for (i
= 0; i
< ARG_CACHE_SIZE
; i
++)
2226 for (e
= arg_cache
[i
]; (t
= e
); e
= e
->next
, FREE(t
))
2228 arg_cache
[i
] = NULL
;
2231 #endif /* defined(YYBTYACC) */
2234 advance_to_start(void)
2240 #if defined(YYBTYACC)
2265 syntax_error(lineno
, line
, s_cptr
);
2270 if (!isalpha(UCH(c
)) && c
!= '_' && c
!= '.' && c
!= '_')
2271 syntax_error(lineno
, line
, cptr
);
2275 if (bp
->class == TERM
)
2276 terminal_start(bp
->name
);
2284 rescan_lineno
= lineno
; /* line# for possible inherited args rescan */
2285 #if defined(YYBTYACC)
2289 args
= copy_args(&argslen
);
2295 syntax_error(lineno
, line
, cptr
);
2296 start_rule(bp
, s_lineno
);
2297 #if defined(YYBTYACC)
2298 parse_arginfo(bp
, args
, argslen
);
2304 start_rule(bucket
*bp
, int s_lineno
)
2306 if (bp
->class == TERM
)
2307 terminal_lhs(s_lineno
);
2308 bp
->class = NONTERM
;
2311 if (nrules
>= maxrules
)
2314 rprec
[nrules
] = UNDEFINED
;
2315 rassoc
[nrules
] = TOKEN
;
2323 if (!last_was_action
&& plhs
[nrules
]->tag
)
2325 if (pitem
[nitems
- 1])
2327 for (i
= nitems
- 1; (i
> 0) && pitem
[i
]; --i
)
2329 if (pitem
[i
+ 1] == 0 || pitem
[i
+ 1]->tag
!= plhs
[nrules
]->tag
)
2330 default_action_warning(plhs
[nrules
]->name
);
2333 default_action_warning(plhs
[nrules
]->name
);
2336 last_was_action
= 0;
2337 if (nitems
>= maxitems
)
2345 insert_empty_rule(void)
2350 assert(cache_size
>= CACHE_SIZE
);
2351 sprintf(cache
, "$$%d", ++gensym
);
2352 bp
= make_bucket(cache
);
2353 last_symbol
->next
= bp
;
2355 bp
->tag
= plhs
[nrules
]->tag
;
2357 #if defined(YYBTYACC)
2361 nitems
= (Value_t
)(nitems
+ 2);
2362 if (nitems
> maxitems
)
2364 bpp
= pitem
+ nitems
- 1;
2366 while ((bpp
[0] = bpp
[-1]) != 0)
2369 if (++nrules
>= maxrules
)
2371 plhs
[nrules
] = plhs
[nrules
- 1];
2372 plhs
[nrules
- 1] = bp
;
2373 rprec
[nrules
] = rprec
[nrules
- 1];
2374 rprec
[nrules
- 1] = 0;
2375 rassoc
[nrules
] = rassoc
[nrules
- 1];
2376 rassoc
[nrules
- 1] = TOKEN
;
2379 #if defined(YYBTYACC)
2381 insert_arg_rule(char *arg
, char *tag
)
2383 int line_number
= rescan_lineno
;
2384 char *code
= compile_arg(&arg
, tag
);
2385 int rule
= lookup_arg_cache(code
);
2386 FILE *f
= action_file
;
2391 insert_arg_cache(code
, rule
);
2392 trialaction
= 1; /* arg rules always run in trial mode */
2393 fprintf(f
, "case %d:\n", rule
- 2);
2395 fprintf(f
, line_format
, line_number
, input_file_name
);
2396 fprintf(f
, "%s;\n", code
);
2397 fprintf(f
, "break;\n");
2398 insert_empty_rule();
2399 plhs
[rule
]->tag
= cache_tag(tag
, strlen(tag
));
2400 plhs
[rule
]->class = ARGUMENT
;
2404 if (++nitems
> maxitems
)
2406 pitem
[nitems
- 1] = plhs
[rule
];
2418 int s_lineno
= lineno
;
2419 #if defined(YYBTYACC)
2425 if (c
== '\'' || c
== '"')
2431 rescan_lineno
= lineno
; /* line# for possible inherited args rescan */
2432 #if defined(YYBTYACC)
2436 args
= copy_args(&argslen
);
2444 start_rule(bp
, s_lineno
);
2445 #if defined(YYBTYACC)
2446 parse_arginfo(bp
, args
, argslen
);
2452 if (last_was_action
)
2453 insert_empty_rule();
2454 last_was_action
= 0;
2456 #if defined(YYBTYACC)
2459 if (argslen
== 0 && bp
->args
> 0 && pitem
[nitems
- 1] == NULL
)
2462 if (plhs
[nrules
]->args
!= bp
->args
)
2463 wrong_number_args_warning("default ", bp
->name
);
2464 for (i
= bp
->args
- 1; i
>= 0; i
--)
2465 if (plhs
[nrules
]->argtags
[i
] != bp
->argtags
[i
])
2466 wrong_type_for_arg_warning(i
+ 1, bp
->name
);
2468 else if (bp
->args
!= argslen
)
2469 wrong_number_args_warning("", bp
->name
);
2474 int elide_cnt
= can_elide_arg(&ap
, bp
->argtags
[0]);
2476 if (elide_cnt
> argslen
)
2480 for (i
= 1; i
< elide_cnt
; i
++)
2481 if (can_elide_arg(&ap
, bp
->argtags
[i
]) != elide_cnt
- i
)
2489 assert(i
== elide_cnt
);
2496 for (; i
< argslen
; i
++)
2497 ap
= insert_arg_rule(ap
, bp
->argtags
[i
]);
2500 #endif /* defined(YYBTYACC) */
2502 if (++nitems
> maxitems
)
2504 pitem
[nitems
- 1] = bp
;
2513 #if defined(YYBTYACC)
2517 FILE *f
= action_file
;
2519 Value_t
*offsets
= NULL
, maxoffset
;
2522 a
.a_lineno
= lineno
;
2523 a
.a_line
= dup_line();
2524 a
.a_cptr
= a
.a_line
+ (cptr
- line
);
2526 if (last_was_action
)
2527 insert_empty_rule();
2528 last_was_action
= 1;
2529 #if defined(YYBTYACC)
2530 trialaction
= (*cptr
== L_BRAC
);
2533 fprintf(f
, "case %d:\n", nrules
- 2);
2534 #if defined(YYBTYACC)
2538 fprintf(f
, " if (!yytrial)\n");
2542 fprintf(f
, line_format
, lineno
, input_file_name
);
2546 /* avoid putting curly-braces in first column, to ease editing */
2547 if (*after_blanks(cptr
) == L_CURL
)
2550 cptr
= after_blanks(cptr
);
2555 for (i
= nitems
- 1; pitem
[i
]; --i
)
2558 if (pitem
[i
]->class != ARGUMENT
)
2563 offsets
= TMALLOC(Value_t
, maxoffset
+ 1);
2566 for (j
= 0, i
++; i
< nitems
; i
++)
2568 if (pitem
[i
]->class != ARGUMENT
)
2570 offsets
[++j
] = (Value_t
)(i
- nitems
+ 1);
2574 rhs
= pitem
+ nitems
- 1;
2583 int d_lineno
= lineno
;
2584 char *d_line
= dup_line();
2585 char *d_cptr
= d_line
+ (cptr
- line
);
2592 fprintf(f
, "yyval.%s", tag
);
2597 else if (isdigit(UCH(c
)))
2601 fprintf(f
, "yystack.l_mark[%d].%s", -n
, tag
);
2602 else if (i
> maxoffset
)
2604 dollar_warning(d_lineno
, i
);
2605 fprintf(f
, "yystack.l_mark[%d].%s", i
- maxoffset
, tag
);
2608 fprintf(f
, "yystack.l_mark[%d].%s", offsets
[i
], tag
);
2612 else if (c
== '-' && isdigit(UCH(cptr
[1])))
2615 i
= -get_number() - n
;
2616 fprintf(f
, "yystack.l_mark[%d].%s", i
, tag
);
2620 #if defined(YYBTYACC)
2621 else if (isalpha(UCH(c
)) || c
== '_')
2623 char *arg
= scan_id();
2624 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2625 if (arg
== plhs
[nrules
]->argnames
[i
])
2628 unknown_arg_warning(d_lineno
, "$", arg
, d_line
, d_cptr
);
2629 fprintf(f
, "yystack.l_mark[%d].%s",
2630 i
- plhs
[nrules
]->args
+ 1 - n
, tag
);
2636 dollar_error(d_lineno
, d_line
, d_cptr
);
2638 else if (cptr
[1] == '$')
2642 tag
= plhs
[nrules
]->tag
;
2645 fprintf(f
, "yyval.%s", tag
);
2648 fprintf(f
, "yyval");
2650 #if defined(YYBTYACC)
2655 else if (isdigit(UCH(cptr
[1])))
2659 if (havetags
&& offsets
)
2661 if (i
<= 0 || i
> maxoffset
)
2663 tag
= rhs
[offsets
[i
]]->tag
;
2665 untyped_rhs(i
, rhs
[offsets
[i
]]->name
);
2666 fprintf(f
, "yystack.l_mark[%d].%s", offsets
[i
], tag
);
2671 fprintf(f
, "yystack.l_mark[%d]", -n
);
2672 else if (i
> maxoffset
)
2674 dollar_warning(lineno
, i
);
2675 fprintf(f
, "yystack.l_mark[%d]", i
- maxoffset
);
2678 fprintf(f
, "yystack.l_mark[%d]", offsets
[i
]);
2682 else if (cptr
[1] == '-')
2688 fprintf(f
, "yystack.l_mark[%d]", -i
- n
);
2691 #if defined(YYBTYACC)
2692 else if (isalpha(UCH(cptr
[1])) || cptr
[1] == '_')
2697 for (i
= plhs
[nrules
]->args
- 1; i
>= 0; i
--)
2698 if (arg
== plhs
[nrules
]->argnames
[i
])
2701 unknown_arg_warning(lineno
, "$", arg
, line
, cptr
);
2702 tag
= (i
< 0 ? NULL
: plhs
[nrules
]->argtags
[i
]);
2703 fprintf(f
, "yystack.l_mark[%d]", i
- plhs
[nrules
]->args
+ 1 - n
);
2705 fprintf(f
, ".%s", tag
);
2707 untyped_arg_warning(lineno
, "$", arg
);
2712 #if defined(YYBTYACC)
2717 int l_lineno
= lineno
;
2718 char *l_line
= dup_line();
2719 char *l_cptr
= l_line
+ (cptr
- line
);
2720 syntax_error(l_lineno
, l_line
, l_cptr
);
2724 fprintf(f
, "yyloc");
2728 else if (isdigit(UCH(cptr
[1])))
2733 fprintf(f
, "yystack.p_mark[%d]", -n
);
2734 else if (i
> maxoffset
)
2736 at_warning(lineno
, i
);
2737 fprintf(f
, "yystack.p_mark[%d]", i
- maxoffset
);
2740 fprintf(f
, "yystack.p_mark[%d]", offsets
[i
]);
2743 else if (cptr
[1] == '-')
2747 fprintf(f
, "yystack.p_mark[%d]", -i
- n
);
2759 while (IS_NAME2(c
));
2763 #if defined(YYBTYACC)
2766 if (trialaction
&& c
== L_BRAC
&& depth
== 0)
2772 if (trialaction
&& c
== R_BRAC
&& depth
== 1)
2777 if (c
== L_BRAC
&& !haveyyval
)
2781 if (c
== L_CURL
&& !haveyyval
)
2783 fprintf(f
, " if (!yytrial)\n");
2785 fprintf(f
, line_format
, lineno
, input_file_name
);
2789 fprintf(f
, "\nbreak;\n");
2804 unterminated_action(&a
);
2809 fprintf(f
, "\nbreak;\n");
2815 #if defined(YYBTYACC)
2834 #if defined(YYBTYACC)
2838 if (c
== L_BRAC
&& !haveyyval
)
2843 if (c
== L_CURL
&& !haveyyval
)
2845 fprintf(f
, " if (!yytrial)\n");
2847 fprintf(f
, line_format
, lineno
, input_file_name
);
2852 fprintf(f
, "\nbreak;\n");
2861 char *s
= copy_string(c
);
2869 char *s
= copy_comment();
2880 #if defined(YYBTYACC)
2882 get_code(struct ainfo
*a
, const char *loc
)
2887 struct mstring
*code_mstr
= msnew();
2890 msprintf(code_mstr
, line_format
, lineno
, input_file_name
);
2892 cptr
= after_blanks(cptr
);
2893 if (*cptr
== L_CURL
)
2894 /* avoid putting curly-braces in first column, to ease editing */
2895 mputc(code_mstr
, '\t');
2897 syntax_error(lineno
, line
, cptr
);
2899 a
->a_lineno
= lineno
;
2900 a
->a_line
= dup_line();
2901 a
->a_cptr
= a
->a_line
+ (cptr
- line
);
2910 int d_lineno
= lineno
;
2911 char *d_line
= dup_line();
2912 char *d_cptr
= d_line
+ (cptr
- line
);
2919 msprintf(code_mstr
, "(*val).%s", tag
);
2925 dollar_error(d_lineno
, d_line
, d_cptr
);
2927 else if (cptr
[1] == '$')
2929 /* process '$$' later; replacement is context dependent */
2930 msprintf(code_mstr
, "$$");
2935 if (c
== '@' && cptr
[1] == '$')
2939 int l_lineno
= lineno
;
2940 char *l_line
= dup_line();
2941 char *l_cptr
= l_line
+ (cptr
- line
);
2942 syntax_error(l_lineno
, l_line
, l_cptr
);
2944 msprintf(code_mstr
, "%s", loc
);
2952 mputc(code_mstr
, c
);
2955 while (IS_NAME2(c
));
2959 mputc(code_mstr
, c
);
2966 unterminated_action(a
);
2980 char *s
= copy_string(c
);
2981 msprintf(code_mstr
, "%s", s
);
2988 char *s
= copy_comment();
2989 msprintf(code_mstr
, "%s", s
);
2998 return msdone(code_mstr
);
3002 copy_initial_action(void)
3006 initial_action
= get_code(&a
, "yyloc");
3011 copy_destructor(void)
3018 code_text
= get_code(&a
, "(*loc)");
3028 { /* "no semantic type" default destructor */
3030 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) == NULL
)
3032 static char untyped_default
[] = "<>";
3033 bp
= make_bucket("untyped default");
3034 bp
->tag
= untyped_default
;
3035 default_destructor
[UNTYPED_DEFAULT
] = bp
;
3037 if (bp
->destructor
!= NULL
)
3038 destructor_redeclared_warning(&a
);
3040 /* replace "$$" with "(*val)" in destructor code */
3041 bp
->destructor
= process_destructor_XX(code_text
, NULL
);
3043 else if (cptr
[1] == '*' && cptr
[2] == '>')
3044 { /* "no per-symbol or per-type" default destructor */
3046 if ((bp
= default_destructor
[TYPED_DEFAULT
]) == NULL
)
3048 static char typed_default
[] = "<*>";
3049 bp
= make_bucket("typed default");
3050 bp
->tag
= typed_default
;
3051 default_destructor
[TYPED_DEFAULT
] = bp
;
3053 if (bp
->destructor
!= NULL
)
3054 destructor_redeclared_warning(&a
);
3057 /* postpone re-processing destructor $$s until end of grammar spec */
3058 bp
->destructor
= TMALLOC(char, strlen(code_text
) + 1);
3059 NO_SPACE(bp
->destructor
);
3060 strcpy(bp
->destructor
, code_text
);
3064 { /* "semantic type" default destructor */
3065 char *tag
= get_tag();
3066 bp
= lookup_type_destructor(tag
);
3067 if (bp
->destructor
!= NULL
)
3068 destructor_redeclared_warning(&a
);
3070 /* replace "$$" with "(*val).tag" in destructor code */
3071 bp
->destructor
= process_destructor_XX(code_text
, tag
);
3074 else if (isalpha(UCH(c
)) || c
== '_' || c
== '.' || c
== '$')
3075 { /* "symbol" destructor */
3077 if (bp
->destructor
!= NULL
)
3078 destructor_redeclared_warning(&a
);
3081 /* postpone re-processing destructor $$s until end of grammar spec */
3082 bp
->destructor
= TMALLOC(char, strlen(code_text
) + 1);
3083 NO_SPACE(bp
->destructor
);
3084 strcpy(bp
->destructor
, code_text
);
3095 process_destructor_XX(char *code
, char *tag
)
3100 struct mstring
*new_code
= msnew();
3101 char *codeptr
= code
;
3104 loop
: /* step thru code */
3106 if (c
== '$' && codeptr
[1] == '$')
3110 msprintf(new_code
, "(*val)");
3112 msprintf(new_code
, "(*val).%s", tag
);
3122 while (IS_NAME2(c
));
3136 return msdone(new_code
);
3164 if (c
== '*' && *codeptr
== '/')
3166 mputc(new_code
, '/');
3178 #endif /* defined(YYBTYACC) */
3187 if (c
== '%' || c
== '\\')
3195 else if ((c
== 'p' || c
== 'P') &&
3196 ((c
= cptr
[2]) == 'r' || c
== 'R') &&
3197 ((c
= cptr
[3]) == 'e' || c
== 'E') &&
3198 ((c
= cptr
[4]) == 'c' || c
== 'C') &&
3199 ((c
= cptr
[5], !IS_IDENT(c
))))
3202 syntax_error(lineno
, line
, cptr
);
3205 if (isalpha(UCH(c
)) || c
== '_' || c
== '.' || c
== '$')
3207 else if (c
== '\'' || c
== '"')
3211 syntax_error(lineno
, line
, cptr
);
3215 if (rprec
[nrules
] != UNDEFINED
&& bp
->prec
!= rprec
[nrules
])
3218 rprec
[nrules
] = bp
->prec
;
3219 rassoc
[nrules
] = bp
->assoc
;
3228 initialize_grammar();
3243 #if defined(YYBTYACC)
3244 else if (c
== L_CURL
|| c
== '=' || (backtrack
&& c
== L_BRAC
))
3246 else if (c
== L_CURL
|| c
== '=')
3252 start_rule(plhs
[nrules
- 1], 0);
3261 syntax_error(lineno
, line
, cptr
);
3264 #if defined(YYBTYACC)
3266 start_requires_args(goal
->name
);
3278 for (i
= 0; i
< ntags
; ++i
)
3280 assert(tag_table
[i
]);
3292 name_pool_size
= 13; /* 13 == sizeof("$end") + sizeof("$accept") */
3293 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3294 name_pool_size
+= strlen(bp
->name
) + 1;
3296 name_pool
= TMALLOC(char, name_pool_size
);
3297 NO_SPACE(name_pool
);
3299 strcpy(name_pool
, "$accept");
3300 strcpy(name_pool
+ 8, "$end");
3302 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3306 while ((*t
++ = *s
++) != 0)
3318 if (goal
->class == UNKNOWN
)
3319 undefined_goal(goal
->name
);
3321 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3323 if (bp
->class == UNKNOWN
)
3325 undefined_symbol_warning(bp
->name
);
3332 protect_string(char *src
, char **des
)
3345 if ('\\' == *s
|| '"' == *s
)
3351 *des
= d
= TMALLOC(char, len
);
3357 if ('\\' == *s
|| '"' == *s
)
3371 #if defined(YYBTYACC)
3372 Value_t max_tok_pval
;
3377 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3380 if (bp
->class == TERM
)
3383 start_symbol
= (Value_t
)ntokens
;
3384 nvars
= (Value_t
)(nsyms
- ntokens
);
3386 symbol_name
= TMALLOC(char *, nsyms
);
3387 NO_SPACE(symbol_name
);
3389 symbol_value
= TMALLOC(Value_t
, nsyms
);
3390 NO_SPACE(symbol_value
);
3392 symbol_prec
= TMALLOC(Value_t
, nsyms
);
3393 NO_SPACE(symbol_prec
);
3395 symbol_assoc
= TMALLOC(char, nsyms
);
3396 NO_SPACE(symbol_assoc
);
3398 #if defined(YYBTYACC)
3399 symbol_pval
= TMALLOC(Value_t
, nsyms
);
3400 NO_SPACE(symbol_pval
);
3404 symbol_destructor
= CALLOC(sizeof(char *), nsyms
);
3405 NO_SPACE(symbol_destructor
);
3407 symbol_type_tag
= CALLOC(sizeof(char *), nsyms
);
3408 NO_SPACE(symbol_type_tag
);
3412 v
= TMALLOC(bucket
*, nsyms
);
3416 v
[start_symbol
] = 0;
3419 j
= (Value_t
)(start_symbol
+ 1);
3420 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
3422 if (bp
->class == TERM
)
3427 assert(i
== ntokens
&& j
== nsyms
);
3429 for (i
= 1; i
< ntokens
; ++i
)
3432 goal
->index
= (Index_t
)(start_symbol
+ 1);
3433 k
= (Value_t
)(start_symbol
+ 2);
3443 for (i
= (Value_t
)(start_symbol
+ 1); i
< nsyms
; ++i
)
3453 for (i
= 1; i
< ntokens
; ++i
)
3458 for (j
= k
++; j
> 0 && symbol_value
[j
- 1] > n
; --j
)
3459 symbol_value
[j
] = symbol_value
[j
- 1];
3460 symbol_value
[j
] = n
;
3466 if (v
[1]->value
== UNDEFINED
)
3471 for (i
= 2; i
< ntokens
; ++i
)
3473 if (v
[i
]->value
== UNDEFINED
)
3475 while (j
< k
&& n
== symbol_value
[j
])
3477 while (++j
< k
&& n
== symbol_value
[j
])
3486 symbol_name
[0] = name_pool
+ 8;
3487 symbol_value
[0] = 0;
3489 symbol_assoc
[0] = TOKEN
;
3490 #if defined(YYBTYACC)
3494 for (i
= 1; i
< ntokens
; ++i
)
3496 symbol_name
[i
] = v
[i
]->name
;
3497 symbol_value
[i
] = v
[i
]->value
;
3498 symbol_prec
[i
] = v
[i
]->prec
;
3499 symbol_assoc
[i
] = v
[i
]->assoc
;
3500 #if defined(YYBTYACC)
3501 symbol_pval
[i
] = v
[i
]->value
;
3502 if (symbol_pval
[i
] > max_tok_pval
)
3503 max_tok_pval
= symbol_pval
[i
];
3506 symbol_destructor
[i
] = v
[i
]->destructor
;
3507 symbol_type_tag
[i
] = v
[i
]->tag
;
3511 symbol_name
[start_symbol
] = name_pool
;
3512 symbol_value
[start_symbol
] = -1;
3513 symbol_prec
[start_symbol
] = 0;
3514 symbol_assoc
[start_symbol
] = TOKEN
;
3515 #if defined(YYBTYACC)
3516 symbol_pval
[start_symbol
] = (Value_t
)(max_tok_pval
+ 1);
3518 for (++i
; i
< nsyms
; ++i
)
3521 symbol_name
[k
] = v
[i
]->name
;
3522 symbol_value
[k
] = v
[i
]->value
;
3523 symbol_prec
[k
] = v
[i
]->prec
;
3524 symbol_assoc
[k
] = v
[i
]->assoc
;
3525 #if defined(YYBTYACC)
3526 symbol_pval
[k
] = (Value_t
)((max_tok_pval
+ 1) + v
[i
]->value
+ 1);
3529 symbol_destructor
[k
] = v
[i
]->destructor
;
3530 symbol_type_tag
[k
] = v
[i
]->tag
;
3537 symbol_pname
= TMALLOC(char *, nsyms
);
3538 NO_SPACE(symbol_pname
);
3540 for (i
= 0; i
< nsyms
; ++i
)
3541 protect_string(symbol_name
[i
], &(symbol_pname
[i
]));
3555 ritem
= TMALLOC(Value_t
, nitems
);
3558 rlhs
= TMALLOC(Value_t
, nrules
);
3561 rrhs
= TMALLOC(Value_t
, nrules
+ 1);
3564 rprec
= TREALLOC(Value_t
, rprec
, nrules
);
3567 rassoc
= TREALLOC(Assoc_t
, rassoc
, nrules
);
3571 ritem
[1] = goal
->index
;
3576 rlhs
[2] = start_symbol
;
3582 for (i
= 3; i
< nrules
; ++i
)
3584 #if defined(YYBTYACC)
3585 if (plhs
[i
]->args
> 0)
3587 if (plhs
[i
]->argnames
)
3589 FREE(plhs
[i
]->argnames
);
3590 plhs
[i
]->argnames
= NULL
;
3592 if (plhs
[i
]->argtags
)
3594 FREE(plhs
[i
]->argtags
);
3595 plhs
[i
]->argtags
= NULL
;
3598 #endif /* defined(YYBTYACC) */
3599 rlhs
[i
] = plhs
[i
]->index
;
3605 ritem
[j
] = pitem
[j
]->index
;
3606 if (pitem
[j
]->class == TERM
)
3608 prec2
= pitem
[j
]->prec
;
3609 assoc
= pitem
[j
]->assoc
;
3613 ritem
[j
] = (Value_t
)-i
;
3615 if (rprec
[i
] == UNDEFINED
)
3625 #if defined(YYBTYACC)
3634 size_t j
, spacing
= 0;
3635 FILE *f
= verbose_file
;
3641 for (i
= 2; i
< nrules
; ++i
)
3643 if (rlhs
[i
] != rlhs
[i
- 1])
3647 fprintf(f
, "%4d %s :", i
- 2, symbol_name
[rlhs
[i
]]);
3648 spacing
= strlen(symbol_name
[rlhs
[i
]]) + 1;
3652 fprintf(f
, "%4d ", i
- 2);
3659 while (ritem
[k
] >= 0)
3661 fprintf(f
, " %s", symbol_name
[ritem
[k
]]);
3669 #if defined(YYBTYACC)
3671 finalize_destructors(void)
3677 for (i
= 2; i
< nsyms
; ++i
)
3679 tag
= symbol_type_tag
[i
];
3680 if (symbol_destructor
[i
] == NULL
)
3683 { /* use <> destructor, if there is one */
3684 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) != NULL
)
3686 symbol_destructor
[i
] = TMALLOC(char,
3687 strlen(bp
->destructor
) + 1);
3688 NO_SPACE(symbol_destructor
[i
]);
3689 strcpy(symbol_destructor
[i
], bp
->destructor
);
3693 { /* use type destructor for this tag, if there is one */
3694 bp
= lookup_type_destructor(tag
);
3695 if (bp
->destructor
!= NULL
)
3697 symbol_destructor
[i
] = TMALLOC(char,
3698 strlen(bp
->destructor
) + 1);
3699 NO_SPACE(symbol_destructor
[i
]);
3700 strcpy(symbol_destructor
[i
], bp
->destructor
);
3703 { /* use <*> destructor, if there is one */
3704 if ((bp
= default_destructor
[TYPED_DEFAULT
]) != NULL
)
3705 /* replace "$$" with "(*val).tag" in destructor code */
3706 symbol_destructor
[i
]
3707 = process_destructor_XX(bp
->destructor
, tag
);
3712 { /* replace "$$" with "(*val)[.tag]" in destructor code */
3713 symbol_destructor
[i
]
3714 = process_destructor_XX(symbol_destructor
[i
], tag
);
3717 /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
3718 DO_FREE(symbol_type_tag
); /* no longer needed */
3719 if ((bp
= default_destructor
[UNTYPED_DEFAULT
]) != NULL
)
3722 /* 'bp->tag' is a static value, don't free */
3723 FREE(bp
->destructor
);
3726 if ((bp
= default_destructor
[TYPED_DEFAULT
]) != NULL
)
3729 /* 'bp->tag' is a static value, don't free */
3730 FREE(bp
->destructor
);
3733 if ((bp
= default_destructor
[TYPE_SPECIFIED
]) != NULL
)
3740 /* 'bp->tag' freed by 'free_tags()' */
3741 FREE(bp
->destructor
);
3746 #endif /* defined(YYBTYACC) */
3751 write_section(code_file
, banner
);
3752 create_symbol_table();
3753 read_declarations();
3755 free_symbol_table();
3762 #if defined(YYBTYACC)
3764 finalize_destructors();
3771 free_declarations(param
*list
)
3775 param
*next
= list
->next
;
3788 lex_param
= free_declarations(lex_param
);
3789 parse_param
= free_declarations(parse_param
);
3799 DO_FREE(symbol_name
);
3800 DO_FREE(symbol_prec
);
3801 DO_FREE(symbol_assoc
);
3802 DO_FREE(symbol_value
);
3803 #if defined(YYBTYACC)
3804 DO_FREE(symbol_pval
);
3805 DO_FREE(symbol_destructor
);
3806 DO_FREE(symbol_type_tag
);