3 /* The line size must be a positive integer. One hundred was chosen */
4 /* because few lines in Yacc input grammars exceed 100 characters. */
5 /* Note that if a line exceeds LINESIZE characters, the line buffer */
6 /* will be expanded to accomodate it. */
16 char saw_eof, unionized;
34 char line_format[] = "#line %d \"%s\"\n";
41 if (cinc >= cache_size)
44 cache = REALLOC(cache, cache_size);
45 if (cache == 0) no_space();
54 register FILE *f = input_file;
58 if (saw_eof || (c = getc(f)) == EOF)
60 if (line) { FREE(line); line = 0; }
66 if (line == 0 || linesize != (LINESIZE + 1))
69 linesize = LINESIZE + 1;
70 line = MALLOC(linesize);
71 if (line == 0) no_space();
79 if (c == '\n') { cptr = line; return; }
83 line = REALLOC(line, linesize);
84 if (line == 0) no_space();
101 register char *p, *s, *t;
103 if (line == 0) return (0);
105 while (*s != '\n') ++s;
106 p = MALLOC(s - line + 1);
107 if (p == 0) no_space();
111 while ((*t++ = *s++) != '\n') continue;
120 int st_lineno = lineno;
121 char *st_line = dup_line();
122 char *st_cptr = st_line + (cptr - line);
127 if (*s == '*' && s[1] == '/')
137 unterminated_comment(st_lineno, st_line, st_cptr);
165 if (line == 0) return (EOF);
173 case '\013': /* ACK_MOD, '\v' is not K&R C */
191 else if (s[1] == '/')
194 if (line == 0) return (EOF);
222 if (isupper(c)) c = tolower(c);
225 else if (isdigit(c) || c == '_' || c == '.' || c == '$')
233 if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0)
235 if (strcmp(cache, "type") == 0)
237 if (strcmp(cache, "left") == 0)
239 if (strcmp(cache, "right") == 0)
241 if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0)
243 if (strcmp(cache, "start") == 0)
245 if (strcmp(cache, "union") == 0)
247 if (strcmp(cache, "ident") == 0)
255 if (c == '%' || c == '\\')
266 syntax_error(lineno, line, t_cptr);
274 register FILE *f = output_file;
277 if (c == EOF) unexpected_EOF();
278 if (c != '"') syntax_error(lineno, line, cptr);
280 fprintf(f, "#ident \"");
304 register FILE *f = text_file;
305 int need_newline = 0;
306 int t_lineno = lineno;
307 char *t_line = dup_line();
308 char *t_cptr = t_line + (cptr - line - 2);
314 unterminated_text(t_lineno, t_line, t_cptr);
316 if (!lflag) fprintf(f, line_format, lineno, input_file_name);
328 unterminated_text(t_lineno, t_line, t_cptr);
333 int s_lineno = lineno;
334 char *s_line = dup_line();
335 char *s_cptr = s_line + (cptr - line - 1);
350 unterminated_string(s_lineno, s_line, s_cptr);
359 unterminated_string(s_lineno, s_line, s_cptr);
372 while ((c = *++cptr) != '\n')
374 if (c == '*' && cptr[1] == '/')
384 int c_lineno = lineno;
385 char *c_line = dup_line();
386 char *c_cptr = c_line + (cptr - line - 1);
394 if (c == '*' && *cptr == '/')
405 unterminated_comment(c_lineno, c_line, c_cptr);
416 if (need_newline) putc('\n', f);
436 int u_lineno = lineno;
437 char *u_line = dup_line();
438 char *u_cptr = u_line + (cptr - line - 6);
440 if (unionized) over_unionized(cptr - 6);
444 fprintf(text_file, line_format, lineno, input_file_name);
446 fprintf(text_file, "typedef union");
447 if (dflag) fprintf(union_file, "typedef union");
453 if (dflag) putc(c, union_file);
459 if (line == 0) unterminated_union(u_lineno, u_line, u_cptr);
469 fprintf(text_file, " YYSTYPE;\n");
478 int s_lineno = lineno;
479 char *s_line = dup_line();
480 char *s_cptr = s_line + (cptr - line - 1);
487 if (dflag) putc(c, union_file);
494 unterminated_string(s_lineno, s_line, s_cptr);
499 if (dflag) putc(c, union_file);
504 unterminated_string(s_lineno, s_line, s_cptr);
514 putc('*', text_file);
515 if (dflag) putc('*', union_file);
516 while ((c = *++cptr) != '\n')
518 if (c == '*' && cptr[1] == '/')
520 fprintf(text_file, "* ");
521 if (dflag) fprintf(union_file, "* ");
526 if (dflag) putc(c, union_file);
529 fprintf(text_file, "*/\n");
530 if (dflag) fprintf(union_file, "*/\n");
535 int c_lineno = lineno;
536 char *c_line = dup_line();
537 char *c_cptr = c_line + (cptr - line - 1);
539 putc('*', text_file);
540 if (dflag) putc('*', union_file);
546 if (dflag) putc(c, union_file);
547 if (c == '*' && *cptr == '/')
549 putc('/', text_file);
550 if (dflag) putc('/', union_file);
559 unterminated_comment(c_lineno, c_line, c_cptr);
575 if (c >= '0' && c <= '9')
577 if (c >= 'A' && c <= 'F')
578 return (c - 'A' + 10);
579 if (c >= 'a' && c <= 'f')
580 return (c - 'a' + 10);
588 register int c, quote;
593 int s_lineno = lineno;
594 char *s_line = dup_line();
595 char *s_cptr = s_line + (cptr - line);
602 if (c == quote) break;
603 if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr);
606 char *c_cptr = cptr - 1;
613 if (line == 0) unterminated_string(s_lineno, s_line, s_cptr);
616 case '0': case '1': case '2': case '3':
617 case '4': case '5': case '6': case '7':
622 n = (n << 3) + (c - '0');
626 n = (n << 3) + (c - '0');
630 if (n > MAXCHAR) illegal_character(c_cptr);
637 if (n < 0 || n >= 16)
638 illegal_character(c_cptr);
643 if (i < 0 || i >= 16) break;
646 if (n > MAXCHAR) illegal_character(c_cptr);
651 case 'a': c = 7; break;
652 case 'b': c = '\b'; break;
653 case 'f': c = '\f'; break;
654 case 'n': c = '\n'; break;
655 case 'r': c = '\r'; break;
656 case 't': c = '\t'; break;
657 case 'v': c = '\013'; break; /* ACK_MOD, '\v' is not K&R C */
666 if (s == 0) no_space();
668 for (i = 0; i < n; ++i)
677 for (i = 0; i < n; ++i)
679 c = ((unsigned char *)s)[i];
680 if (c == '\\' || c == cache[0])
692 case 7: cachec('a'); break;
693 case '\b': cachec('b'); break;
694 case '\f': cachec('f'); break;
695 case '\n': cachec('n'); break;
696 case '\r': cachec('r'); break;
697 case '\t': cachec('t'); break;
698 case '\013': cachec('v'); break; /* ACK_MOD, '\v' is not K&R C */
700 cachec(((c >> 6) & 7) + '0');
701 cachec(((c >> 3) & 7) + '0');
702 cachec((c & 7) + '0');
716 if (n == 1 && bp->value == UNDEFINED)
717 bp->value = *(unsigned char *)s;
730 if (strcmp(name, ".") == 0 ||
731 strcmp(name, "$accept") == 0 ||
732 strcmp(name, "$end") == 0)
735 if (name[0] == '$' && name[1] == '$' && isdigit(name[2]))
738 while (isdigit(*s)) ++s;
739 if (*s == NUL) return (1);
752 for (c = *cptr; IS_IDENT(c); c = *++cptr)
756 if (is_reserved(cache)) used_reserved(cache);
758 return (lookup(cache));
769 for (c = *cptr; isdigit(c); c = *++cptr)
770 n = 10*n + (c - '0');
782 int t_lineno = lineno;
783 char *t_line = dup_line();
784 char *t_cptr = t_line + (cptr - line);
788 if (c == EOF) unexpected_EOF();
789 if (!isalpha(c) && c != '_' && c != '$')
790 illegal_tag(t_lineno, t_line, t_cptr);
793 do { cachec(c); c = *++cptr; } while (IS_IDENT(c));
797 if (c == EOF) unexpected_EOF();
799 illegal_tag(t_lineno, t_line, t_cptr);
802 for (i = 0; i < ntags; ++i)
804 if (strcmp(cache, tag_table[i]) == 0)
805 return (tag_table[i]);
811 tag_table = (char **)
812 (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *))
813 : MALLOC(tagmax*sizeof(char *)));
814 if (tag_table == 0) no_space();
818 if (s == 0) no_space();
820 tag_table[ntags] = s;
827 declare_tokens(assoc)
835 if (assoc != TOKEN) ++prec;
838 if (c == EOF) unexpected_EOF();
843 if (c == EOF) unexpected_EOF();
848 if (isalpha(c) || c == '_' || c == '.' || c == '$')
850 else if (c == '\'' || c == '"')
855 if (bp == goal) tokenized_start(bp->name);
860 if (bp->tag && tag != bp->tag)
861 retyped_warning(bp->name);
867 if (bp->prec && prec != bp->prec)
868 reprec_warning(bp->name);
874 if (c == EOF) unexpected_EOF();
878 value = get_number();
879 if (bp->value != UNDEFINED && value != bp->value)
880 revalued_warning(bp->name);
883 if (c == EOF) unexpected_EOF();
896 if (c == EOF) unexpected_EOF();
897 if (c != '<') syntax_error(lineno, line, cptr);
903 if (isalpha(c) || c == '_' || c == '.' || c == '$')
905 else if (c == '\'' || c == '"')
910 if (bp->tag && tag != bp->tag)
911 retyped_warning(bp->name);
923 if (c == EOF) unexpected_EOF();
924 if (!isalpha(c) && c != '_' && c != '.' && c != '$')
925 syntax_error(lineno, line, cptr);
927 if (bp->class == TERM)
928 terminal_start(bp->name);
929 if (goal && goal != bp)
940 cache = MALLOC(cache_size);
941 if (cache == 0) no_space();
946 if (c == EOF) unexpected_EOF();
947 if (c != '%') syntax_error(lineno, line, cptr);
948 switch (k = keyword())
988 pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *));
989 if (pitem == 0) no_space();
997 plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *));
998 if (plhs == 0) no_space();
1002 rprec = (short *) MALLOC(maxrules*sizeof(short));
1003 if (rprec == 0) no_space();
1007 rassoc = (char *) MALLOC(maxrules*sizeof(char));
1008 if (rassoc == 0) no_space();
1018 pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *));
1019 if (pitem == 0) no_space();
1026 plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *));
1027 if (plhs == 0) no_space();
1028 rprec = (short *) REALLOC(rprec, maxrules*sizeof(short));
1029 if (rprec == 0) no_space();
1030 rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char));
1031 if (rassoc == 0) no_space();
1038 register bucket *bp;
1045 if (c != '%') break;
1061 syntax_error(lineno, line, s_cptr);
1066 if (!isalpha(c) && c != '_' && c != '.' && c != '_')
1067 syntax_error(lineno, line, cptr);
1071 if (bp->class == TERM)
1072 terminal_start(bp->name);
1078 if (c == EOF) unexpected_EOF();
1079 if (c != ':') syntax_error(lineno, line, cptr);
1080 start_rule(bp, s_lineno);
1085 start_rule(bp, s_lineno)
1086 register bucket *bp;
1089 if (bp->class == TERM)
1090 terminal_lhs(s_lineno);
1091 bp->class = NONTERM;
1092 if (nrules >= maxrules)
1095 rprec[nrules] = UNDEFINED;
1096 rassoc[nrules] = TOKEN;
1104 if (!last_was_action && plhs[nrules]->tag)
1106 for (i = nitems - 1; pitem[i]; --i) continue;
1107 if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag)
1108 default_action_warning();
1111 last_was_action = 0;
1112 if (nitems >= maxitems) expand_items();
1121 register bucket *bp, **bpp;
1124 sprintf(cache, "$$%d", ++gensym);
1125 bp = make_bucket(cache);
1126 last_symbol->next = bp;
1128 bp->tag = plhs[nrules]->tag;
1129 bp->class = NONTERM;
1131 if ((nitems += 2) > maxitems)
1133 bpp = pitem + nitems - 1;
1135 while (bpp[0] = bpp[-1]) --bpp;
1137 if (++nrules >= maxrules)
1139 plhs[nrules] = plhs[nrules-1];
1140 plhs[nrules-1] = bp;
1141 rprec[nrules] = rprec[nrules-1];
1142 rprec[nrules-1] = 0;
1143 rassoc[nrules] = rassoc[nrules-1];
1144 rassoc[nrules-1] = TOKEN;
1151 register bucket *bp;
1152 int s_lineno = lineno;
1155 if (c == '\'' || c == '"')
1164 start_rule(bp, s_lineno);
1169 if (last_was_action)
1170 insert_empty_rule();
1171 last_was_action = 0;
1173 if (++nitems > maxitems)
1175 pitem[nitems-1] = bp;
1186 register FILE *f = action_file;
1187 int a_lineno = lineno;
1188 char *a_line = dup_line();
1189 char *a_cptr = a_line + (cptr - line);
1191 if (last_was_action)
1192 insert_empty_rule();
1193 last_was_action = 1;
1195 fprintf(f, "case %d:\n", nrules - 2);
1197 fprintf(f, line_format, lineno, input_file_name);
1198 if (*cptr == '=') ++cptr;
1201 for (i = nitems - 1; pitem[i]; --i) ++n;
1210 int d_lineno = lineno;
1211 char *d_line = dup_line();
1212 char *d_cptr = d_line + (cptr - line);
1219 fprintf(f, "yyval.%s", tag);
1224 else if (isdigit(c))
1227 if (i > n) dollar_warning(d_lineno, i);
1228 fprintf(f, "yyvsp[%d].%s", i - n, tag);
1232 else if (c == '-' && isdigit(cptr[1]))
1235 i = -get_number() - n;
1236 fprintf(f, "yyvsp[%d].%s", i, tag);
1241 dollar_error(d_lineno, d_line, d_cptr);
1243 else if (cptr[1] == '$')
1247 tag = plhs[nrules]->tag;
1248 if (tag == 0) untyped_lhs();
1249 fprintf(f, "yyval.%s", tag);
1252 fprintf(f, "yyval");
1256 else if (isdigit(cptr[1]))
1262 if (i <= 0 || i > n)
1264 tag = pitem[nitems + i - n - 1]->tag;
1265 if (tag == 0) untyped_rhs(i, pitem[nitems + i - n - 1]->name);
1266 fprintf(f, "yyvsp[%d].%s", i - n, tag);
1271 dollar_warning(lineno, i);
1272 fprintf(f, "yyvsp[%d]", i - n);
1276 else if (cptr[1] == '-')
1282 fprintf(f, "yyvsp[%d]", -i - n);
1286 if (isalpha(c) || c == '_' || c == '$')
1292 } while (isalnum(c) || c == '_' || c == '$');
1302 if (line) goto loop;
1303 unterminated_action(a_lineno, a_line, a_cptr);
1306 if (depth > 0) goto loop;
1307 fprintf(f, "\nbreak;\n");
1315 if (--depth > 0) goto loop;
1316 fprintf(f, "\nbreak;\n");
1322 int s_lineno = lineno;
1323 char *s_line = dup_line();
1324 char *s_cptr = s_line + (cptr - line - 1);
1337 unterminated_string(s_lineno, s_line, s_cptr);
1346 unterminated_string(s_lineno, s_line, s_cptr);
1357 while ((c = *++cptr) != '\n')
1359 if (c == '*' && cptr[1] == '/')
1369 int c_lineno = lineno;
1370 char *c_line = dup_line();
1371 char *c_cptr = c_line + (cptr - line - 1);
1379 if (c == '*' && *cptr == '/')
1390 unterminated_comment(c_lineno, c_line, c_cptr);
1406 register bucket *bp;
1409 if (c == '%' || c == '\\')
1417 else if ((c == 'p' || c == 'P') &&
1418 ((c = cptr[2]) == 'r' || c == 'R') &&
1419 ((c = cptr[3]) == 'e' || c == 'E') &&
1420 ((c = cptr[4]) == 'c' || c == 'C') &&
1421 ((c = cptr[5], !IS_IDENT(c))))
1424 syntax_error(lineno, line, cptr);
1427 if (isalpha(c) || c == '_' || c == '.' || c == '$')
1429 else if (c == '\'' || c == '"')
1433 syntax_error(lineno, line, cptr);
1437 if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
1440 rprec[nrules] = bp->prec;
1441 rassoc[nrules] = bp->assoc;
1450 initialize_grammar();
1456 if (c == EOF) break;
1457 if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' ||
1460 else if (c == '{' || c == '=')
1465 start_rule(plhs[nrules-1], 0);
1470 if (mark_symbol()) break;
1473 syntax_error(lineno, line, cptr);
1483 if (tag_table == 0) return;
1485 for (i = 0; i < ntags; ++i)
1487 assert(tag_table[i]);
1496 register bucket *bp;
1497 register char *p, *s, *t;
1499 name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
1500 for (bp = first_symbol; bp; bp = bp->next)
1501 name_pool_size += strlen(bp->name) + 1;
1502 name_pool = MALLOC(name_pool_size);
1503 if (name_pool == 0) no_space();
1505 strcpy(name_pool, "$accept");
1506 strcpy(name_pool+8, "$end");
1508 for (bp = first_symbol; bp; bp = bp->next)
1512 while (*t++ = *s++) continue;
1521 register bucket *bp;
1523 if (goal->class == UNKNOWN)
1524 undefined_goal(goal->name);
1526 for (bp = first_symbol; bp; bp = bp->next)
1528 if (bp->class == UNKNOWN)
1530 undefined_symbol_warning(bp->name);
1539 register bucket *bp;
1540 register bucket **v;
1541 register int i, j, k, n;
1545 for (bp = first_symbol; bp; bp = bp->next)
1548 if (bp->class == TERM) ++ntokens;
1550 start_symbol = ntokens;
1551 nvars = nsyms - ntokens;
1553 symbol_name = (char **) MALLOC(nsyms*sizeof(char *));
1554 if (symbol_name == 0) no_space();
1555 symbol_value = (short *) MALLOC(nsyms*sizeof(short));
1556 if (symbol_value == 0) no_space();
1557 symbol_prec = (short *) MALLOC(nsyms*sizeof(short));
1558 if (symbol_prec == 0) no_space();
1559 symbol_assoc = MALLOC(nsyms);
1560 if (symbol_assoc == 0) no_space();
1562 v = (bucket **) MALLOC(nsyms*sizeof(bucket *));
1563 if (v == 0) no_space();
1566 v[start_symbol] = 0;
1569 j = start_symbol + 1;
1570 for (bp = first_symbol; bp; bp = bp->next)
1572 if (bp->class == TERM)
1577 assert(i == ntokens && j == nsyms);
1579 for (i = 1; i < ntokens; ++i)
1582 goal->index = start_symbol + 1;
1583 k = start_symbol + 2;
1593 for (i = start_symbol + 1; i < nsyms; ++i)
1603 for (i = 1; i < ntokens; ++i)
1608 for (j = k++; j > 0 && symbol_value[j-1] > n; --j)
1609 symbol_value[j] = symbol_value[j-1];
1610 symbol_value[j] = n;
1614 if (v[1]->value == UNDEFINED)
1619 for (i = 2; i < ntokens; ++i)
1621 if (v[i]->value == UNDEFINED)
1623 while (j < k && n == symbol_value[j])
1625 while (++j < k && n == symbol_value[j]) continue;
1633 symbol_name[0] = name_pool + 8;
1634 symbol_value[0] = 0;
1636 symbol_assoc[0] = TOKEN;
1637 for (i = 1; i < ntokens; ++i)
1639 symbol_name[i] = v[i]->name;
1640 symbol_value[i] = v[i]->value;
1641 symbol_prec[i] = v[i]->prec;
1642 symbol_assoc[i] = v[i]->assoc;
1644 symbol_name[start_symbol] = name_pool;
1645 symbol_value[start_symbol] = -1;
1646 symbol_prec[start_symbol] = 0;
1647 symbol_assoc[start_symbol] = TOKEN;
1648 for (++i; i < nsyms; ++i)
1651 symbol_name[k] = v[i]->name;
1652 symbol_value[k] = v[i]->value;
1653 symbol_prec[k] = v[i]->prec;
1654 symbol_assoc[k] = v[i]->assoc;
1666 ritem = (short *) MALLOC(nitems*sizeof(short));
1667 if (ritem == 0) no_space();
1668 rlhs = (short *) MALLOC(nrules*sizeof(short));
1669 if (rlhs == 0) no_space();
1670 rrhs = (short *) MALLOC((nrules+1)*sizeof(short));
1671 if (rrhs == 0) no_space();
1672 rprec = (short *) REALLOC(rprec, nrules*sizeof(short));
1673 if (rprec == 0) no_space();
1674 rassoc = REALLOC(rassoc, nrules);
1675 if (rassoc == 0) no_space();
1678 ritem[1] = goal->index;
1683 rlhs[2] = start_symbol;
1689 for (i = 3; i < nrules; ++i)
1691 rlhs[i] = plhs[i]->index;
1697 ritem[j] = pitem[j]->index;
1698 if (pitem[j]->class == TERM)
1700 prec = pitem[j]->prec;
1701 assoc = pitem[j]->assoc;
1707 if (rprec[i] == UNDEFINED)
1722 register int i, j, k;
1724 register FILE *f = verbose_file;
1729 for (i = 2; i < nrules; ++i)
1731 if (rlhs[i] != rlhs[i-1])
1733 if (i != 2) fprintf(f, "\n");
1734 fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
1735 spacing = strlen(symbol_name[rlhs[i]]) + 1;
1739 fprintf(f, "%4d ", i - 2);
1741 while (--j >= 0) putc(' ', f);
1745 while (ritem[k] >= 0)
1747 fprintf(f, " %s", symbol_name[ritem[k]]);
1758 write_section(banner);
1759 create_symbol_table();
1760 read_declarations();
1762 free_symbol_table();