2 * Copyright (c) 1989 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $FreeBSD: src/usr.bin/yacc/reader.c,v 1.8.2.1 2001/10/05 03:00:44 obrien Exp $
37 * $DragonFly: src/usr.bin/yacc/reader.c,v 1.2 2003/06/17 04:29:34 dillon Exp $
39 * @(#)reader.c 5.7 (Berkeley) 1/20/91
46 /* The line size must be a positive integer. One hundred was chosen */
47 /* because few lines in Yacc input grammars exceed 100 characters. */
48 /* Note that if a line exceeds LINESIZE characters, the line buffer */
49 /* will be expanded to accomodate it. */
59 char saw_eof, unionized;
77 static const char line_format[] = "#line %d \"%s\"\n";
79 static void add_symbol __P((void));
80 static void advance_to_start __P((void));
81 static void cachec __P((int));
82 static void check_symbols __P((void));
83 static void copy_action __P((void));
84 static void copy_ident __P((void));
85 static void copy_text __P((void));
86 static void copy_union __P((void));
87 static void declare_start __P((void));
88 static void declare_tokens __P((int));
89 static void declare_types __P((void));
90 static char *dup_line __P((void));
91 static void end_rule __P((void));
92 static void expand_items __P((void));
93 static void expand_rules __P((void));
94 static void free_tags __P((void));
95 static void get_line __P((void));
96 static bucket *get_literal __P((void));
97 static bucket *get_name __P((void));
98 static int get_number __P((void));
99 static char *get_tag __P((void));
100 static int hexval __P((int));
101 static void initialize_grammar __P((void));
102 static void insert_empty_rule __P((void));
103 static int is_reserved __P((char *));
104 static int keyword __P((void));
105 static int mark_symbol __P((void));
106 static int nextc __P((void));
107 static void pack_grammar __P((void));
108 static void pack_names __P((void));
109 static void pack_symbols __P((void));
110 static void print_grammar __P((void));
111 static void read_declarations __P((void));
112 static void read_grammar __P((void));
113 static void skip_comment __P((void));
114 static void start_rule __P((bucket *, int));
121 if (cinc >= cache_size)
124 cache = REALLOC(cache, cache_size);
125 if (cache == 0) no_space();
135 register FILE *f = input_file;
139 if (saw_eof || (c = getc(f)) == EOF)
141 if (line) { FREE(line); line = 0; }
147 if (line == 0 || linesize != (LINESIZE + 1))
149 if (line) FREE(line);
150 linesize = LINESIZE + 1;
151 line = MALLOC(linesize);
152 if (line == 0) no_space();
160 if (c == '\n') { cptr = line; return; }
163 linesize += LINESIZE;
164 line = REALLOC(line, linesize);
165 if (line == 0) no_space();
182 register char *p, *s, *t;
184 if (line == 0) return (0);
186 while (*s != '\n') ++s;
187 p = MALLOC(s - line + 1);
188 if (p == 0) no_space();
192 while ((*t++ = *s++) != '\n') continue;
202 int st_lineno = lineno;
203 char *st_line = dup_line();
204 char *st_cptr = st_line + (cptr - line);
209 if (*s == '*' && s[1] == '/')
219 unterminated_comment(st_lineno, st_line, st_cptr);
247 if (line == 0) return (EOF);
273 else if (s[1] == '/')
276 if (line == 0) return (EOF);
304 if (isupper(c)) c = tolower(c);
307 else if (isdigit(c) || c == '_' || c == '.' || c == '$')
315 if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0)
317 if (strcmp(cache, "type") == 0)
319 if (strcmp(cache, "left") == 0)
321 if (strcmp(cache, "right") == 0)
323 if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0)
325 if (strcmp(cache, "start") == 0)
327 if (strcmp(cache, "union") == 0)
329 if (strcmp(cache, "ident") == 0)
331 if (strcmp(cache, "expect") == 0)
339 if (c == '%' || c == '\\')
350 syntax_error(lineno, line, t_cptr);
360 register FILE *f = output_file;
363 if (c == EOF) unexpected_EOF();
364 if (c != '"') syntax_error(lineno, line, cptr);
366 fprintf(f, "#ident \"");
391 register FILE *f = text_file;
392 int need_newline = 0;
393 int t_lineno = lineno;
394 char *t_line = dup_line();
395 char *t_cptr = t_line + (cptr - line - 2);
401 unterminated_text(t_lineno, t_line, t_cptr);
403 if (!lflag) fprintf(f, line_format, lineno, input_file_name);
415 unterminated_text(t_lineno, t_line, t_cptr);
420 int s_lineno = lineno;
421 char *s_line = dup_line();
422 char *s_cptr = s_line + (cptr - line - 1);
437 unterminated_string(s_lineno, s_line, s_cptr);
446 unterminated_string(s_lineno, s_line, s_cptr);
459 while ((c = *++cptr) != '\n')
461 if (c == '*' && cptr[1] == '/')
471 int c_lineno = lineno;
472 char *c_line = dup_line();
473 char *c_cptr = c_line + (cptr - line - 1);
481 if (c == '*' && *cptr == '/')
492 unterminated_comment(c_lineno, c_line, c_cptr);
503 if (need_newline) putc('\n', f);
524 int u_lineno = lineno;
525 char *u_line = dup_line();
526 char *u_cptr = u_line + (cptr - line - 6);
528 if (unionized) over_unionized(cptr - 6);
532 fprintf(text_file, line_format, lineno, input_file_name);
534 fprintf(text_file, "typedef union");
535 if (dflag) fprintf(union_file, "typedef union");
541 if (dflag) putc(c, union_file);
547 if (line == 0) unterminated_union(u_lineno, u_line, u_cptr);
557 fprintf(text_file, " YYSTYPE;\n");
566 int s_lineno = lineno;
567 char *s_line = dup_line();
568 char *s_cptr = s_line + (cptr - line - 1);
575 if (dflag) putc(c, union_file);
582 unterminated_string(s_lineno, s_line, s_cptr);
587 if (dflag) putc(c, union_file);
592 unterminated_string(s_lineno, s_line, s_cptr);
602 putc('*', text_file);
603 if (dflag) putc('*', union_file);
604 while ((c = *++cptr) != '\n')
606 if (c == '*' && cptr[1] == '/')
608 fprintf(text_file, "* ");
609 if (dflag) fprintf(union_file, "* ");
614 if (dflag) putc(c, union_file);
617 fprintf(text_file, "*/\n");
618 if (dflag) fprintf(union_file, "*/\n");
623 int c_lineno = lineno;
624 char *c_line = dup_line();
625 char *c_cptr = c_line + (cptr - line - 1);
627 putc('*', text_file);
628 if (dflag) putc('*', union_file);
634 if (dflag) putc(c, union_file);
635 if (c == '*' && *cptr == '/')
637 putc('/', text_file);
638 if (dflag) putc('/', union_file);
647 unterminated_comment(c_lineno, c_line, c_cptr);
663 if (c >= '0' && c <= '9')
665 if (c >= 'A' && c <= 'F')
666 return (c - 'A' + 10);
667 if (c >= 'a' && c <= 'f')
668 return (c - 'a' + 10);
676 register int c, quote;
681 int s_lineno = lineno;
682 char *s_line = dup_line();
683 char *s_cptr = s_line + (cptr - line);
690 if (c == quote) break;
691 if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr);
694 char *c_cptr = cptr - 1;
701 if (line == 0) unterminated_string(s_lineno, s_line, s_cptr);
704 case '0': case '1': case '2': case '3':
705 case '4': case '5': case '6': case '7':
710 n = (n << 3) + (c - '0');
714 n = (n << 3) + (c - '0');
718 if (n > MAXCHAR) illegal_character(c_cptr);
725 if (n < 0 || n >= 16)
726 illegal_character(c_cptr);
731 if (i < 0 || i >= 16) break;
734 if (n > MAXCHAR) illegal_character(c_cptr);
739 case 'a': c = 7; break;
740 case 'b': c = '\b'; break;
741 case 'f': c = '\f'; break;
742 case 'n': c = '\n'; break;
743 case 'r': c = '\r'; break;
744 case 't': c = '\t'; break;
745 case 'v': c = '\v'; break;
754 if (s == 0) no_space();
756 for (i = 0; i < n; ++i)
765 for (i = 0; i < n; ++i)
767 c = ((unsigned char *)s)[i];
768 if (c == '\\' || c == cache[0])
780 case 7: cachec('a'); break;
781 case '\b': cachec('b'); break;
782 case '\f': cachec('f'); break;
783 case '\n': cachec('n'); break;
784 case '\r': cachec('r'); break;
785 case '\t': cachec('t'); break;
786 case '\v': cachec('v'); break;
788 cachec(((c >> 6) & 7) + '0');
789 cachec(((c >> 3) & 7) + '0');
790 cachec((c & 7) + '0');
804 if (n == 1 && bp->value == UNDEFINED)
805 bp->value = *(unsigned char *)s;
818 if (strcmp(name, ".") == 0 ||
819 strcmp(name, "$accept") == 0 ||
820 strcmp(name, "$end") == 0)
823 if (name[0] == '$' && name[1] == '$' && isdigit(name[2]))
826 while (isdigit(*s)) ++s;
827 if (*s == NUL) return (1);
840 for (c = *cptr; IS_IDENT(c); c = *++cptr)
844 if (is_reserved(cache)) used_reserved(cache);
846 return (lookup(cache));
857 for (c = *cptr; isdigit(c); c = *++cptr)
858 n = 10*n + (c - '0');
870 int t_lineno = lineno;
871 char *t_line = dup_line();
872 char *t_cptr = t_line + (cptr - line);
876 if (c == EOF) unexpected_EOF();
877 if (!isalpha(c) && c != '_' && c != '$')
878 illegal_tag(t_lineno, t_line, t_cptr);
881 do { cachec(c); c = *++cptr; } while (IS_IDENT(c));
885 if (c == EOF) unexpected_EOF();
887 illegal_tag(t_lineno, t_line, t_cptr);
890 for (i = 0; i < ntags; ++i)
892 if (strcmp(cache, tag_table[i]) == 0)
893 return (tag_table[i]);
899 tag_table = (char **)
900 (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *))
901 : MALLOC(tagmax*sizeof(char *)));
902 if (tag_table == 0) no_space();
906 if (s == 0) no_space();
908 tag_table[ntags] = s;
916 declare_tokens(assoc)
924 if (assoc != TOKEN) ++prec;
927 if (c == EOF) unexpected_EOF();
932 if (c == EOF) unexpected_EOF();
937 if (isalpha(c) || c == '_' || c == '.' || c == '$')
939 else if (c == '\'' || c == '"')
944 if (bp == goal) tokenized_start(bp->name);
949 if (bp->tag && tag != bp->tag)
950 retyped_warning(bp->name);
956 if (bp->prec && prec != bp->prec)
957 reprec_warning(bp->name);
963 if (c == EOF) unexpected_EOF();
967 value = get_number();
968 if (bp->value != UNDEFINED && value != bp->value)
969 revalued_warning(bp->name);
972 if (c == EOF) unexpected_EOF();
979 * %expect requires special handling
980 * as it really isn't part of the yacc
981 * grammar only a flag for yacc proper.
984 declare_expect(assoc)
989 if (assoc != EXPECT) ++prec;
992 * Stay away from nextc - doesn't
993 * detect EOL and will read to EOF.
996 if (c == EOF) unexpected_EOF();
1002 SRexpect = get_number();
1006 * Looking for number before EOL.
1007 * Spaces, tabs, and numbers are ok,
1008 * words, punc., etc. are syntax errors.
1010 else if (c == '\n' || isalpha(c) || !isspace(c))
1012 syntax_error(lineno, line, cptr);
1017 if (c == EOF) unexpected_EOF();
1027 register bucket *bp;
1031 if (c == EOF) unexpected_EOF();
1032 if (c != '<') syntax_error(lineno, line, cptr);
1038 if (isalpha(c) || c == '_' || c == '.' || c == '$')
1040 else if (c == '\'' || c == '"')
1045 if (bp->tag && tag != bp->tag)
1046 retyped_warning(bp->name);
1056 register bucket *bp;
1059 if (c == EOF) unexpected_EOF();
1060 if (!isalpha(c) && c != '_' && c != '.' && c != '$')
1061 syntax_error(lineno, line, cptr);
1063 if (bp->class == TERM)
1064 terminal_start(bp->name);
1065 if (goal && goal != bp)
1066 restarted_warning();
1077 cache = MALLOC(cache_size);
1078 if (cache == 0) no_space();
1083 if (c == EOF) unexpected_EOF();
1084 if (c != '%') syntax_error(lineno, line, cptr);
1085 switch (k = keyword())
1126 initialize_grammar()
1130 pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *));
1131 if (pitem == 0) no_space();
1139 plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *));
1140 if (plhs == 0) no_space();
1144 rprec = (short *) MALLOC(maxrules*sizeof(short));
1145 if (rprec == 0) no_space();
1149 rassoc = (char *) MALLOC(maxrules*sizeof(char));
1150 if (rassoc == 0) no_space();
1161 pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *));
1162 if (pitem == 0) no_space();
1170 plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *));
1171 if (plhs == 0) no_space();
1172 rprec = (short *) REALLOC(rprec, maxrules*sizeof(short));
1173 if (rprec == 0) no_space();
1174 rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char));
1175 if (rassoc == 0) no_space();
1183 register bucket *bp;
1190 if (c != '%') break;
1206 syntax_error(lineno, line, s_cptr);
1211 if (!isalpha(c) && c != '_' && c != '.' && c != '_')
1212 syntax_error(lineno, line, cptr);
1216 if (bp->class == TERM)
1217 terminal_start(bp->name);
1223 if (c == EOF) unexpected_EOF();
1224 if (c != ':') syntax_error(lineno, line, cptr);
1225 start_rule(bp, s_lineno);
1231 start_rule(bp, s_lineno)
1232 register bucket *bp;
1235 if (bp->class == TERM)
1236 terminal_lhs(s_lineno);
1237 bp->class = NONTERM;
1238 if (nrules >= maxrules)
1241 rprec[nrules] = UNDEFINED;
1242 rassoc[nrules] = TOKEN;
1251 if (!last_was_action && plhs[nrules]->tag)
1253 for (i = nitems - 1; pitem[i]; --i) continue;
1254 if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag)
1255 default_action_warning();
1258 last_was_action = 0;
1259 if (nitems >= maxitems) expand_items();
1269 register bucket *bp, **bpp;
1272 sprintf(cache, "$$%d", ++gensym);
1273 bp = make_bucket(cache);
1274 last_symbol->next = bp;
1276 bp->tag = plhs[nrules]->tag;
1277 bp->class = NONTERM;
1279 if ((nitems += 2) > maxitems)
1281 bpp = pitem + nitems - 1;
1283 while ((bpp[0] = bpp[-1])) --bpp;
1285 if (++nrules >= maxrules)
1287 plhs[nrules] = plhs[nrules-1];
1288 plhs[nrules-1] = bp;
1289 rprec[nrules] = rprec[nrules-1];
1290 rprec[nrules-1] = 0;
1291 rassoc[nrules] = rassoc[nrules-1];
1292 rassoc[nrules-1] = TOKEN;
1300 register bucket *bp;
1301 int s_lineno = lineno;
1304 if (c == '\'' || c == '"')
1313 start_rule(bp, s_lineno);
1318 if (last_was_action)
1319 insert_empty_rule();
1320 last_was_action = 0;
1322 if (++nitems > maxitems)
1324 pitem[nitems-1] = bp;
1336 register FILE *f = action_file;
1337 int a_lineno = lineno;
1338 char *a_line = dup_line();
1339 char *a_cptr = a_line + (cptr - line);
1341 if (last_was_action)
1342 insert_empty_rule();
1343 last_was_action = 1;
1345 fprintf(f, "case %d:\n", nrules - 2);
1347 fprintf(f, line_format, lineno, input_file_name);
1348 if (*cptr == '=') ++cptr;
1351 for (i = nitems - 1; pitem[i]; --i) ++n;
1360 int d_lineno = lineno;
1361 char *d_line = dup_line();
1362 char *d_cptr = d_line + (cptr - line);
1369 fprintf(f, "yyval.%s", tag);
1374 else if (isdigit(c))
1377 if (i > n) dollar_warning(d_lineno, i);
1378 fprintf(f, "yyvsp[%d].%s", i - n, tag);
1382 else if (c == '-' && isdigit(cptr[1]))
1385 i = -get_number() - n;
1386 fprintf(f, "yyvsp[%d].%s", i, tag);
1391 dollar_error(d_lineno, d_line, d_cptr);
1393 else if (cptr[1] == '$')
1397 tag = plhs[nrules]->tag;
1398 if (tag == 0) untyped_lhs();
1399 fprintf(f, "yyval.%s", tag);
1402 fprintf(f, "yyval");
1406 else if (isdigit(cptr[1]))
1412 if (i <= 0 || i > n)
1414 tag = pitem[nitems + i - n - 1]->tag;
1415 if (tag == 0) untyped_rhs(i, pitem[nitems + i - n - 1]->name);
1416 fprintf(f, "yyvsp[%d].%s", i - n, tag);
1421 dollar_warning(lineno, i);
1422 fprintf(f, "yyvsp[%d]", i - n);
1426 else if (cptr[1] == '-')
1432 fprintf(f, "yyvsp[%d]", -i - n);
1436 if (isalpha(c) || c == '_' || c == '$')
1442 } while (isalnum(c) || c == '_' || c == '$');
1452 if (line) goto loop;
1453 unterminated_action(a_lineno, a_line, a_cptr);
1456 if (depth > 0) goto loop;
1457 fprintf(f, "\nbreak;\n");
1465 if (--depth > 0) goto loop;
1466 fprintf(f, "\nbreak;\n");
1472 int s_lineno = lineno;
1473 char *s_line = dup_line();
1474 char *s_cptr = s_line + (cptr - line - 1);
1487 unterminated_string(s_lineno, s_line, s_cptr);
1496 unterminated_string(s_lineno, s_line, s_cptr);
1507 while ((c = *++cptr) != '\n')
1509 if (c == '*' && cptr[1] == '/')
1519 int c_lineno = lineno;
1520 char *c_line = dup_line();
1521 char *c_cptr = c_line + (cptr - line - 1);
1529 if (c == '*' && *cptr == '/')
1540 unterminated_comment(c_lineno, c_line, c_cptr);
1556 register bucket *bp = NULL;
1559 if (c == '%' || c == '\\')
1567 else if ((c == 'p' || c == 'P') &&
1568 ((c = cptr[2]) == 'r' || c == 'R') &&
1569 ((c = cptr[3]) == 'e' || c == 'E') &&
1570 ((c = cptr[4]) == 'c' || c == 'C') &&
1571 ((c = cptr[5], !IS_IDENT(c))))
1574 syntax_error(lineno, line, cptr);
1577 if (isalpha(c) || c == '_' || c == '.' || c == '$')
1579 else if (c == '\'' || c == '"')
1583 syntax_error(lineno, line, cptr);
1587 if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
1590 rprec[nrules] = bp->prec;
1591 rassoc[nrules] = bp->assoc;
1601 initialize_grammar();
1607 if (c == EOF) break;
1608 if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' ||
1611 else if (c == '{' || c == '=')
1616 start_rule(plhs[nrules-1], 0);
1621 if (mark_symbol()) break;
1624 syntax_error(lineno, line, cptr);
1635 if (tag_table == 0) return;
1637 for (i = 0; i < ntags; ++i)
1639 assert(tag_table[i]);
1649 register bucket *bp;
1650 register char *p, *s, *t;
1652 name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
1653 for (bp = first_symbol; bp; bp = bp->next)
1654 name_pool_size += strlen(bp->name) + 1;
1655 name_pool = MALLOC(name_pool_size);
1656 if (name_pool == 0) no_space();
1658 strcpy(name_pool, "$accept");
1659 strcpy(name_pool+8, "$end");
1661 for (bp = first_symbol; bp; bp = bp->next)
1665 while ((*t++ = *s++)) continue;
1675 register bucket *bp;
1677 if (goal->class == UNKNOWN)
1678 undefined_goal(goal->name);
1680 for (bp = first_symbol; bp; bp = bp->next)
1682 if (bp->class == UNKNOWN)
1684 undefined_symbol_warning(bp->name);
1694 register bucket *bp;
1695 register bucket **v;
1696 register int i, j, k, n;
1700 for (bp = first_symbol; bp; bp = bp->next)
1703 if (bp->class == TERM) ++ntokens;
1705 start_symbol = ntokens;
1706 nvars = nsyms - ntokens;
1708 symbol_name = (char **) MALLOC(nsyms*sizeof(char *));
1709 if (symbol_name == 0) no_space();
1710 symbol_value = (short *) MALLOC(nsyms*sizeof(short));
1711 if (symbol_value == 0) no_space();
1712 symbol_prec = (short *) MALLOC(nsyms*sizeof(short));
1713 if (symbol_prec == 0) no_space();
1714 symbol_assoc = MALLOC(nsyms);
1715 if (symbol_assoc == 0) no_space();
1717 v = (bucket **) MALLOC(nsyms*sizeof(bucket *));
1718 if (v == 0) no_space();
1721 v[start_symbol] = 0;
1724 j = start_symbol + 1;
1725 for (bp = first_symbol; bp; bp = bp->next)
1727 if (bp->class == TERM)
1732 assert(i == ntokens && j == nsyms);
1734 for (i = 1; i < ntokens; ++i)
1737 goal->index = start_symbol + 1;
1738 k = start_symbol + 2;
1748 for (i = start_symbol + 1; i < nsyms; ++i)
1758 for (i = 1; i < ntokens; ++i)
1763 for (j = k++; j > 0 && symbol_value[j-1] > n; --j)
1764 symbol_value[j] = symbol_value[j-1];
1765 symbol_value[j] = n;
1769 if (v[1]->value == UNDEFINED)
1774 for (i = 2; i < ntokens; ++i)
1776 if (v[i]->value == UNDEFINED)
1778 while (j < k && n == symbol_value[j])
1780 while (++j < k && n == symbol_value[j]) continue;
1788 symbol_name[0] = name_pool + 8;
1789 symbol_value[0] = 0;
1791 symbol_assoc[0] = TOKEN;
1792 for (i = 1; i < ntokens; ++i)
1794 symbol_name[i] = v[i]->name;
1795 symbol_value[i] = v[i]->value;
1796 symbol_prec[i] = v[i]->prec;
1797 symbol_assoc[i] = v[i]->assoc;
1799 symbol_name[start_symbol] = name_pool;
1800 symbol_value[start_symbol] = -1;
1801 symbol_prec[start_symbol] = 0;
1802 symbol_assoc[start_symbol] = TOKEN;
1803 for (++i; i < nsyms; ++i)
1806 symbol_name[k] = v[i]->name;
1807 symbol_value[k] = v[i]->value;
1808 symbol_prec[k] = v[i]->prec;
1809 symbol_assoc[k] = v[i]->assoc;
1822 ritem = (short *) MALLOC(nitems*sizeof(short));
1823 if (ritem == 0) no_space();
1824 rlhs = (short *) MALLOC(nrules*sizeof(short));
1825 if (rlhs == 0) no_space();
1826 rrhs = (short *) MALLOC((nrules+1)*sizeof(short));
1827 if (rrhs == 0) no_space();
1828 rprec = (short *) REALLOC(rprec, nrules*sizeof(short));
1829 if (rprec == 0) no_space();
1830 rassoc = REALLOC(rassoc, nrules);
1831 if (rassoc == 0) no_space();
1834 ritem[1] = goal->index;
1839 rlhs[2] = start_symbol;
1845 for (i = 3; i < nrules; ++i)
1847 rlhs[i] = plhs[i]->index;
1853 ritem[j] = pitem[j]->index;
1854 if (pitem[j]->class == TERM)
1856 prec = pitem[j]->prec;
1857 assoc = pitem[j]->assoc;
1863 if (rprec[i] == UNDEFINED)
1879 register int i, j, k;
1881 register FILE *f = verbose_file;
1886 for (i = 2; i < nrules; ++i)
1888 if (rlhs[i] != rlhs[i-1])
1890 if (i != 2) fprintf(f, "\n");
1891 fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
1892 spacing = strlen(symbol_name[rlhs[i]]) + 1;
1896 fprintf(f, "%4d ", i - 2);
1898 while (--j >= 0) putc(' ', f);
1902 while (ritem[k] >= 0)
1904 fprintf(f, " %s", symbol_name[ritem[k]]);
1916 write_section(banner);
1917 create_symbol_table();
1918 read_declarations();
1920 free_symbol_table();