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.5 2005/01/05 15:26:05 joerg 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
;
78 static const char line_format
[] = "#line %d \"%s\"\n";
80 static void add_symbol(void);
81 static void advance_to_start(void);
82 static void cachec(int);
83 static void check_symbols(void);
84 static void copy_action(void);
85 static void copy_ident(void);
86 static void copy_text(void);
87 static void copy_union(void);
88 static void declare_start(void);
89 static void declare_tokens(int);
90 static void declare_types(void);
91 static char *dup_line(void);
92 static void end_rule(void);
93 static void expand_items(void);
94 static void expand_rules(void);
95 static void free_tags(void);
96 static void get_line(void);
97 static bucket
*get_literal(void);
98 static bucket
*get_name(void);
99 static int get_number(void);
100 static char *get_tag(void);
101 static int hexval(int);
102 static void initialize_grammar(void);
103 static void insert_empty_rule(void);
104 static int is_reserved(char *);
105 static int keyword(void);
106 static int mark_symbol(void);
107 static int nextc(void);
108 static void pack_grammar(void);
109 static void pack_names(void);
110 static void pack_symbols(void);
111 static void print_grammar(void);
112 static void read_declarations(void);
113 static void read_grammar(void);
114 static void skip_comment(void);
115 static void start_rule(bucket
*, int);
121 if (cinc
>= cache_size
)
124 cache
= REALLOC(cache
, cache_size
);
125 if (cache
== 0) no_space();
135 FILE *f
= input_file
;
139 if (saw_eof
|| (c
= getc(f
)) == EOF
)
141 if (line
) { FREE(line
); line
= NULL
; }
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();
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
);
294 const char *t_cptr
= cptr
;
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 FILE *f
= output_file
;
363 if (c
== EOF
) unexpected_EOF();
364 if (c
!= '"') syntax_error(lineno
, line
, cptr
);
366 fprintf(f
, "#ident \"");
392 int need_newline
= 0;
393 int t_lineno
= lineno
;
394 char *t_line
= dup_line();
395 const 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 const 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 const 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 const 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 const 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 const 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
);
662 if (c
>= '0' && c
<= '9')
664 if (c
>= 'A' && c
<= 'F')
665 return (c
- 'A' + 10);
666 if (c
>= 'a' && c
<= 'f')
667 return (c
- 'a' + 10);
680 int s_lineno
= lineno
;
681 char *s_line
= dup_line();
682 const char *s_cptr
= s_line
+ (cptr
- line
);
689 if (c
== quote
) break;
690 if (c
== '\n') unterminated_string(s_lineno
, s_line
, s_cptr
);
693 const char *c_cptr
= cptr
- 1;
700 if (line
== 0) unterminated_string(s_lineno
, s_line
, s_cptr
);
703 case '0': case '1': case '2': case '3':
704 case '4': case '5': case '6': case '7':
709 n
= (n
<< 3) + (c
- '0');
713 n
= (n
<< 3) + (c
- '0');
717 if (n
> MAXCHAR
) illegal_character(c_cptr
);
724 if (n
< 0 || n
>= 16)
725 illegal_character(c_cptr
);
730 if (i
< 0 || i
>= 16) break;
733 if (n
> MAXCHAR
) illegal_character(c_cptr
);
738 case 'a': c
= 7; break;
739 case 'b': c
= '\b'; break;
740 case 'f': c
= '\f'; break;
741 case 'n': c
= '\n'; break;
742 case 'r': c
= '\r'; break;
743 case 't': c
= '\t'; break;
744 case 'v': c
= '\v'; break;
753 if (s
== 0) no_space();
755 for (i
= 0; i
< n
; ++i
)
764 for (i
= 0; i
< n
; ++i
)
766 c
= ((unsigned char *)s
)[i
];
767 if (c
== '\\' || c
== cache
[0])
779 case 7: cachec('a'); break;
780 case '\b': cachec('b'); break;
781 case '\f': cachec('f'); break;
782 case '\n': cachec('n'); break;
783 case '\r': cachec('r'); break;
784 case '\t': cachec('t'); break;
785 case '\v': cachec('v'); break;
787 cachec(((c
>> 6) & 7) + '0');
788 cachec(((c
>> 3) & 7) + '0');
789 cachec((c
& 7) + '0');
803 if (n
== 1 && bp
->value
== UNDEFINED
)
804 bp
->value
= *(unsigned char *)s
;
812 is_reserved(char *name
)
816 if (strcmp(name
, ".") == 0 ||
817 strcmp(name
, "$accept") == 0 ||
818 strcmp(name
, "$end") == 0)
821 if (name
[0] == '$' && name
[1] == '$' && isdigit(name
[2]))
824 while (isdigit(*s
)) ++s
;
825 if (*s
== NUL
) return (1);
838 for (c
= *cptr
; IS_IDENT(c
); c
= *++cptr
)
842 if (is_reserved(cache
)) used_reserved(cache
);
844 return (lookup(cache
));
855 for (c
= *cptr
; isdigit(c
); c
= *++cptr
)
856 n
= 10*n
+ (c
- '0');
868 int t_lineno
= lineno
;
869 char *t_line
= dup_line();
870 const char *t_cptr
= t_line
+ (cptr
- line
);
874 if (c
== EOF
) unexpected_EOF();
875 if (!isalpha(c
) && c
!= '_' && c
!= '$')
876 illegal_tag(t_lineno
, t_line
, t_cptr
);
879 do { cachec(c
); c
= *++cptr
; } while (IS_IDENT(c
));
883 if (c
== EOF
) unexpected_EOF();
885 illegal_tag(t_lineno
, t_line
, t_cptr
);
888 for (i
= 0; i
< ntags
; ++i
)
890 if (strcmp(cache
, tag_table
[i
]) == 0)
891 return (tag_table
[i
]);
897 tag_table
= (char **)
898 (tag_table
? REALLOC(tag_table
, tagmax
*sizeof(char *))
899 : MALLOC(tagmax
*sizeof(char *)));
900 if (tag_table
== 0) no_space();
904 if (s
== 0) no_space();
906 tag_table
[ntags
] = s
;
914 declare_tokens(int assoc
)
921 if (assoc
!= TOKEN
) ++prec
;
924 if (c
== EOF
) unexpected_EOF();
929 if (c
== EOF
) unexpected_EOF();
934 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
936 else if (c
== '\'' || c
== '"')
941 if (bp
== goal
) tokenized_start(bp
->name
);
946 if (bp
->tag
&& tag
!= bp
->tag
)
947 retyped_warning(bp
->name
);
953 if (bp
->prec
&& prec
!= bp
->prec
)
954 reprec_warning(bp
->name
);
960 if (c
== EOF
) unexpected_EOF();
964 value
= get_number();
965 if (bp
->value
!= UNDEFINED
&& value
!= bp
->value
)
966 revalued_warning(bp
->name
);
969 if (c
== EOF
) unexpected_EOF();
976 * %expect requires special handling
977 * as it really isn't part of the yacc
978 * grammar only a flag for yacc proper.
981 declare_expect(int assoc
)
985 if (assoc
!= EXPECT
) ++prec
;
988 * Stay away from nextc - doesn't
989 * detect EOL and will read to EOF.
992 if (c
== EOF
) unexpected_EOF();
998 SRexpect
= get_number();
1002 * Looking for number before EOL.
1003 * Spaces, tabs, and numbers are ok,
1004 * words, punc., etc. are syntax errors.
1006 else if (c
== '\n' || isalpha(c
) || !isspace(c
))
1008 syntax_error(lineno
, line
, cptr
);
1013 if (c
== EOF
) unexpected_EOF();
1027 if (c
== EOF
) unexpected_EOF();
1028 if (c
!= '<') syntax_error(lineno
, line
, cptr
);
1034 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1036 else if (c
== '\'' || c
== '"')
1041 if (bp
->tag
&& tag
!= bp
->tag
)
1042 retyped_warning(bp
->name
);
1055 if (c
== EOF
) unexpected_EOF();
1056 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '$')
1057 syntax_error(lineno
, line
, cptr
);
1059 if (bp
->class == TERM
)
1060 terminal_start(bp
->name
);
1061 if (goal
&& goal
!= bp
)
1062 restarted_warning();
1068 read_declarations(void)
1073 cache
= MALLOC(cache_size
);
1074 if (cache
== 0) no_space();
1079 if (c
== EOF
) unexpected_EOF();
1080 if (c
!= '%') syntax_error(lineno
, line
, cptr
);
1081 switch (k
= keyword())
1122 initialize_grammar(void)
1126 pitem
= (bucket
**) MALLOC(maxitems
*sizeof(bucket
*));
1127 if (pitem
== 0) no_space();
1135 plhs
= (bucket
**) MALLOC(maxrules
*sizeof(bucket
*));
1136 if (plhs
== 0) no_space();
1140 rprec
= (short *) MALLOC(maxrules
*sizeof(short));
1141 if (rprec
== 0) no_space();
1145 rassoc
= (char *) MALLOC(maxrules
*sizeof(char));
1146 if (rassoc
== 0) no_space();
1157 pitem
= (bucket
**) REALLOC(pitem
, maxitems
*sizeof(bucket
*));
1158 if (pitem
== 0) no_space();
1166 plhs
= (bucket
**) REALLOC(plhs
, maxrules
*sizeof(bucket
*));
1167 if (plhs
== 0) no_space();
1168 rprec
= (short *) REALLOC(rprec
, maxrules
*sizeof(short));
1169 if (rprec
== 0) no_space();
1170 rassoc
= (char *) REALLOC(rassoc
, maxrules
*sizeof(char));
1171 if (rassoc
== 0) no_space();
1176 advance_to_start(void)
1186 if (c
!= '%') break;
1202 syntax_error(lineno
, line
, s_cptr
);
1207 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '_')
1208 syntax_error(lineno
, line
, cptr
);
1212 if (bp
->class == TERM
)
1213 terminal_start(bp
->name
);
1219 if (c
== EOF
) unexpected_EOF();
1220 if (c
!= ':') syntax_error(lineno
, line
, cptr
);
1221 start_rule(bp
, s_lineno
);
1227 start_rule(bucket
*bp
, int s_lineno
)
1229 if (bp
->class == TERM
)
1230 terminal_lhs(s_lineno
);
1231 bp
->class = NONTERM
;
1232 if (nrules
>= maxrules
)
1235 rprec
[nrules
] = UNDEFINED
;
1236 rassoc
[nrules
] = TOKEN
;
1245 if (!last_was_action
&& plhs
[nrules
]->tag
)
1247 for (i
= nitems
- 1; pitem
[i
]; --i
) continue;
1248 if (pitem
[i
+1] == 0 || pitem
[i
+1]->tag
!= plhs
[nrules
]->tag
)
1249 default_action_warning();
1252 last_was_action
= 0;
1253 if (nitems
>= maxitems
) expand_items();
1261 insert_empty_rule(void)
1266 sprintf(cache
, "$$%d", ++gensym
);
1267 bp
= make_bucket(cache
);
1268 last_symbol
->next
= bp
;
1270 bp
->tag
= plhs
[nrules
]->tag
;
1271 bp
->class = NONTERM
;
1273 if ((nitems
+= 2) > maxitems
)
1275 bpp
= pitem
+ nitems
- 1;
1277 while ((bpp
[0] = bpp
[-1])) --bpp
;
1279 if (++nrules
>= maxrules
)
1281 plhs
[nrules
] = plhs
[nrules
-1];
1282 plhs
[nrules
-1] = bp
;
1283 rprec
[nrules
] = rprec
[nrules
-1];
1284 rprec
[nrules
-1] = 0;
1285 rassoc
[nrules
] = rassoc
[nrules
-1];
1286 rassoc
[nrules
-1] = TOKEN
;
1295 int s_lineno
= lineno
;
1298 if (c
== '\'' || c
== '"')
1307 start_rule(bp
, s_lineno
);
1312 if (last_was_action
)
1313 insert_empty_rule();
1314 last_was_action
= 0;
1316 if (++nitems
> maxitems
)
1318 pitem
[nitems
-1] = bp
;
1330 FILE *f
= action_file
;
1331 int a_lineno
= lineno
;
1332 char *a_line
= dup_line();
1333 char *a_cptr
= a_line
+ (cptr
- line
);
1335 if (last_was_action
)
1336 insert_empty_rule();
1337 last_was_action
= 1;
1339 fprintf(f
, "case %d:\n", nrules
- 2);
1341 fprintf(f
, line_format
, lineno
, input_file_name
);
1342 if (*cptr
== '=') ++cptr
;
1345 for (i
= nitems
- 1; pitem
[i
]; --i
) ++n
;
1354 int d_lineno
= lineno
;
1355 char *d_line
= dup_line();
1356 char *d_cptr
= d_line
+ (cptr
- line
);
1363 fprintf(f
, "yyval.%s", tag
);
1368 else if (isdigit(c
))
1371 if (i
> n
) dollar_warning(d_lineno
, i
);
1372 fprintf(f
, "yyvsp[%d].%s", i
- n
, tag
);
1376 else if (c
== '-' && isdigit(cptr
[1]))
1379 i
= -get_number() - n
;
1380 fprintf(f
, "yyvsp[%d].%s", i
, tag
);
1385 dollar_error(d_lineno
, d_line
, d_cptr
);
1387 else if (cptr
[1] == '$')
1391 tag
= plhs
[nrules
]->tag
;
1392 if (tag
== 0) untyped_lhs();
1393 fprintf(f
, "yyval.%s", tag
);
1396 fprintf(f
, "yyval");
1400 else if (isdigit(cptr
[1]))
1406 if (i
<= 0 || i
> n
)
1408 tag
= pitem
[nitems
+ i
- n
- 1]->tag
;
1409 if (tag
== 0) untyped_rhs(i
, pitem
[nitems
+ i
- n
- 1]->name
);
1410 fprintf(f
, "yyvsp[%d].%s", i
- n
, tag
);
1415 dollar_warning(lineno
, i
);
1416 fprintf(f
, "yyvsp[%d]", i
- n
);
1420 else if (cptr
[1] == '-')
1426 fprintf(f
, "yyvsp[%d]", -i
- n
);
1430 if (isalpha(c
) || c
== '_' || c
== '$')
1436 } while (isalnum(c
) || c
== '_' || c
== '$');
1446 if (line
) goto loop
;
1447 unterminated_action(a_lineno
, a_line
, a_cptr
);
1450 if (depth
> 0) goto loop
;
1451 fprintf(f
, "\nbreak;\n");
1459 if (--depth
> 0) goto loop
;
1460 fprintf(f
, "\nbreak;\n");
1466 int s_lineno
= lineno
;
1467 char *s_line
= dup_line();
1468 char *s_cptr
= s_line
+ (cptr
- line
- 1);
1481 unterminated_string(s_lineno
, s_line
, s_cptr
);
1490 unterminated_string(s_lineno
, s_line
, s_cptr
);
1501 while ((c
= *++cptr
) != '\n')
1503 if (c
== '*' && cptr
[1] == '/')
1513 int c_lineno
= lineno
;
1514 char *c_line
= dup_line();
1515 char *c_cptr
= c_line
+ (cptr
- line
- 1);
1523 if (c
== '*' && *cptr
== '/')
1534 unterminated_comment(c_lineno
, c_line
, c_cptr
);
1553 if (c
== '%' || c
== '\\')
1561 else if ((c
== 'p' || c
== 'P') &&
1562 ((c
= cptr
[2]) == 'r' || c
== 'R') &&
1563 ((c
= cptr
[3]) == 'e' || c
== 'E') &&
1564 ((c
= cptr
[4]) == 'c' || c
== 'C') &&
1565 ((c
= cptr
[5], !IS_IDENT(c
))))
1568 syntax_error(lineno
, line
, cptr
);
1571 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1573 else if (c
== '\'' || c
== '"')
1577 syntax_error(lineno
, line
, cptr
);
1581 if (rprec
[nrules
] != UNDEFINED
&& bp
->prec
!= rprec
[nrules
])
1584 rprec
[nrules
] = bp
->prec
;
1585 rassoc
[nrules
] = bp
->assoc
;
1595 initialize_grammar();
1601 if (c
== EOF
) break;
1602 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$' || c
== '\'' ||
1605 else if (c
== '{' || c
== '=')
1610 start_rule(plhs
[nrules
-1], 0);
1615 if (mark_symbol()) break;
1618 syntax_error(lineno
, line
, cptr
);
1629 if (tag_table
== 0) return;
1631 for (i
= 0; i
< ntags
; ++i
)
1633 assert(tag_table
[i
]);
1646 name_pool_size
= 13; /* 13 == sizeof("$end") + sizeof("$accept") */
1647 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1648 name_pool_size
+= strlen(bp
->name
) + 1;
1649 name_pool
= MALLOC(name_pool_size
);
1650 if (name_pool
== 0) no_space();
1652 strcpy(name_pool
, "$accept");
1653 strcpy(name_pool
+8, "$end");
1655 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1659 while ((*t
++ = *s
++)) continue;
1671 if (goal
->class == UNKNOWN
)
1672 undefined_goal(goal
->name
);
1674 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1676 if (bp
->class == UNKNOWN
)
1678 undefined_symbol_warning(bp
->name
);
1694 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1697 if (bp
->class == TERM
) ++ntokens
;
1699 start_symbol
= ntokens
;
1700 nvars
= nsyms
- ntokens
;
1702 symbol_name
= (char **) MALLOC(nsyms
*sizeof(char *));
1703 if (symbol_name
== 0) no_space();
1704 symbol_value
= (short *) MALLOC(nsyms
*sizeof(short));
1705 if (symbol_value
== 0) no_space();
1706 symbol_prec
= (short *) MALLOC(nsyms
*sizeof(short));
1707 if (symbol_prec
== 0) no_space();
1708 symbol_assoc
= MALLOC(nsyms
);
1709 if (symbol_assoc
== 0) no_space();
1711 v
= (bucket
**) MALLOC(nsyms
*sizeof(bucket
*));
1712 if (v
== 0) no_space();
1715 v
[start_symbol
] = 0;
1718 j
= start_symbol
+ 1;
1719 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1721 if (bp
->class == TERM
)
1726 assert(i
== ntokens
&& j
== nsyms
);
1728 for (i
= 1; i
< ntokens
; ++i
)
1731 goal
->index
= start_symbol
+ 1;
1732 k
= start_symbol
+ 2;
1742 for (i
= start_symbol
+ 1; i
< nsyms
; ++i
)
1752 for (i
= 1; i
< ntokens
; ++i
)
1757 for (j
= k
++; j
> 0 && symbol_value
[j
-1] > n
; --j
)
1758 symbol_value
[j
] = symbol_value
[j
-1];
1759 symbol_value
[j
] = n
;
1763 if (v
[1]->value
== UNDEFINED
)
1768 for (i
= 2; i
< ntokens
; ++i
)
1770 if (v
[i
]->value
== UNDEFINED
)
1772 while (j
< k
&& n
== symbol_value
[j
])
1774 while (++j
< k
&& n
== symbol_value
[j
]) continue;
1782 symbol_name
[0] = name_pool
+ 8;
1783 symbol_value
[0] = 0;
1785 symbol_assoc
[0] = TOKEN
;
1786 for (i
= 1; i
< ntokens
; ++i
)
1788 symbol_name
[i
] = v
[i
]->name
;
1789 symbol_value
[i
] = v
[i
]->value
;
1790 symbol_prec
[i
] = v
[i
]->prec
;
1791 symbol_assoc
[i
] = v
[i
]->assoc
;
1793 symbol_name
[start_symbol
] = name_pool
;
1794 symbol_value
[start_symbol
] = -1;
1795 symbol_prec
[start_symbol
] = 0;
1796 symbol_assoc
[start_symbol
] = TOKEN
;
1797 for (++i
; i
< nsyms
; ++i
)
1800 symbol_name
[k
] = v
[i
]->name
;
1801 symbol_value
[k
] = v
[i
]->value
;
1802 symbol_prec
[k
] = v
[i
]->prec
;
1803 symbol_assoc
[k
] = v
[i
]->assoc
;
1814 int assoc
, loc_prec
;
1816 ritem
= (short *) MALLOC(nitems
*sizeof(short));
1817 if (ritem
== 0) no_space();
1818 rlhs
= (short *) MALLOC(nrules
*sizeof(short));
1819 if (rlhs
== 0) no_space();
1820 rrhs
= (short *) MALLOC((nrules
+1)*sizeof(short));
1821 if (rrhs
== 0) no_space();
1822 rprec
= (short *) REALLOC(rprec
, nrules
*sizeof(short));
1823 if (rprec
== 0) no_space();
1824 rassoc
= REALLOC(rassoc
, nrules
);
1825 if (rassoc
== 0) no_space();
1828 ritem
[1] = goal
->index
;
1833 rlhs
[2] = start_symbol
;
1839 for (i
= 3; i
< nrules
; ++i
)
1841 rlhs
[i
] = plhs
[i
]->index
;
1847 ritem
[j
] = pitem
[j
]->index
;
1848 if (pitem
[j
]->class == TERM
)
1850 loc_prec
= pitem
[j
]->prec
;
1851 assoc
= pitem
[j
]->assoc
;
1857 if (rprec
[i
] == UNDEFINED
)
1859 rprec
[i
] = loc_prec
;
1875 FILE *f
= verbose_file
;
1880 for (i
= 2; i
< nrules
; ++i
)
1882 if (rlhs
[i
] != rlhs
[i
-1])
1884 if (i
!= 2) fprintf(f
, "\n");
1885 fprintf(f
, "%4d %s :", i
- 2, symbol_name
[rlhs
[i
]]);
1886 spacing
= strlen(symbol_name
[rlhs
[i
]]) + 1;
1890 fprintf(f
, "%4d ", i
- 2);
1892 while (--j
>= 0) putc(' ', f
);
1896 while (ritem
[k
] >= 0)
1898 fprintf(f
, " %s", symbol_name
[ritem
[k
]]);
1910 write_section(banner
);
1911 create_symbol_table();
1912 read_declarations();
1914 free_symbol_table();