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
38 static char sccsid
[] = "@(#)reader.c 5.7 (Berkeley) 1/20/91";
43 /* this resolves "unresolved symbol _snprintf" on Windows */
44 #if defined (_MSC_VER)
45 #define snprintf _snprintf
48 /* The line size must be a positive integer. One hundred was chosen */
49 /* because few lines in Yacc input grammars exceed 100 characters. */
50 /* Note that if a line exceeds LINESIZE characters, the line buffer */
51 /* will be expanded to accomodate it. */
98 const char *line_format
= "\t\t\t\t\t// line %d \"%s\"\n";
99 const char *default_line_format
= "\t\t\t\t\t// line %d\n";
102 start_rule (bucket
*bp
, int s_lineno
);
108 if (cinc
>= cache_size
)
111 cache
= (char*)REALLOC(cache
, cache_size
);
112 if (cache
== 0) no_space();
121 register FILE *f
= input_file
;
125 if (saw_eof
|| (c
= getc(f
)) == EOF
)
127 if (line
) { FREE(line
); line
= 0; }
133 if (line
== 0 || linesize
!= (LINESIZE
+ 1))
135 if (line
) FREE(line
);
136 linesize
= LINESIZE
+ 1;
137 line
= (char*)MALLOC(linesize
);
138 if (line
== 0) no_space();
146 if (c
== '\n') { cptr
= line
; return; }
149 linesize
+= LINESIZE
;
150 line
= (char*)REALLOC(line
, linesize
);
151 if (line
== 0) no_space();
167 register char *p
, *s
, *t
;
169 if (line
== 0) return (0);
171 while (*s
!= '\n') ++s
;
172 p
= (char*)MALLOC(s
- line
+ 1);
173 if (p
== 0) no_space();
177 while ((*t
++ = *s
++) != '\n') continue;
186 int st_lineno
= lineno
;
187 char *st_line
= dup_line();
188 char *st_cptr
= st_line
+ (cptr
- line
);
193 if (*s
== '*' && s
[1] == '/')
203 unterminated_comment(st_lineno
, st_line
, st_cptr
);
230 if (line
== 0) return (EOF
);
256 else if (s
[1] == '/')
259 if (line
== 0) return (EOF
);
286 if (isupper(c
)) c
= tolower(c
);
289 else if (isdigit(c
) || c
== '_' || c
== '.' || c
== '$')
297 if (strcmp(cache
, "token") == 0 || strcmp(cache
, "term") == 0)
299 if (strcmp(cache
, "type") == 0)
301 if (strcmp(cache
, "left") == 0)
303 if (strcmp(cache
, "right") == 0)
305 if (strcmp(cache
, "nonassoc") == 0 || strcmp(cache
, "binary") == 0)
307 if (strcmp(cache
, "start") == 0)
315 if (c
== '%' || c
== '\\')
326 syntax_error(lineno
, line
, t_cptr
);
335 int need_newline
= 0;
336 int t_lineno
= lineno
;
337 char *t_line
= dup_line();
338 char *t_cptr
= t_line
+ (cptr
- line
- 2);
344 unterminated_text(t_lineno
, t_line
, t_cptr
);
346 fprintf(f
, line_format
, lineno
, input_file_name
);
358 unterminated_text(t_lineno
, t_line
, t_cptr
);
363 int s_lineno
= lineno
;
364 char *s_line
= dup_line();
365 char *s_cptr
= s_line
+ (cptr
- line
- 1);
380 unterminated_string(s_lineno
, s_line
, s_cptr
);
389 unterminated_string(s_lineno
, s_line
, s_cptr
);
401 do putc(c
, f
); while ((c
= *++cptr
) != '\n');
406 int c_lineno
= lineno
;
407 char *c_line
= dup_line();
408 char *c_cptr
= c_line
+ (cptr
- line
- 1);
416 if (c
== '*' && *cptr
== '/')
427 unterminated_comment(c_lineno
, c_line
, c_cptr
);
438 if (need_newline
) putc('\n', f
);
455 if (c
>= '0' && c
<= '9')
457 if (c
>= 'A' && c
<= 'F')
458 return (c
- 'A' + 10);
459 if (c
>= 'a' && c
<= 'f')
460 return (c
- 'a' + 10);
467 register int c
, quote
;
472 int s_lineno
= lineno
;
473 char *s_line
= dup_line();
474 char *s_cptr
= s_line
+ (cptr
- line
);
481 if (c
== quote
) break;
482 if (c
== '\n') unterminated_string(s_lineno
, s_line
, s_cptr
);
485 char *c_cptr
= cptr
- 1;
492 if (line
== 0) unterminated_string(s_lineno
, s_line
, s_cptr
);
495 case '0': case '1': case '2': case '3':
496 case '4': case '5': case '6': case '7':
501 n
= (n
<< 3) + (c
- '0');
505 n
= (n
<< 3) + (c
- '0');
509 if (n
> MAXCHAR
) illegal_character(c_cptr
);
516 if (n
< 0 || n
>= 16)
517 illegal_character(c_cptr
);
522 if (i
< 0 || i
>= 16) break;
525 if (n
> MAXCHAR
) illegal_character(c_cptr
);
530 case 'a': c
= 7; break;
531 case 'b': c
= '\b'; break;
532 case 'f': c
= '\f'; break;
533 case 'n': c
= '\n'; break;
534 case 'r': c
= '\r'; break;
535 case 't': c
= '\t'; break;
536 case 'v': c
= '\v'; break;
544 s
= (char*)MALLOC(n
);
545 if (s
== 0) no_space();
547 for (i
= 0; i
< n
; ++i
)
556 for (i
= 0; i
< n
; ++i
)
558 c
= ((unsigned char *)s
)[i
];
559 if (c
== '\\' || c
== cache
[0])
571 case 7: cachec('a'); break;
572 case '\b': cachec('b'); break;
573 case '\f': cachec('f'); break;
574 case '\n': cachec('n'); break;
575 case '\r': cachec('r'); break;
576 case '\t': cachec('t'); break;
577 case '\v': cachec('v'); break;
579 cachec(((c
>> 6) & 7) + '0');
580 cachec(((c
>> 3) & 7) + '0');
581 cachec((c
& 7) + '0');
595 if (n
== 1 && bp
->value
== UNDEFINED
)
596 bp
->value
= *(unsigned char *)s
;
603 is_reserved (const char *name
)
607 if (strcmp(name
, ".") == 0 ||
608 strcmp(name
, "$accept") == 0 ||
609 strcmp(name
, "$end") == 0)
612 if (name
[0] == '$' && name
[1] == '$' && isdigit(name
[2]))
615 while (isdigit(*s
)) ++s
;
616 if (*s
== NUL
) return (1);
628 for (c
= *cptr
; IS_IDENT(c
); c
= *++cptr
)
632 if (is_reserved(cache
)) used_reserved(cache
);
634 return (lookup(cache
));
644 for (c
= *cptr
; isdigit(c
); c
= *++cptr
)
645 n
= 10*n
+ (c
- '0');
651 get_tag (int emptyOk
)
656 int t_lineno
= lineno
;
657 char *t_line
= dup_line();
658 char *t_cptr
= t_line
+ (cptr
- line
);
662 if (c
== EOF
) unexpected_EOF();
663 if (emptyOk
&& c
== '>') {
664 ++cptr
; return 0; // 0 indicates empty tag if emptyOk
666 if (!isalpha(c
) && c
!= '_' && c
!= '$')
667 illegal_tag(t_lineno
, t_line
, t_cptr
);
670 do { cachec(c
); c
= *++cptr
; } while (IS_IDENT(c
));
674 if (c
== EOF
) unexpected_EOF();
676 illegal_tag(t_lineno
, t_line
, t_cptr
);
679 for (i
= 0; i
< ntags
; ++i
)
681 if (strcmp(cache
, tag_table
[i
]) == 0)
682 return (tag_table
[i
]);
688 tag_table
= (char **)
689 (tag_table
? REALLOC(tag_table
, tagmax
*sizeof(char *))
690 : MALLOC(tagmax
*sizeof(char *)));
691 if (tag_table
== 0) no_space();
694 s
= (char*)MALLOC(cinc
);
695 if (s
== 0) no_space();
697 tag_table
[ntags
] = s
;
704 declare_tokens (int assoc
)
711 if (assoc
!= TOKEN
) ++prec
;
714 if (c
== EOF
) unexpected_EOF();
719 if (c
== EOF
) unexpected_EOF();
724 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
726 else if (c
== '\'' || c
== '"')
731 if (bp
== goal
) tokenized_start(bp
->name
);
736 if (bp
->tag
&& tag
!= bp
->tag
)
737 retyped_warning(bp
->name
);
743 if (bp
->prec
&& prec
!= bp
->prec
)
744 reprec_warning(bp
->name
);
750 if (c
== EOF
) unexpected_EOF();
754 value
= get_number();
755 if (bp
->value
!= UNDEFINED
&& value
!= bp
->value
)
756 revalued_warning(bp
->name
);
759 if (c
== EOF
) unexpected_EOF();
772 if (c
== EOF
) unexpected_EOF();
773 if (c
!= '<') syntax_error(lineno
, line
, cptr
);
779 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
781 else if (c
== '\'' || c
== '"')
786 if (bp
->tag
&& tag
!= bp
->tag
)
787 retyped_warning(bp
->name
);
799 if (c
== EOF
) unexpected_EOF();
800 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '$')
801 syntax_error(lineno
, line
, cptr
);
803 if (bp
->class == TERM
)
804 terminal_start(bp
->name
);
805 if (goal
&& goal
!= bp
)
811 read_declarations (void)
816 cache
= (char*)MALLOC(cache_size
);
817 if (cache
== 0) no_space();
822 if (c
== EOF
) unexpected_EOF();
823 if (c
!= '%') syntax_error(lineno
, line
, cptr
);
824 switch (k
= keyword())
830 copy_text(prolog_file
);
852 initialize_grammar (void)
856 pitem
= (bucket
**) MALLOC(maxitems
*sizeof(bucket
*));
857 if (pitem
== 0) no_space();
866 plhs
= (bucket
**) MALLOC(maxrules
*sizeof(bucket
*));
867 if (plhs
== 0) no_space();
871 rprec
= (short *) MALLOC(maxrules
*sizeof(short));
872 if (rprec
== 0) no_space();
876 rassoc
= (char *) MALLOC(maxrules
*sizeof(char));
877 if (rassoc
== 0) no_space();
887 pitem
= (bucket
**) REALLOC(pitem
, maxitems
*sizeof(bucket
*));
888 if (pitem
== 0) no_space();
889 memset(pitem
+maxitems
-300, 0, 300*sizeof(bucket
*));
896 plhs
= (bucket
**) REALLOC(plhs
, maxrules
*sizeof(bucket
*));
897 if (plhs
== 0) no_space();
898 rprec
= (short *) REALLOC(rprec
, maxrules
*sizeof(short));
899 if (rprec
== 0) no_space();
900 rassoc
= (char *) REALLOC(rassoc
, maxrules
*sizeof(char));
901 if (rassoc
== 0) no_space();
905 advance_to_start (void)
923 copy_text(local_file
);
931 syntax_error(lineno
, line
, s_cptr
);
936 if (!isalpha(c
) && c
!= '_' && c
!= '.' && c
!= '_')
937 syntax_error(lineno
, line
, cptr
);
941 if (bp
->class == TERM
)
942 terminal_start(bp
->name
);
948 if (c
== EOF
) unexpected_EOF();
949 if (c
!= ':') syntax_error(lineno
, line
, cptr
);
950 start_rule(bp
, s_lineno
);
955 start_rule (bucket
*bp
, int s_lineno
)
957 if (bp
->class == TERM
)
958 terminal_lhs(s_lineno
);
960 if (nrules
>= maxrules
)
963 rprec
[nrules
] = UNDEFINED
;
964 rassoc
[nrules
] = TOKEN
;
972 if (nitems
>= maxitems
) expand_items();
974 if (!last_was_action
&& plhs
[nrules
]->tag
)
976 for (i
= nitems
- 1; pitem
[i
]; --i
) continue;
977 if (pitem
[i
+1] == 0 || pitem
[i
+1]->tag
!= plhs
[nrules
]->tag
)
978 default_action_warning(); /** if classes don't match exactly **/
979 } /** bug: could be superclass... **/
988 insert_empty_rule (void)
990 register bucket
*bp
, **bpp
;
993 sprintf(cache
, "$$%d", ++gensym
);
994 bp
= make_bucket(cache
);
995 last_symbol
->next
= bp
;
997 bp
->tag
= plhs
[nrules
]->tag
;
1000 if ((nitems
+= 2) > maxitems
)
1002 bpp
= pitem
+ nitems
- 1;
1004 while ((bpp
[0] = bpp
[-1])) --bpp
;
1006 if (++nrules
>= maxrules
)
1008 plhs
[nrules
] = plhs
[nrules
-1];
1009 plhs
[nrules
-1] = bp
;
1010 rprec
[nrules
] = rprec
[nrules
-1];
1011 rprec
[nrules
-1] = 0;
1012 rassoc
[nrules
] = rassoc
[nrules
-1];
1013 rassoc
[nrules
-1] = TOKEN
;
1020 register bucket
*bp
;
1021 int s_lineno
= lineno
;
1024 if (c
== '\'' || c
== '"')
1033 start_rule(bp
, s_lineno
);
1038 if (last_was_action
)
1039 insert_empty_rule();
1040 last_was_action
= 0;
1042 if (++nitems
> maxitems
)
1044 pitem
[nitems
-1] = bp
;
1055 FILE *f
= action_file
;
1056 int a_lineno
= lineno
;
1057 char *a_line
= dup_line();
1058 char *a_cptr
= a_line
+ (cptr
- line
);
1059 char buffer
[10000];
1061 int comment_lines
= 0;
1063 memset (buffer
, 0, 10000);
1065 if (last_was_action
)
1066 insert_empty_rule();
1067 last_was_action
= 1;
1069 fprintf(f
, "case %d:\n", nrules
- 2);
1070 if (*cptr
== '=') ++cptr
;
1074 for (i
= nitems
- 1; pitem
[i
]; --i
) ++n
;
1083 int d_lineno
= lineno
;
1084 char *d_line
= dup_line();
1085 char *d_cptr
= d_line
+ (cptr
- line
);
1092 if (tag
&& strcmp(tag
, "Object")) {
1093 len
+= sprintf(buffer
+ len
, "((%s)yyVal)", tag
);
1095 strcat (buffer
+ len
, "yyVal");
1102 else if (isdigit(c
))
1105 if (i
> n
) dollar_warning(d_lineno
, i
);
1106 if (tag
&& strcmp(tag
, "Object"))
1107 len
+= sprintf(buffer
+ len
, "((%s)yyVals[%d+yyTop])", tag
, i
- n
);
1109 len
+= sprintf(buffer
+ len
, "yyVals[%d+yyTop]", i
- n
);
1113 else if (c
== '-' && isdigit(cptr
[1]))
1116 i
= -get_number() - n
;
1117 if (tag
&& strcmp(tag
, "Object"))
1118 len
+= sprintf(buffer
+ len
, "((%s)yyVals[%d+yyTop])", tag
, i
);
1120 len
+= sprintf(buffer
+ len
, "yyVals[%d+yyTop]", i
);
1125 dollar_error(d_lineno
, d_line
, d_cptr
);
1127 else if (cptr
[1] == '$')
1129 if (ntags
&& plhs
[nrules
]->tag
== 0)
1131 strcat (buffer
, "yyVal");
1136 else if (isdigit(cptr
[1]))
1142 if (i
<= 0 || i
> n
)
1144 tag
= pitem
[nitems
+ i
- n
- 1]->tag
;
1146 untyped_rhs(i
, pitem
[nitems
+ i
- n
- 1]->name
),
1147 len
+= sprintf(buffer
+ len
, "yyVals[%d+yyTop]", i
- n
);
1148 else if (strcmp(tag
, "Object"))
1149 len
+= sprintf(buffer
+ len
, "((%s)yyVals[%d+yyTop])", tag
, i
- n
);
1151 len
+= sprintf(buffer
+ len
, "yyVals[%d+yyTop]", i
- n
);
1156 dollar_warning(lineno
, i
);
1158 len
+= sprintf(buffer
+ len
,"yyVals[%d+yyTop]", i
- n
);
1162 else if (cptr
[1] == '-')
1168 len
+= sprintf(buffer
+ len
, "yyVals[%d+yyTop]", -i
- n
);
1172 if (isalpha(c
) || c
== '_' || c
== '$')
1178 } while (isalnum(c
) || c
== '_' || c
== '$');
1188 if (line
) goto loop
;
1189 unterminated_action(a_lineno
, a_line
, a_cptr
);
1192 if (depth
> 0) goto loop
;
1200 if (--depth
> 0) goto loop
;
1206 int s_lineno
= lineno
;
1207 char *s_line
= dup_line();
1208 char *s_cptr
= s_line
+ (cptr
- line
- 1);
1221 unterminated_string(s_lineno
, s_line
, s_cptr
);
1230 unterminated_string(s_lineno
, s_line
, s_cptr
);
1240 buffer
[len
++] = '*';
1241 while ((c
= *++cptr
) != '\n')
1243 if (c
== '*' && cptr
[1] == '/'){
1244 buffer
[len
++] = '*';
1245 buffer
[len
++] = ' ';
1250 buffer
[len
++] = '*';
1251 buffer
[len
++] = '/';
1252 buffer
[len
++] = '\n';
1257 int c_lineno
= lineno
;
1258 char *c_line
= dup_line();
1259 char *c_cptr
= c_line
+ (cptr
- line
- 1);
1261 buffer
[len
++] = '*';
1267 if (c
== '*' && *cptr
== '/')
1269 buffer
[len
++] = '/';
1279 unterminated_comment(c_lineno
, c_line
, c_cptr
);
1289 if (comment_lines
> 0)
1292 if ((lineno
- (a_lineno
+ comment_lines
)) > 2)
1297 // the maximum size of of an unsigned int in characters is 20, with 8 for 'case_()\0'
1298 sprintf(mname
, "case_%d()", nrules
- 2);
1300 putc(' ', f
); putc(' ', f
);
1306 methods
= NEW2(maxmethods
, char *);
1308 else if (nmethods
== maxmethods
)
1311 methods
= (char**)REALLOC (methods
, maxmethods
*sizeof(char *));
1314 line_define
= NEW2(snprintf(NULL
, 0, line_format
, a_lineno
, input_file_name
)+1, char);
1315 sprintf(line_define
, line_format
, a_lineno
, input_file_name
);
1317 mbody
= NEW2(5+strlen(line_define
)+1+strlen(mname
)+strlen(buffer
)+1, char);
1318 strcpy(mbody
, "void ");
1319 strcat(mbody
, mname
);
1320 strcat(mbody
, "\n");
1321 strcat(mbody
, line_define
);
1322 strcat(mbody
, buffer
);
1323 methods
[nmethods
++] = mbody
;
1329 fprintf(f
, line_format
, lineno
, input_file_name
);
1330 putc(' ', f
); putc(' ', f
);
1331 fwrite(buffer
, 1, len
, f
);
1334 fprintf(f
, "\n break;\n");
1341 register bucket
*bp
= NULL
;
1344 if (c
== '%' || c
== '\\')
1352 else if ((c
== 'p' || c
== 'P') &&
1353 ((c
= cptr
[2]) == 'r' || c
== 'R') &&
1354 ((c
= cptr
[3]) == 'e' || c
== 'E') &&
1355 ((c
= cptr
[4]) == 'c' || c
== 'C') &&
1356 ((c
= cptr
[5], !IS_IDENT(c
))))
1359 syntax_error(lineno
, line
, cptr
);
1362 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$')
1364 else if (c
== '\'' || c
== '"')
1368 syntax_error(lineno
, line
, cptr
);
1372 if (rprec
[nrules
] != UNDEFINED
&& bp
->prec
!= rprec
[nrules
])
1375 rprec
[nrules
] = bp
->prec
;
1376 rassoc
[nrules
] = bp
->assoc
;
1385 initialize_grammar();
1391 if (c
== EOF
) break;
1392 if (isalpha(c
) || c
== '_' || c
== '.' || c
== '$' || c
== '\'' ||
1395 else if (c
== '{' || c
== '=')
1400 start_rule(plhs
[nrules
-1], 0);
1405 if (mark_symbol()) break;
1408 syntax_error(lineno
, line
, cptr
);
1418 if (tag_table
== 0) return;
1420 for (i
= 0; i
< ntags
; ++i
)
1422 assert(tag_table
[i
]);
1431 register bucket
*bp
;
1432 register char *p
, *s
, *t
;
1434 name_pool_size
= 13; /* 13 == sizeof("$end") + sizeof("$accept") */
1435 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1436 name_pool_size
+= strlen(bp
->name
) + 1;
1437 name_pool
= (char*)MALLOC(name_pool_size
);
1438 if (name_pool
== 0) no_space();
1440 strcpy(name_pool
, "$accept");
1441 strcpy(name_pool
+8, "$end");
1443 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1447 while ((*t
++ = *s
++)) continue;
1454 check_symbols (void)
1456 register bucket
*bp
;
1458 if (goal
->class == UNKNOWN
)
1459 undefined_goal(goal
->name
);
1461 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1463 if (bp
->class == UNKNOWN
)
1465 undefined_symbol_warning(bp
->name
);
1474 register bucket
*bp
;
1475 register bucket
**v
;
1476 register int i
, j
, k
, n
;
1480 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1483 if (bp
->class == TERM
) ++ntokens
;
1485 start_symbol
= ntokens
;
1486 nvars
= nsyms
- ntokens
;
1488 symbol_name
= (char **) MALLOC(nsyms
*sizeof(char *));
1489 if (symbol_name
== 0) no_space();
1490 symbol_value
= (short *) MALLOC(nsyms
*sizeof(short));
1491 if (symbol_value
== 0) no_space();
1492 symbol_prec
= (short *) MALLOC(nsyms
*sizeof(short));
1493 if (symbol_prec
== 0) no_space();
1494 symbol_assoc
= (char*)MALLOC(nsyms
);
1495 if (symbol_assoc
== 0) no_space();
1497 v
= (bucket
**) MALLOC(nsyms
*sizeof(bucket
*));
1498 if (v
== 0) no_space();
1501 v
[start_symbol
] = 0;
1504 j
= start_symbol
+ 1;
1505 for (bp
= first_symbol
; bp
; bp
= bp
->next
)
1507 if (bp
->class == TERM
)
1512 assert(i
== ntokens
&& j
== nsyms
);
1514 for (i
= 1; i
< ntokens
; ++i
)
1517 goal
->index
= start_symbol
+ 1;
1518 k
= start_symbol
+ 2;
1528 for (i
= start_symbol
+ 1; i
< nsyms
; ++i
)
1538 for (i
= 1; i
< ntokens
; ++i
)
1543 for (j
= k
++; j
> 0 && symbol_value
[j
-1] > n
; --j
)
1544 symbol_value
[j
] = symbol_value
[j
-1];
1545 symbol_value
[j
] = n
;
1549 if (v
[1]->value
== UNDEFINED
)
1554 for (i
= 2; i
< ntokens
; ++i
)
1556 if (v
[i
]->value
== UNDEFINED
)
1558 while (j
< k
&& n
== symbol_value
[j
])
1560 while (++j
< k
&& n
== symbol_value
[j
]) continue;
1568 symbol_name
[0] = name_pool
+ 8;
1569 symbol_value
[0] = 0;
1571 symbol_assoc
[0] = TOKEN
;
1572 for (i
= 1; i
< ntokens
; ++i
)
1574 symbol_name
[i
] = v
[i
]->name
;
1575 symbol_value
[i
] = v
[i
]->value
;
1576 symbol_prec
[i
] = v
[i
]->prec
;
1577 symbol_assoc
[i
] = v
[i
]->assoc
;
1579 symbol_name
[start_symbol
] = name_pool
;
1580 symbol_value
[start_symbol
] = -1;
1581 symbol_prec
[start_symbol
] = 0;
1582 symbol_assoc
[start_symbol
] = TOKEN
;
1583 for (++i
; i
< nsyms
; ++i
)
1586 symbol_name
[k
] = v
[i
]->name
;
1587 symbol_value
[k
] = v
[i
]->value
;
1588 symbol_prec
[k
] = v
[i
]->prec
;
1589 symbol_assoc
[k
] = v
[i
]->assoc
;
1601 ritem
= (short *) MALLOC(nitems
*sizeof(short));
1602 if (ritem
== 0) no_space();
1603 rlhs
= (short *) MALLOC(nrules
*sizeof(short));
1604 if (rlhs
== 0) no_space();
1605 rrhs
= (short *) MALLOC((nrules
+1)*sizeof(short));
1606 if (rrhs
== 0) no_space();
1607 rprec
= (short *) REALLOC(rprec
, nrules
*sizeof(short));
1608 if (rprec
== 0) no_space();
1609 rassoc
= (char*)REALLOC(rassoc
, nrules
);
1610 if (rassoc
== 0) no_space();
1613 ritem
[1] = goal
->index
;
1618 rlhs
[2] = start_symbol
;
1624 for (i
= 3; i
< nrules
; ++i
)
1626 rlhs
[i
] = plhs
[i
]->index
;
1632 ritem
[j
] = pitem
[j
]->index
;
1633 if (pitem
[j
]->class == TERM
)
1635 prec
= pitem
[j
]->prec
;
1636 assoc
= pitem
[j
]->assoc
;
1642 if (rprec
[i
] == UNDEFINED
)
1655 print_grammar (void)
1657 register int i
, j
, k
;
1659 register FILE *f
= verbose_file
;
1664 for (i
= 2; i
< nrules
; ++i
)
1666 if (rlhs
[i
] != rlhs
[i
-1])
1668 if (i
!= 2) fprintf(f
, "\n");
1669 fprintf(f
, "%4d %s :", i
- 2, symbol_name
[rlhs
[i
]]);
1670 spacing
= strlen(symbol_name
[rlhs
[i
]]) + 1;
1674 fprintf(f
, "%4d ", i
- 2);
1676 while (--j
>= 0) putc(' ', f
);
1680 while (ritem
[k
] >= 0)
1682 fprintf(f
, " %s", symbol_name
[ritem
[k
]]);
1693 create_symbol_table();
1694 read_declarations();
1696 free_symbol_table();