1 /* $OpenBSD: reader.c,v 1.34 2017/05/25 20:11:03 tedu Exp $ */
2 /* $NetBSD: reader.c,v 1.5 1996/03/19 03:21:43 jtc Exp $ */
5 * Copyright (c) 1989 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 /* The line size must be a positive integer. One hundred was chosen */
40 /* because few lines in Yacc input grammars exceed 100 characters. */
41 /* Note that if a line exceeds LINESIZE characters, the line buffer */
42 /* will be expanded to accommodate it. */
52 char saw_eof
, unionized
;
73 void skip_comment(void);
76 void copy_ident(void);
78 void copy_union(void);
79 bucket
*get_literal(void);
80 int is_reserved(char *);
81 bucket
*get_name(void);
84 void declare_tokens(int);
85 void declare_types(void);
86 void declare_start(void);
87 void handle_expect(void);
88 void read_declarations(void);
89 void initialize_grammar(void);
90 void expand_items(void);
91 void expand_rules(void);
92 void advance_to_start(void);
93 void start_rule(bucket
*, int);
95 void insert_empty_rule(void);
96 void add_symbol(void);
97 void copy_action(void);
98 int mark_symbol(void);
99 void read_grammar(void);
100 void free_tags(void);
101 void pack_names(void);
102 void check_symbols(void);
103 void pack_symbols(void);
104 void pack_grammar(void);
105 void print_grammar(void);
107 char line_format
[] = "#line %d \"%s\"\n";
113 if (cinc
>= cache_size
) {
115 cache
= realloc(cache
, cache_size
);
127 FILE *f
= input_file
;
130 if (saw_eof
|| (c
= getc(f
)) == EOF
) {
139 if (line
== NULL
|| linesize
!= (LINESIZE
+ 1)) {
141 linesize
= LINESIZE
+ 1;
142 line
= malloc(linesize
);
154 if (++i
>= linesize
) {
155 linesize
+= LINESIZE
;
156 line
= realloc(line
, linesize
);
181 p
= malloc(s
- line
+ 1);
187 while ((*t
++ = *s
++) != '\n')
197 int st_lineno
= lineno
;
198 char *st_line
= dup_line();
199 char *st_cptr
= st_line
+ (cptr
- line
);
203 if (*s
== '*' && s
[1] == '/') {
211 unterminated_comment(st_lineno
, st_line
, st_cptr
);
259 } else if (s
[1] == '/') {
270 return ((unsigned char) *s
);
282 c
= (unsigned char) *++cptr
;
290 } else if (isdigit(c
) || c
== '_' || c
== '.' || c
== '$')
294 c
= (unsigned char) *++cptr
;
298 if (strcmp(cache
, "token") == 0 || strcmp(cache
, "term") == 0)
300 if (strcmp(cache
, "type") == 0)
302 if (strcmp(cache
, "left") == 0)
304 if (strcmp(cache
, "right") == 0)
306 if (strcmp(cache
, "nonassoc") == 0 || strcmp(cache
, "binary") == 0)
308 if (strcmp(cache
, "start") == 0)
310 if (strcmp(cache
, "union") == 0)
312 if (strcmp(cache
, "ident") == 0)
314 if (strcmp(cache
, "expect") == 0)
320 if (c
== '%' || c
== '\\')
331 syntax_error(lineno
, line
, t_cptr
);
341 FILE *f
= output_file
;
347 syntax_error(lineno
, line
, cptr
);
349 fprintf(f
, "#ident \"");
351 c
= (unsigned char) *++cptr
;
372 int need_newline
= 0;
373 int t_lineno
= lineno
;
374 char *t_line
= dup_line();
375 char *t_cptr
= t_line
+ (cptr
- line
- 2);
380 unterminated_text(t_lineno
, t_line
, t_cptr
);
383 fprintf(f
, line_format
, lineno
, input_file_name
);
386 c
= (unsigned char) *cptr
++;
395 unterminated_text(t_lineno
, t_line
, t_cptr
);
399 int s_lineno
= lineno
;
400 char *s_line
= dup_line();
401 char *s_cptr
= s_line
+ (cptr
- line
- 1);
406 c
= (unsigned char) *cptr
++;
414 unterminated_string(s_lineno
, s_line
, s_cptr
);
416 c
= (unsigned char) *cptr
++;
421 unterminated_string(s_lineno
, s_line
, s_cptr
);
430 c
= (unsigned char) *cptr
;
433 while ((c
= (unsigned char) *++cptr
) != '\n') {
434 if (c
== '*' && cptr
[1] == '/')
443 int c_lineno
= lineno
;
444 char *c_line
= dup_line();
445 char *c_cptr
= c_line
+ (cptr
- line
- 1);
450 c
= (unsigned char) *cptr
++;
452 if (c
== '*' && *cptr
== '/') {
461 unterminated_comment(c_lineno
, c_line
, c_cptr
);
491 int u_lineno
= lineno
;
492 char *u_line
= dup_line();
493 char *u_cptr
= u_line
+ (cptr
- line
- 6);
496 over_unionized(cptr
- 6);
500 fprintf(text_file
, line_format
, lineno
, input_file_name
);
502 fprintf(text_file
, "#ifndef YYSTYPE_DEFINED\n");
503 fprintf(text_file
, "#define YYSTYPE_DEFINED\n");
504 fprintf(text_file
, "typedef union");
506 fprintf(union_file
, "#ifndef YYSTYPE_DEFINED\n");
507 fprintf(union_file
, "#define YYSTYPE_DEFINED\n");
508 fprintf(union_file
, "typedef union");
513 c
= (unsigned char) *cptr
++;
522 unterminated_union(u_lineno
, u_line
, u_cptr
);
531 fprintf(text_file
, " YYSTYPE;\n");
532 fprintf(text_file
, "#endif /* YYSTYPE_DEFINED */\n");
540 int s_lineno
= lineno
;
541 char *s_line
= dup_line();
542 char *s_cptr
= s_line
+ (cptr
- line
- 1);
546 c
= (unsigned char) *cptr
++;
555 unterminated_string(s_lineno
, s_line
, s_cptr
);
557 c
= (unsigned char) *cptr
++;
564 unterminated_string(s_lineno
,
572 c
= (unsigned char) *cptr
;
574 putc('*', text_file
);
576 putc('*', union_file
);
577 while ((c
= (unsigned char) *++cptr
) != '\n') {
578 if (c
== '*' && cptr
[1] == '/') {
579 fprintf(text_file
, "* ");
581 fprintf(union_file
, "* ");
588 fprintf(text_file
, "*/\n");
590 fprintf(union_file
, "*/\n");
594 int c_lineno
= lineno
;
595 char *c_line
= dup_line();
596 char *c_cptr
= c_line
+ (cptr
- line
- 1);
598 putc('*', text_file
);
600 putc('*', union_file
);
603 c
= (unsigned char) *cptr
++;
607 if (c
== '*' && *cptr
== '/') {
608 putc('/', text_file
);
610 putc('/', union_file
);
618 unterminated_comment(c_lineno
,
637 int s_lineno
= lineno
;
638 char *s_line
= dup_line();
639 char *s_cptr
= s_line
+ (cptr
- line
);
641 quote
= (unsigned char) *cptr
++;
644 c
= (unsigned char) *cptr
++;
648 unterminated_string(s_lineno
, s_line
, s_cptr
);
650 char *c_cptr
= cptr
- 1;
653 c
= (unsigned char) *cptr
++;
658 unterminated_string(s_lineno
, s_line
,
670 ulval
= strtoul(cptr
- 1, &s
, 8);
671 if (s
== cptr
- 1 || ulval
> MAXCHAR
)
672 illegal_character(c_cptr
);
678 ulval
= strtoul(cptr
, &s
, 16);
679 if (s
== cptr
|| ulval
> MAXCHAR
)
680 illegal_character(c_cptr
);
725 for (i
= 0; i
< n
; ++i
) {
726 c
= ((unsigned char *) s
)[i
];
727 if (c
== '\\' || c
== cache
[0]) {
730 } else if (isprint(c
))
757 cachec(((c
>> 6) & 7) + '0');
758 cachec(((c
>> 3) & 7) + '0');
759 cachec((c
& 7) + '0');
773 if (n
== 1 && bp
->value
== UNDEFINED
)
774 bp
->value
= *(unsigned char *) s
;
782 is_reserved(char *name
)
786 if (strcmp(name
, ".") == 0 ||
787 strcmp(name
, "$accept") == 0 ||
788 strcmp(name
, "$end") == 0)
791 if (name
[0] == '$' && name
[1] == '$' && isdigit((unsigned char) name
[2])) {
793 while (isdigit((unsigned char) *s
))
808 for (c
= (unsigned char) *cptr
; IS_IDENT(c
); c
= (unsigned char) *++cptr
)
812 if (is_reserved(cache
))
813 used_reserved(cache
);
815 return (lookup(cache
));
825 ul
= strtoul(cptr
, &p
, 10);
827 syntax_error(lineno
, line
, cptr
);
838 int t_lineno
= lineno
;
839 char *t_line
= dup_line();
840 char *t_cptr
= t_line
+ (cptr
- line
);
846 if (!isalpha(c
) && c
!= '_' && c
!= '$')
847 illegal_tag(t_lineno
, t_line
, t_cptr
);
852 c
= (unsigned char) *++cptr
;
853 } while (IS_IDENT(c
));
860 illegal_tag(t_lineno
, t_line
, t_cptr
);
864 for (i
= 0; i
< ntags
; ++i
) {
865 if (strcmp(cache
, tag_table
[i
]) == 0)
866 return (tag_table
[i
]);
869 if (ntags
>= tagmax
) {
871 tag_table
= reallocarray(tag_table
, tagmax
, sizeof(char *));
872 if (tag_table
== NULL
)
878 strlcpy(s
, cache
, cinc
);
879 tag_table
[ntags
] = s
;
886 declare_tokens(int assoc
)
906 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
908 else if (c
== '\'' || c
== '"')
914 tokenized_start(bp
->name
);
918 if (bp
->tag
&& tag
!= bp
->tag
)
919 retyped_warning(bp
->name
);
922 if (assoc
!= TOKEN
) {
923 if (bp
->prec
&& prec
!= bp
->prec
)
924 reprec_warning(bp
->name
);
932 value
= get_number();
933 if (bp
->value
!= UNDEFINED
&& value
!= bp
->value
)
934 revalued_warning(bp
->name
);
945 * %expect requires special handling as it really isn't part of the yacc
946 * grammar only a flag for yacc proper.
949 declare_expect(int assoc
)
957 * Stay away from nextc - doesn't detect EOL and will read to EOF.
959 c
= (unsigned char) *++cptr
;
965 SRexpect
= get_number();
969 * Looking for number before EOL.
970 * Spaces, tabs, and numbers are ok.
971 * Words, punc., etc. are syntax errors.
973 else if (c
== '\n' || isalpha(c
) || !isspace(c
)) {
974 syntax_error(lineno
, line
, cptr
);
976 c
= (unsigned char) *++cptr
;
995 syntax_error(lineno
, line
, cptr
);
1000 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1002 else if (c
== '\'' || c
== '"')
1007 if (bp
->tag
&& tag
!= bp
->tag
)
1008 retyped_warning(bp
->name
);
1023 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '$')
1024 syntax_error(lineno
, line
, cptr
);
1026 if (bp
->class == TERM
)
1027 terminal_start(bp
->name
);
1028 if (goal
&& goal
!= bp
)
1029 restarted_warning();
1035 read_declarations(void)
1040 cache
= malloc(cache_size
);
1049 syntax_error(lineno
, line
, cptr
);
1050 switch (k
= keyword()) {
1090 initialize_grammar(void)
1094 pitem
= calloc(maxitems
, sizeof(bucket
*));
1100 plhs
= reallocarray(NULL
, maxrules
, sizeof(bucket
*));
1106 rprec
= reallocarray(NULL
, maxrules
, sizeof(short));
1112 rassoc
= reallocarray(NULL
, maxrules
, sizeof(char));
1124 int olditems
= maxitems
;
1127 pitem
= reallocarray(pitem
, maxitems
, sizeof(bucket
*));
1130 memset(pitem
+ olditems
, 0, (maxitems
- olditems
) * sizeof(bucket
*));
1138 plhs
= reallocarray(plhs
, maxrules
, sizeof(bucket
*));
1141 rprec
= reallocarray(rprec
, maxrules
, sizeof(short));
1144 rassoc
= reallocarray(rassoc
, maxrules
, sizeof(char));
1151 advance_to_start(void)
1163 switch (keyword()) {
1176 syntax_error(lineno
, line
, s_cptr
);
1181 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '_')
1182 syntax_error(lineno
, line
, cptr
);
1185 if (bp
->class == TERM
)
1186 terminal_start(bp
->name
);
1194 syntax_error(lineno
, line
, cptr
);
1195 start_rule(bp
, s_lineno
);
1201 start_rule(bucket
* bp
, int s_lineno
)
1203 if (bp
->class == TERM
)
1204 terminal_lhs(s_lineno
);
1205 bp
->class = NONTERM
;
1206 if (nrules
>= maxrules
)
1209 rprec
[nrules
] = UNDEFINED
;
1210 rassoc
[nrules
] = TOKEN
;
1219 if (!last_was_action
&& plhs
[nrules
]->tag
) {
1220 for (i
= nitems
- 1; pitem
[i
]; --i
)
1222 if (i
== maxitems
- 1 || pitem
[i
+ 1] == 0 ||
1223 pitem
[i
+ 1]->tag
!= plhs
[nrules
]->tag
)
1224 default_action_warning();
1226 last_was_action
= 0;
1227 if (nitems
>= maxitems
)
1236 insert_empty_rule(void)
1241 snprintf(cache
, cache_size
, "$$%d", ++gensym
);
1242 bp
= make_bucket(cache
);
1243 last_symbol
->next
= bp
;
1245 bp
->tag
= plhs
[nrules
]->tag
;
1246 bp
->class = NONTERM
;
1248 if ((nitems
+= 2) > maxitems
)
1250 bpp
= pitem
+ nitems
- 1;
1252 while ((bpp
[0] = bpp
[-1]))
1255 if (++nrules
>= maxrules
)
1257 plhs
[nrules
] = plhs
[nrules
- 1];
1258 plhs
[nrules
- 1] = bp
;
1259 rprec
[nrules
] = rprec
[nrules
- 1];
1260 rprec
[nrules
- 1] = 0;
1261 rassoc
[nrules
] = rassoc
[nrules
- 1];
1262 rassoc
[nrules
- 1] = TOKEN
;
1271 int s_lineno
= lineno
;
1273 c
= (unsigned char) *cptr
;
1274 if (c
== '\'' || c
== '"')
1282 start_rule(bp
, s_lineno
);
1286 if (last_was_action
)
1287 insert_empty_rule();
1288 last_was_action
= 0;
1290 if (++nitems
> maxitems
)
1292 pitem
[nitems
- 1] = bp
;
1299 int c
, i
, n
, depth
, quote
;
1301 FILE *f
= action_file
;
1302 int a_lineno
= lineno
;
1303 char *a_line
= dup_line();
1304 char *a_cptr
= a_line
+ (cptr
- line
);
1306 if (last_was_action
)
1307 insert_empty_rule();
1308 last_was_action
= 1;
1310 fprintf(f
, "case %d:\n", nrules
- 2);
1312 fprintf(f
, line_format
, lineno
, input_file_name
);
1317 for (i
= nitems
- 1; pitem
[i
]; --i
)
1322 c
= (unsigned char) *cptr
;
1324 if (cptr
[1] == '<') {
1325 int d_lineno
= lineno
;
1326 char *d_line
= dup_line();
1327 char *d_cptr
= d_line
+ (cptr
- line
);
1331 c
= (unsigned char) *cptr
;
1333 fprintf(f
, "yyval.%s", tag
);
1337 } else if (isdigit(c
)) {
1340 dollar_warning(d_lineno
, i
);
1341 fprintf(f
, "yyvsp[%d].%s", i
- n
, tag
);
1344 } else if (c
== '-' && isdigit((unsigned char) cptr
[1])) {
1346 i
= -get_number() - n
;
1347 fprintf(f
, "yyvsp[%d].%s", i
, tag
);
1351 dollar_error(d_lineno
, d_line
, d_cptr
);
1352 } else if (cptr
[1] == '$') {
1354 tag
= plhs
[nrules
]->tag
;
1357 fprintf(f
, "yyval.%s", tag
);
1359 fprintf(f
, "yyval");
1362 } else if (isdigit((unsigned char) cptr
[1])) {
1366 if (i
<= 0 || i
> n
)
1368 tag
= pitem
[nitems
+ i
- n
- 1]->tag
;
1370 untyped_rhs(i
, pitem
[nitems
+ i
- n
- 1]->name
);
1371 fprintf(f
, "yyvsp[%d].%s", i
- n
, tag
);
1374 dollar_warning(lineno
, i
);
1375 fprintf(f
, "yyvsp[%d]", i
- n
);
1378 } else if (cptr
[1] == '-') {
1383 fprintf(f
, "yyvsp[%d]", -i
- n
);
1387 if (isalpha(c
) || c
== '_' || c
== '$') {
1390 c
= (unsigned char) *++cptr
;
1391 } while (isalnum(c
) || c
== '_' || c
== '$');
1402 unterminated_action(a_lineno
, a_line
, a_cptr
);
1407 fprintf(f
, "\nbreak;\n");
1418 fprintf(f
, "\nbreak;\n");
1424 int s_lineno
= lineno
;
1425 char *s_line
= dup_line();
1426 char *s_cptr
= s_line
+ (cptr
- line
- 1);
1430 c
= (unsigned char) *cptr
++;
1437 unterminated_string(s_lineno
, s_line
, s_cptr
);
1439 c
= (unsigned char) *cptr
++;
1444 unterminated_string(s_lineno
, s_line
, s_cptr
);
1451 c
= (unsigned char) *cptr
;
1454 while ((c
= (unsigned char) *++cptr
) != '\n') {
1455 if (c
== '*' && cptr
[1] == '/')
1464 int c_lineno
= lineno
;
1465 char *c_line
= dup_line();
1466 char *c_cptr
= c_line
+ (cptr
- line
- 1);
1471 c
= (unsigned char) *cptr
++;
1473 if (c
== '*' && *cptr
== '/') {
1482 unterminated_comment(c_lineno
, c_line
, c_cptr
);
1500 c
= (unsigned char) cptr
[1];
1501 if (c
== '%' || c
== '\\') {
1507 else if ((c
== 'p' || c
== 'P') &&
1508 ((c
= cptr
[2]) == 'r' || c
== 'R') &&
1509 ((c
= cptr
[3]) == 'e' || c
== 'E') &&
1510 ((c
= cptr
[4]) == 'c' || c
== 'C') &&
1511 ((c
= (unsigned char) cptr
[5], !IS_IDENT(c
))))
1514 syntax_error(lineno
, line
, cptr
);
1517 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1519 else if (c
== '\'' || c
== '"')
1522 syntax_error(lineno
, line
, cptr
);
1526 if (rprec
[nrules
] != UNDEFINED
&& bp
->prec
!= rprec
[nrules
])
1529 rprec
[nrules
] = bp
->prec
;
1530 rassoc
[nrules
] = bp
->assoc
;
1540 initialize_grammar();
1547 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$' || c
== '\'' ||
1550 else if (c
== '{' || c
== '=')
1552 else if (c
== '|') {
1554 start_rule(plhs
[nrules
- 1], 0);
1556 } else if (c
== '%') {
1560 syntax_error(lineno
, line
, cptr
);
1571 if (tag_table
== NULL
)
1574 for (i
= 0; i
< ntags
; ++i
) {
1575 assert(tag_table
[i
]);
1588 name_pool_size
= 13; /* 13 == sizeof("$end") + sizeof("$accept") */
1589 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1590 name_pool_size
+= strlen(bp
->name
) + 1;
1591 name_pool
= malloc(name_pool_size
);
1592 if (name_pool
== NULL
)
1595 strlcpy(name_pool
, "$accept", name_pool_size
);
1596 strlcpy(name_pool
+ 8, "$end", name_pool_size
- 8);
1598 for (bp
= first_symbol
; bp
; bp
= bp
->next
) {
1601 while ((*t
++ = *s
++))
1614 if (goal
->class == UNKNOWN
)
1615 undefined_goal(goal
->name
);
1617 for (bp
= first_symbol
; bp
; bp
= bp
->next
) {
1618 if (bp
->class == UNKNOWN
) {
1619 undefined_symbol_warning(bp
->name
);
1635 for (bp
= first_symbol
; bp
; bp
= bp
->next
) {
1637 if (bp
->class == TERM
)
1640 start_symbol
= ntokens
;
1641 nvars
= nsyms
- ntokens
;
1643 symbol_name
= reallocarray(NULL
, nsyms
, sizeof(char *));
1644 if (symbol_name
== NULL
)
1646 symbol_value
= reallocarray(NULL
, nsyms
, sizeof(short));
1647 if (symbol_value
== NULL
)
1649 symbol_prec
= reallocarray(NULL
, nsyms
, sizeof(short));
1650 if (symbol_prec
== NULL
)
1652 symbol_assoc
= malloc(nsyms
);
1653 if (symbol_assoc
== NULL
)
1656 v
= reallocarray(NULL
, nsyms
, sizeof(bucket
*));
1661 v
[start_symbol
] = 0;
1664 j
= start_symbol
+ 1;
1665 for (bp
= first_symbol
; bp
; bp
= bp
->next
) {
1666 if (bp
->class == TERM
)
1671 assert(i
== ntokens
&& j
== nsyms
);
1673 for (i
= 1; i
< ntokens
; ++i
)
1676 goal
->index
= start_symbol
+ 1;
1677 k
= start_symbol
+ 2;
1685 for (i
= start_symbol
+ 1; i
< nsyms
; ++i
) {
1693 for (i
= 1; i
< ntokens
; ++i
) {
1696 for (j
= k
++; j
> 0 && symbol_value
[j
- 1] > n
; --j
)
1697 symbol_value
[j
] = symbol_value
[j
- 1];
1698 symbol_value
[j
] = n
;
1702 if (v
[1]->value
== UNDEFINED
)
1707 for (i
= 2; i
< ntokens
; ++i
) {
1708 if (v
[i
]->value
== UNDEFINED
) {
1709 while (j
< k
&& n
== symbol_value
[j
]) {
1710 while (++j
< k
&& n
== symbol_value
[j
])
1719 symbol_name
[0] = name_pool
+ 8;
1720 symbol_value
[0] = 0;
1722 symbol_assoc
[0] = TOKEN
;
1723 for (i
= 1; i
< ntokens
; ++i
) {
1724 symbol_name
[i
] = v
[i
]->name
;
1725 symbol_value
[i
] = v
[i
]->value
;
1726 symbol_prec
[i
] = v
[i
]->prec
;
1727 symbol_assoc
[i
] = v
[i
]->assoc
;
1729 symbol_name
[start_symbol
] = name_pool
;
1730 symbol_value
[start_symbol
] = -1;
1731 symbol_prec
[start_symbol
] = 0;
1732 symbol_assoc
[start_symbol
] = TOKEN
;
1733 for (++i
; i
< nsyms
; ++i
) {
1735 symbol_name
[k
] = v
[i
]->name
;
1736 symbol_value
[k
] = v
[i
]->value
;
1737 symbol_prec
[k
] = v
[i
]->prec
;
1738 symbol_assoc
[k
] = v
[i
]->assoc
;
1751 ritem
= reallocarray(NULL
, nitems
, sizeof(short));
1754 rlhs
= reallocarray(NULL
, nrules
, sizeof(short));
1757 rrhs
= reallocarray(NULL
, nrules
+ 1, sizeof(short));
1760 rprec
= reallocarray(rprec
, nrules
, sizeof(short));
1763 rassoc
= realloc(rassoc
, nrules
);
1768 ritem
[1] = goal
->index
;
1773 rlhs
[2] = start_symbol
;
1779 for (i
= 3; i
< nrules
; ++i
) {
1780 rlhs
[i
] = plhs
[i
]->index
;
1785 ritem
[j
] = pitem
[j
]->index
;
1786 if (pitem
[j
]->class == TERM
) {
1787 pprec
= pitem
[j
]->prec
;
1788 assoc
= pitem
[j
]->assoc
;
1794 if (rprec
[i
] == UNDEFINED
) {
1811 FILE *f
= verbose_file
;
1817 for (i
= 2; i
< nrules
; ++i
) {
1818 if (rlhs
[i
] != rlhs
[i
- 1]) {
1821 fprintf(f
, "%4d %s :", i
- 2, symbol_name
[rlhs
[i
]]);
1822 spacing
= strlen(symbol_name
[rlhs
[i
]]) + 1;
1824 fprintf(f
, "%4d ", i
- 2);
1831 while (ritem
[k
] >= 0) {
1832 fprintf(f
, " %s", symbol_name
[ritem
[k
]]);
1844 write_section(banner
);
1845 create_symbol_table();
1846 read_declarations();
1848 free_symbol_table();