]> git.saurik.com Git - bison.git/blame - src/reader.c
* src/bison.simple (YYSTACK_USE_ALLOCA): Changed to allow users
[bison.git] / src / reader.c
CommitLineData
1ff442ca 1/* Input parser for bison
8c7ebe49 2 Copyright 1984, 1986, 1989, 1992, 1998, 2000
a70083a3 3 Free Software Foundation, Inc.
1ff442ca 4
41aca2e0 5 This file is part of Bison, the GNU Compiler Compiler.
1ff442ca 6
41aca2e0
AD
7 Bison is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
1ff442ca 11
41aca2e0
AD
12 Bison is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
1ff442ca 16
41aca2e0
AD
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
1ff442ca
NF
21
22
1ff442ca 23#include "system.h"
8c7ebe49 24#include "obstack.h"
2a91a95e
AD
25#include "quotearg.h"
26#include "quote.h"
ceed8467 27#include "getargs.h"
1ff442ca 28#include "files.h"
d7913476 29#include "xalloc.h"
1ff442ca
NF
30#include "symtab.h"
31#include "lex.h"
32#include "gram.h"
a0f6b076 33#include "complain.h"
6c89f1c1 34#include "output.h"
b2ca4022 35#include "reader.h"
340ef489 36#include "conflicts.h"
1ff442ca 37
1ff442ca 38/* Number of slots allocated (but not necessarily used yet) in `rline' */
4a120d45 39static int rline_allocated;
1ff442ca 40
a70083a3
AD
41typedef struct symbol_list
42{
43 struct symbol_list *next;
44 bucket *sym;
45 bucket *ruleprec;
46}
47symbol_list;
118fb205 48
1ff442ca 49int lineno;
1ff442ca 50char **tags;
d019d655 51short *user_toknums;
4a120d45
JT
52static symbol_list *grammar;
53static int start_flag;
54static bucket *startval;
1ff442ca
NF
55
56/* Nonzero if components of semantic values are used, implying
57 they must be unions. */
58static int value_components_used;
59
d7020c20
AD
60/* Nonzero if %union has been seen. */
61static int typed;
1ff442ca 62
d7020c20
AD
63/* Incremented for each %left, %right or %nonassoc seen */
64static int lastprec;
1ff442ca 65
1ff442ca 66static bucket *errtoken;
5b2e3c89 67static bucket *undeftoken;
0d533154 68\f
a70083a3 69
0d533154
AD
70/*===================\
71| Low level lexing. |
72\===================*/
943819bf
RS
73
74static void
118fb205 75skip_to_char (int target)
943819bf
RS
76{
77 int c;
78 if (target == '\n')
a0f6b076 79 complain (_(" Skipping to next \\n"));
943819bf 80 else
a0f6b076 81 complain (_(" Skipping to next %c"), target);
943819bf
RS
82
83 do
0d533154 84 c = skip_white_space ();
943819bf 85 while (c != target && c != EOF);
a083fbbf 86 if (c != EOF)
0d533154 87 ungetc (c, finput);
943819bf
RS
88}
89
90
0d533154
AD
91/*---------------------------------------------------------.
92| Read a signed integer from STREAM and return its value. |
93`---------------------------------------------------------*/
94
95static inline int
96read_signed_integer (FILE *stream)
97{
a70083a3
AD
98 int c = getc (stream);
99 int sign = 1;
100 int n = 0;
0d533154
AD
101
102 if (c == '-')
103 {
104 c = getc (stream);
105 sign = -1;
106 }
107
108 while (isdigit (c))
109 {
110 n = 10 * n + (c - '0');
111 c = getc (stream);
112 }
113
114 ungetc (c, stream);
115
116 return sign * n;
117}
118\f
79282c5a
AD
119/*--------------------------------------------------------------.
120| Get the data type (alternative in the union) of the value for |
121| symbol N in rule RULE. |
122`--------------------------------------------------------------*/
123
124static char *
125get_type_name (int n, symbol_list * rule)
126{
127 int i;
128 symbol_list *rp;
129
130 if (n < 0)
131 {
132 complain (_("invalid $ value"));
133 return NULL;
134 }
135
136 rp = rule;
137 i = 0;
138
139 while (i < n)
140 {
141 rp = rp->next;
142 if (rp == NULL || rp->sym == NULL)
143 {
144 complain (_("invalid $ value"));
145 return NULL;
146 }
147 i++;
148 }
149
150 return rp->sym->type_name;
151}
152\f
337bab46
AD
153/*------------------------------------------------------------.
154| Dump the string from FIN to OOUT if non null. MATCH is the |
155| delimiter of the string (either ' or "). |
156`------------------------------------------------------------*/
ae3c3164
AD
157
158static inline void
337bab46 159copy_string (FILE *fin, struct obstack *oout, int match)
ae3c3164
AD
160{
161 int c;
162
337bab46 163 obstack_1grow (oout, match);
8c7ebe49 164
4a120d45 165 c = getc (fin);
ae3c3164
AD
166
167 while (c != match)
168 {
169 if (c == EOF)
170 fatal (_("unterminated string at end of file"));
171 if (c == '\n')
172 {
a0f6b076 173 complain (_("unterminated string"));
4a120d45 174 ungetc (c, fin);
ae3c3164
AD
175 c = match; /* invent terminator */
176 continue;
177 }
178
337bab46 179 obstack_1grow (oout, c);
ae3c3164
AD
180
181 if (c == '\\')
182 {
4a120d45 183 c = getc (fin);
ae3c3164
AD
184 if (c == EOF)
185 fatal (_("unterminated string at end of file"));
337bab46 186 obstack_1grow (oout, c);
8c7ebe49 187
ae3c3164
AD
188 if (c == '\n')
189 lineno++;
190 }
191
a70083a3 192 c = getc (fin);
ae3c3164
AD
193 }
194
337bab46 195 obstack_1grow (oout, c);
ae3c3164
AD
196}
197
198
337bab46
AD
199/*-----------------------------------------------------------------.
200| Dump the wannabee comment from IN to OUT1 and OUT2 (which can be |
201| NULL). In fact we just saw a `/', which might or might not be a |
202| comment. In any case, copy what we saw. |
203| |
204| OUT2 might be NULL. |
205`-----------------------------------------------------------------*/
ae3c3164
AD
206
207static inline void
337bab46 208copy_comment2 (FILE *fin, struct obstack *oout1, struct obstack *oout2)
ae3c3164
AD
209{
210 int cplus_comment;
a70083a3 211 int ended;
550a72a3
AD
212 int c;
213
214 /* We read a `/', output it. */
337bab46 215 obstack_1grow (oout1, '/');
896fe5c1
AD
216 if (oout2)
217 obstack_1grow (oout2, '/');
550a72a3
AD
218
219 switch ((c = getc (fin)))
220 {
221 case '/':
222 cplus_comment = 1;
223 break;
224 case '*':
225 cplus_comment = 0;
226 break;
227 default:
228 ungetc (c, fin);
229 return;
230 }
ae3c3164 231
337bab46 232 obstack_1grow (oout1, c);
896fe5c1
AD
233 if (oout2)
234 obstack_1grow (oout2, c);
550a72a3 235 c = getc (fin);
ae3c3164
AD
236
237 ended = 0;
238 while (!ended)
239 {
240 if (!cplus_comment && c == '*')
241 {
242 while (c == '*')
243 {
337bab46 244 obstack_1grow (oout1, c);
896fe5c1
AD
245 if (oout2)
246 obstack_1grow (oout2, c);
550a72a3 247 c = getc (fin);
ae3c3164
AD
248 }
249
250 if (c == '/')
251 {
337bab46 252 obstack_1grow (oout1, c);
896fe5c1
AD
253 if (oout2)
254 obstack_1grow (oout2, c);
ae3c3164
AD
255 ended = 1;
256 }
257 }
258 else if (c == '\n')
259 {
260 lineno++;
337bab46 261 obstack_1grow (oout1, c);
896fe5c1
AD
262 if (oout2)
263 obstack_1grow (oout2, c);
ae3c3164
AD
264 if (cplus_comment)
265 ended = 1;
266 else
550a72a3 267 c = getc (fin);
ae3c3164
AD
268 }
269 else if (c == EOF)
270 fatal (_("unterminated comment"));
271 else
272 {
337bab46 273 obstack_1grow (oout1, c);
896fe5c1
AD
274 if (oout2)
275 obstack_1grow (oout2, c);
550a72a3 276 c = getc (fin);
ae3c3164
AD
277 }
278 }
279}
280
281
550a72a3
AD
282/*-------------------------------------------------------------------.
283| Dump the comment (actually the current string starting with a `/') |
337bab46 284| from FIN to OOUT. |
550a72a3 285`-------------------------------------------------------------------*/
27821bff
AD
286
287static inline void
337bab46 288copy_comment (FILE *fin, struct obstack *oout)
27821bff 289{
337bab46 290 copy_comment2 (fin, oout, NULL);
27821bff
AD
291}
292
293
a70083a3 294/*-----------------------------------------------------------------.
337bab46 295| FIN is pointing to a location (i.e., a `@'). Output to OOUT a |
a70083a3
AD
296| reference to this location. STACK_OFFSET is the number of values |
297| in the current rule so far, which says where to find `$0' with |
298| respect to the top of the stack. |
299`-----------------------------------------------------------------*/
1ff442ca 300
a70083a3 301static inline void
337bab46 302copy_at (FILE *fin, struct obstack *oout, int stack_offset)
1ff442ca 303{
a70083a3 304 int c;
1ff442ca 305
a70083a3
AD
306 c = getc (fin);
307 if (c == '$')
1ff442ca 308 {
ff4423cc 309 obstack_sgrow (oout, "yyloc");
89cab50d 310 locations_flag = 1;
a70083a3
AD
311 }
312 else if (isdigit (c) || c == '-')
313 {
314 int n;
1ff442ca 315
a70083a3
AD
316 ungetc (c, fin);
317 n = read_signed_integer (fin);
943819bf 318
337bab46 319 obstack_fgrow1 (oout, "yylsp[%d]", n - stack_offset);
89cab50d 320 locations_flag = 1;
1ff442ca 321 }
a70083a3 322 else
ff4a34be
AD
323 {
324 char buf[] = "@c";
325 buf[1] = c;
326 complain (_("%s is invalid"), quote (buf));
327 }
1ff442ca 328}
79282c5a
AD
329
330
331/*-------------------------------------------------------------------.
332| FIN is pointing to a wannabee semantic value (i.e., a `$'). |
333| |
334| Possible inputs: $[<TYPENAME>]($|integer) |
335| |
337bab46 336| Output to OOUT a reference to this semantic value. STACK_OFFSET is |
79282c5a
AD
337| the number of values in the current rule so far, which says where |
338| to find `$0' with respect to the top of the stack. |
339`-------------------------------------------------------------------*/
340
341static inline void
337bab46 342copy_dollar (FILE *fin, struct obstack *oout,
79282c5a
AD
343 symbol_list *rule, int stack_offset)
344{
345 int c = getc (fin);
b0ce6046 346 const char *type_name = NULL;
79282c5a 347
f282676b 348 /* Get the type name if explicit. */
79282c5a
AD
349 if (c == '<')
350 {
f282676b 351 read_type_name (fin);
79282c5a
AD
352 type_name = token_buffer;
353 value_components_used = 1;
79282c5a
AD
354 c = getc (fin);
355 }
356
357 if (c == '$')
358 {
ff4423cc 359 obstack_sgrow (oout, "yyval");
8c7ebe49 360
79282c5a
AD
361 if (!type_name)
362 type_name = get_type_name (0, rule);
363 if (type_name)
337bab46 364 obstack_fgrow1 (oout, ".%s", type_name);
79282c5a
AD
365 if (!type_name && typed)
366 complain (_("$$ of `%s' has no declared type"),
367 rule->sym->tag);
368 }
369 else if (isdigit (c) || c == '-')
370 {
371 int n;
372 ungetc (c, fin);
373 n = read_signed_integer (fin);
374
375 if (!type_name && n > 0)
376 type_name = get_type_name (n, rule);
377
337bab46 378 obstack_fgrow1 (oout, "yyvsp[%d]", n - stack_offset);
8c7ebe49 379
79282c5a 380 if (type_name)
337bab46 381 obstack_fgrow1 (oout, ".%s", type_name);
79282c5a
AD
382 if (!type_name && typed)
383 complain (_("$%d of `%s' has no declared type"),
384 n, rule->sym->tag);
385 }
386 else
387 {
388 char buf[] = "$c";
389 buf[1] = c;
390 complain (_("%s is invalid"), quote (buf));
391 }
392}
a70083a3
AD
393\f
394/*-------------------------------------------------------------------.
395| Copy the contents of a `%{ ... %}' into the definitions file. The |
396| `%{' has already been read. Return after reading the `%}'. |
397`-------------------------------------------------------------------*/
1ff442ca 398
4a120d45 399static void
118fb205 400copy_definition (void)
1ff442ca 401{
a70083a3 402 int c;
ae3c3164 403 /* -1 while reading a character if prev char was %. */
a70083a3 404 int after_percent;
1ff442ca 405
89cab50d 406 if (!no_lines_flag)
2a91a95e
AD
407 obstack_fgrow2 (&attrs_obstack, "#line %d %s\n",
408 lineno, quotearg_style (c_quoting_style, infile));
1ff442ca
NF
409
410 after_percent = 0;
411
ae3c3164 412 c = getc (finput);
1ff442ca
NF
413
414 for (;;)
415 {
416 switch (c)
417 {
418 case '\n':
dd60faec 419 obstack_1grow (&attrs_obstack, c);
1ff442ca
NF
420 lineno++;
421 break;
422
423 case '%':
a70083a3 424 after_percent = -1;
1ff442ca 425 break;
a083fbbf 426
1ff442ca
NF
427 case '\'':
428 case '"':
337bab46 429 copy_string (finput, &attrs_obstack, c);
1ff442ca
NF
430 break;
431
432 case '/':
337bab46 433 copy_comment (finput, &attrs_obstack);
1ff442ca
NF
434 break;
435
436 case EOF:
a70083a3 437 fatal ("%s", _("unterminated `%{' definition"));
1ff442ca
NF
438
439 default:
dd60faec 440 obstack_1grow (&attrs_obstack, c);
1ff442ca
NF
441 }
442
a70083a3 443 c = getc (finput);
1ff442ca
NF
444
445 if (after_percent)
446 {
447 if (c == '}')
448 return;
dd60faec 449 obstack_1grow (&attrs_obstack, '%');
1ff442ca
NF
450 }
451 after_percent = 0;
1ff442ca 452 }
1ff442ca
NF
453}
454
455
d7020c20
AD
456/*-------------------------------------------------------------------.
457| Parse what comes after %token or %nterm. For %token, WHAT_IS is |
458| token_sym and WHAT_IS_NOT is nterm_sym. For %nterm, the arguments |
459| are reversed. |
460`-------------------------------------------------------------------*/
1ff442ca 461
4a120d45 462static void
d7020c20 463parse_token_decl (symbol_class what_is, symbol_class what_is_not)
1ff442ca 464{
f17bcd1f 465 token_t token = 0;
a70083a3 466 char *typename = 0;
1ff442ca 467
1e9798d5
AD
468 /* The symbol being defined. */
469 struct bucket *symbol = NULL;
470
471 /* After `%token' and `%nterm', any number of symbols maybe be
472 defined. */
1ff442ca
NF
473 for (;;)
474 {
e6011337
JT
475 int tmp_char = ungetc (skip_white_space (), finput);
476
1e9798d5
AD
477 /* `%' (for instance from `%token', or from `%%' etc.) is the
478 only valid means to end this declaration. */
e6011337 479 if (tmp_char == '%')
1ff442ca 480 return;
e6011337 481 if (tmp_char == EOF)
a0f6b076 482 fatal (_("Premature EOF after %s"), token_buffer);
e6011337 483
a70083a3 484 token = lex ();
511e79b3 485 if (token == tok_comma)
943819bf
RS
486 {
487 symbol = NULL;
488 continue;
489 }
511e79b3 490 if (token == tok_typename)
1ff442ca 491 {
95e36146 492 typename = xstrdup (token_buffer);
1ff442ca 493 value_components_used = 1;
943819bf
RS
494 symbol = NULL;
495 }
511e79b3 496 else if (token == tok_identifier && *symval->tag == '\"' && symbol)
943819bf 497 {
8e03724b
AD
498 if (symval->alias)
499 warn (_("symbol `%s' used more than once as a literal string"),
500 symval->tag);
501 else if (symbol->alias)
502 warn (_("symbol `%s' given more than one literal string"),
503 symbol->tag);
504 else
505 {
506 symval->class = token_sym;
507 symval->type_name = typename;
508 symval->user_token_number = symbol->user_token_number;
509 symbol->user_token_number = SALIAS;
510 symval->alias = symbol;
511 symbol->alias = symval;
512 /* symbol and symval combined are only one symbol */
513 nsyms--;
514 }
943819bf 515 translations = 1;
8e03724b 516 symbol = NULL;
1ff442ca 517 }
511e79b3 518 else if (token == tok_identifier)
1ff442ca
NF
519 {
520 int oldclass = symval->class;
943819bf 521 symbol = symval;
1ff442ca 522
943819bf 523 if (symbol->class == what_is_not)
a0f6b076 524 complain (_("symbol %s redefined"), symbol->tag);
943819bf 525 symbol->class = what_is;
d7020c20 526 if (what_is == nterm_sym && oldclass != nterm_sym)
943819bf 527 symbol->value = nvars++;
1ff442ca
NF
528
529 if (typename)
530 {
943819bf
RS
531 if (symbol->type_name == NULL)
532 symbol->type_name = typename;
a70083a3 533 else if (strcmp (typename, symbol->type_name) != 0)
a0f6b076 534 complain (_("type redeclaration for %s"), symbol->tag);
1ff442ca
NF
535 }
536 }
511e79b3 537 else if (symbol && token == tok_number)
a70083a3 538 {
943819bf 539 symbol->user_token_number = numval;
1ff442ca 540 translations = 1;
a70083a3 541 }
1ff442ca 542 else
943819bf 543 {
a0f6b076 544 complain (_("`%s' is invalid in %s"),
d7020c20 545 token_buffer, (what_is == token_sym) ? "%token" : "%nterm");
a70083a3 546 skip_to_char ('%');
943819bf 547 }
1ff442ca
NF
548 }
549
550}
551
1ff442ca 552
d7020c20
AD
553/*------------------------------.
554| Parse what comes after %start |
555`------------------------------*/
1ff442ca 556
4a120d45 557static void
118fb205 558parse_start_decl (void)
1ff442ca
NF
559{
560 if (start_flag)
27821bff 561 complain (_("multiple %s declarations"), "%start");
511e79b3 562 if (lex () != tok_identifier)
27821bff 563 complain (_("invalid %s declaration"), "%start");
943819bf
RS
564 else
565 {
566 start_flag = 1;
567 startval = symval;
568 }
1ff442ca
NF
569}
570
a70083a3
AD
571/*-----------------------------------------------------------.
572| read in a %type declaration and record its information for |
573| get_type_name to access |
574`-----------------------------------------------------------*/
575
576static void
577parse_type_decl (void)
578{
a70083a3
AD
579 char *name;
580
511e79b3 581 if (lex () != tok_typename)
a70083a3
AD
582 {
583 complain ("%s", _("%type declaration has no <typename>"));
584 skip_to_char ('%');
585 return;
586 }
587
95e36146 588 name = xstrdup (token_buffer);
a70083a3
AD
589
590 for (;;)
591 {
f17bcd1f 592 token_t t;
a70083a3
AD
593 int tmp_char = ungetc (skip_white_space (), finput);
594
595 if (tmp_char == '%')
596 return;
597 if (tmp_char == EOF)
598 fatal (_("Premature EOF after %s"), token_buffer);
599
600 t = lex ();
601
602 switch (t)
1ff442ca
NF
603 {
604
511e79b3
AD
605 case tok_comma:
606 case tok_semicolon:
1ff442ca
NF
607 break;
608
511e79b3 609 case tok_identifier:
1ff442ca
NF
610 if (symval->type_name == NULL)
611 symval->type_name = name;
a70083a3 612 else if (strcmp (name, symval->type_name) != 0)
a0f6b076 613 complain (_("type redeclaration for %s"), symval->tag);
1ff442ca
NF
614
615 break;
616
617 default:
a0f6b076
AD
618 complain (_("invalid %%type declaration due to item: %s"),
619 token_buffer);
a70083a3 620 skip_to_char ('%');
1ff442ca
NF
621 }
622 }
623}
624
625
626
d7020c20
AD
627/*----------------------------------------------------------------.
628| Read in a %left, %right or %nonassoc declaration and record its |
629| information. |
630`----------------------------------------------------------------*/
1ff442ca 631
4a120d45 632static void
d7020c20 633parse_assoc_decl (associativity assoc)
1ff442ca 634{
a70083a3
AD
635 char *name = NULL;
636 int prev = 0;
1ff442ca 637
a70083a3 638 lastprec++; /* Assign a new precedence level, never 0. */
1ff442ca 639
1ff442ca
NF
640 for (;;)
641 {
f17bcd1f 642 token_t t;
e6011337 643 int tmp_char = ungetc (skip_white_space (), finput);
1ff442ca 644
e6011337 645 if (tmp_char == '%')
1ff442ca 646 return;
e6011337 647 if (tmp_char == EOF)
a0f6b076 648 fatal (_("Premature EOF after %s"), token_buffer);
1ff442ca 649
a70083a3 650 t = lex ();
1ff442ca
NF
651
652 switch (t)
653 {
511e79b3 654 case tok_typename:
95e36146 655 name = xstrdup (token_buffer);
1ff442ca
NF
656 break;
657
511e79b3 658 case tok_comma:
1ff442ca
NF
659 break;
660
511e79b3 661 case tok_identifier:
1ff442ca 662 if (symval->prec != 0)
a0f6b076 663 complain (_("redefining precedence of %s"), symval->tag);
1ff442ca
NF
664 symval->prec = lastprec;
665 symval->assoc = assoc;
d7020c20 666 if (symval->class == nterm_sym)
a0f6b076 667 complain (_("symbol %s redefined"), symval->tag);
d7020c20 668 symval->class = token_sym;
1ff442ca 669 if (name)
a70083a3 670 { /* record the type, if one is specified */
1ff442ca
NF
671 if (symval->type_name == NULL)
672 symval->type_name = name;
a70083a3 673 else if (strcmp (name, symval->type_name) != 0)
a0f6b076 674 complain (_("type redeclaration for %s"), symval->tag);
1ff442ca
NF
675 }
676 break;
677
511e79b3
AD
678 case tok_number:
679 if (prev == tok_identifier)
a70083a3 680 {
1ff442ca
NF
681 symval->user_token_number = numval;
682 translations = 1;
a70083a3
AD
683 }
684 else
685 {
686 complain (_
687 ("invalid text (%s) - number should be after identifier"),
688token_buffer);
689 skip_to_char ('%');
690 }
1ff442ca
NF
691 break;
692
511e79b3 693 case tok_semicolon:
1ff442ca
NF
694 return;
695
696 default:
a0f6b076 697 complain (_("unexpected item: %s"), token_buffer);
a70083a3 698 skip_to_char ('%');
1ff442ca
NF
699 }
700
701 prev = t;
702
703 }
704}
705
706
707
dd60faec
AD
708/*--------------------------------------------------------------.
709| Copy the union declaration into ATTRS_OBSTACK (and fdefines), |
710| where it is made into the definition of YYSTYPE, the type of |
711| elements of the parser value stack. |
712`--------------------------------------------------------------*/
1ff442ca 713
4a120d45 714static void
118fb205 715parse_union_decl (void)
1ff442ca 716{
a70083a3
AD
717 int c;
718 int count = 0;
1ff442ca
NF
719
720 if (typed)
27821bff 721 complain (_("multiple %s declarations"), "%union");
1ff442ca
NF
722
723 typed = 1;
724
89cab50d 725 if (!no_lines_flag)
2a91a95e
AD
726 obstack_fgrow2 (&attrs_obstack, "\n#line %d %s\n",
727 lineno, quotearg_style (c_quoting_style, infile));
1ff442ca 728 else
dd60faec 729 obstack_1grow (&attrs_obstack, '\n');
1ff442ca 730
ff4423cc 731 obstack_sgrow (&attrs_obstack, "typedef union");
896fe5c1 732 if (defines_flag)
ff4423cc 733 obstack_sgrow (&defines_obstack, "typedef union");
1ff442ca 734
27821bff 735 c = getc (finput);
1ff442ca
NF
736
737 while (c != EOF)
738 {
dd60faec 739 obstack_1grow (&attrs_obstack, c);
896fe5c1 740 if (defines_flag)
d7045ec6 741 obstack_1grow (&defines_obstack, c);
1ff442ca
NF
742
743 switch (c)
744 {
745 case '\n':
746 lineno++;
747 break;
748
749 case '/':
337bab46 750 copy_comment2 (finput, &defines_obstack, &attrs_obstack);
1ff442ca
NF
751 break;
752
1ff442ca
NF
753 case '{':
754 count++;
755 break;
756
757 case '}':
758 if (count == 0)
27821bff 759 complain (_("unmatched %s"), "`}'");
1ff442ca 760 count--;
943819bf 761 if (count <= 0)
1ff442ca 762 {
ff4423cc 763 obstack_sgrow (&attrs_obstack, " YYSTYPE;\n");
896fe5c1 764 if (defines_flag)
ff4423cc 765 obstack_sgrow (&defines_obstack, " YYSTYPE;\n");
1ff442ca 766 /* JF don't choke on trailing semi */
27821bff
AD
767 c = skip_white_space ();
768 if (c != ';')
a70083a3 769 ungetc (c, finput);
1ff442ca
NF
770 return;
771 }
772 }
773
27821bff 774 c = getc (finput);
1ff442ca
NF
775 }
776}
777
d7020c20
AD
778
779/*-------------------------------------------------------.
780| Parse the declaration %expect N which says to expect N |
781| shift-reduce conflicts. |
782`-------------------------------------------------------*/
1ff442ca 783
4a120d45 784static void
118fb205 785parse_expect_decl (void)
1ff442ca 786{
131e2fef 787 int c = skip_white_space ();
1ff442ca
NF
788 ungetc (c, finput);
789
131e2fef 790 if (!isdigit (c))
79282c5a 791 complain (_("argument of %%expect is not an integer"));
131e2fef
AD
792 else
793 expected_conflicts = read_signed_integer (finput);
1ff442ca
NF
794}
795
a70083a3
AD
796
797/*-------------------------------------------------------------------.
798| Parse what comes after %thong. the full syntax is |
799| |
800| %thong <type> token number literal |
801| |
802| the <type> or number may be omitted. The number specifies the |
803| user_token_number. |
804| |
805| Two symbols are entered in the table, one for the token symbol and |
806| one for the literal. Both are given the <type>, if any, from the |
807| declaration. The ->user_token_number of the first is SALIAS and |
808| the ->user_token_number of the second is set to the number, if |
809| any, from the declaration. The two symbols are linked via |
810| pointers in their ->alias fields. |
811| |
812| During OUTPUT_DEFINES_TABLE, the symbol is reported thereafter, |
813| only the literal string is retained it is the literal string that |
814| is output to yytname |
815`-------------------------------------------------------------------*/
816
817static void
818parse_thong_decl (void)
7b306f52 819{
f17bcd1f 820 token_t token;
a70083a3
AD
821 struct bucket *symbol;
822 char *typename = 0;
95e36146 823 int usrtoknum;
7b306f52 824
a70083a3
AD
825 translations = 1;
826 token = lex (); /* fetch typename or first token */
511e79b3 827 if (token == tok_typename)
7b306f52 828 {
95e36146 829 typename = xstrdup (token_buffer);
a70083a3
AD
830 value_components_used = 1;
831 token = lex (); /* fetch first token */
7b306f52 832 }
7b306f52 833
a70083a3 834 /* process first token */
7b306f52 835
511e79b3 836 if (token != tok_identifier)
a70083a3
AD
837 {
838 complain (_("unrecognized item %s, expected an identifier"),
839 token_buffer);
840 skip_to_char ('%');
841 return;
7b306f52 842 }
d7020c20 843 symval->class = token_sym;
a70083a3
AD
844 symval->type_name = typename;
845 symval->user_token_number = SALIAS;
846 symbol = symval;
7b306f52 847
a70083a3 848 token = lex (); /* get number or literal string */
1ff442ca 849
511e79b3 850 if (token == tok_number)
943819bf 851 {
a70083a3
AD
852 usrtoknum = numval;
853 token = lex (); /* okay, did number, now get literal */
943819bf 854 }
a70083a3
AD
855 else
856 usrtoknum = 0;
1ff442ca 857
a70083a3 858 /* process literal string token */
1ff442ca 859
511e79b3 860 if (token != tok_identifier || *symval->tag != '\"')
1ff442ca 861 {
a70083a3
AD
862 complain (_("expected string constant instead of %s"), token_buffer);
863 skip_to_char ('%');
864 return;
1ff442ca 865 }
d7020c20 866 symval->class = token_sym;
a70083a3
AD
867 symval->type_name = typename;
868 symval->user_token_number = usrtoknum;
1ff442ca 869
a70083a3
AD
870 symval->alias = symbol;
871 symbol->alias = symval;
1ff442ca 872
79282c5a
AD
873 /* symbol and symval combined are only one symbol. */
874 nsyms--;
a70083a3 875}
3cef001a 876
7333d403
AD
877/*------------------------------------------.
878| Parse what comes after %header_extension. |
879`------------------------------------------*/
880
881static void
882parse_header_extension_decl (void)
883{
884 char buff[32];
3e3da797 885
7333d403
AD
886 if (header_extension)
887 complain (_("multiple %%header_extension declarations"));
888 fscanf (finput, "%s", buff);
3e3da797 889 header_extension = xstrdup (buff);
7333d403
AD
890}
891
892/*------------------------------------------.
893| Parse what comes after %source_extension. |
894`------------------------------------------*/
895
896static void
897parse_source_extension_decl (void)
898{
899 char buff[32];
3e3da797 900
7333d403
AD
901 if (src_extension)
902 complain (_("multiple %%source_extension declarations"));
903 fscanf (finput, "%s", buff);
3e3da797 904 src_extension = xstrdup (buff);
7333d403 905}
d7020c20 906
a70083a3
AD
907/*----------------------------------------------------------------.
908| Read from finput until `%%' is seen. Discard the `%%'. Handle |
909| any `%' declarations, and copy the contents of any `%{ ... %}' |
dd60faec 910| groups to ATTRS_OBSTACK. |
a70083a3 911`----------------------------------------------------------------*/
1ff442ca 912
4a120d45 913static void
a70083a3 914read_declarations (void)
1ff442ca 915{
a70083a3
AD
916 int c;
917 int tok;
1ff442ca 918
a70083a3 919 for (;;)
1ff442ca 920 {
a70083a3 921 c = skip_white_space ();
1ff442ca 922
a70083a3
AD
923 if (c == '%')
924 {
925 tok = parse_percent_token ();
1ff442ca 926
a70083a3 927 switch (tok)
943819bf 928 {
511e79b3 929 case tok_two_percents:
a70083a3 930 return;
1ff442ca 931
511e79b3 932 case tok_percent_left_curly:
a70083a3
AD
933 copy_definition ();
934 break;
1ff442ca 935
511e79b3 936 case tok_token:
d7020c20 937 parse_token_decl (token_sym, nterm_sym);
a70083a3 938 break;
1ff442ca 939
511e79b3 940 case tok_nterm:
d7020c20 941 parse_token_decl (nterm_sym, token_sym);
a70083a3 942 break;
1ff442ca 943
511e79b3 944 case tok_type:
a70083a3
AD
945 parse_type_decl ();
946 break;
1ff442ca 947
511e79b3 948 case tok_start:
a70083a3
AD
949 parse_start_decl ();
950 break;
118fb205 951
511e79b3 952 case tok_union:
a70083a3
AD
953 parse_union_decl ();
954 break;
1ff442ca 955
511e79b3 956 case tok_expect:
a70083a3
AD
957 parse_expect_decl ();
958 break;
6deb4447 959
511e79b3 960 case tok_thong:
a70083a3
AD
961 parse_thong_decl ();
962 break;
d7020c20 963
511e79b3 964 case tok_left:
d7020c20 965 parse_assoc_decl (left_assoc);
a70083a3 966 break;
1ff442ca 967
511e79b3 968 case tok_right:
d7020c20 969 parse_assoc_decl (right_assoc);
a70083a3 970 break;
1ff442ca 971
511e79b3 972 case tok_nonassoc:
d7020c20 973 parse_assoc_decl (non_assoc);
a70083a3 974 break;
1ff442ca 975
7333d403 976 case tok_hdrext:
09a6de7e 977 parse_header_extension_decl ();
7333d403
AD
978 break;
979
980 case tok_srcext:
09a6de7e 981 parse_source_extension_decl ();
7333d403
AD
982 break;
983
511e79b3 984 case tok_noop:
a70083a3 985 break;
1ff442ca 986
a70083a3
AD
987 default:
988 complain (_("unrecognized: %s"), token_buffer);
989 skip_to_char ('%');
990 }
991 }
992 else if (c == EOF)
993 fatal (_("no input grammar"));
994 else
995 {
ff4a34be
AD
996 char buf[] = "c";
997 buf[0] = c;
998 complain (_("unknown character: %s"), quote (buf));
a70083a3 999 skip_to_char ('%');
1ff442ca 1000 }
1ff442ca 1001 }
1ff442ca 1002}
a70083a3
AD
1003\f
1004/*-------------------------------------------------------------------.
1005| Assuming that a `{' has just been seen, copy everything up to the |
1006| matching `}' into the actions file. STACK_OFFSET is the number of |
1007| values in the current rule so far, which says where to find `$0' |
1008| with respect to the top of the stack. |
1009`-------------------------------------------------------------------*/
1ff442ca 1010
4a120d45 1011static void
79282c5a 1012copy_action (symbol_list *rule, int stack_offset)
1ff442ca 1013{
a70083a3 1014 int c;
a70083a3 1015 int count;
8c7ebe49 1016 char buf[4096];
1ff442ca
NF
1017
1018 /* offset is always 0 if parser has already popped the stack pointer */
41aca2e0
AD
1019 if (semantic_parser)
1020 stack_offset = 0;
1ff442ca 1021
8c7ebe49
AD
1022 sprintf (buf, "\ncase %d:\n", nrules);
1023 obstack_grow (&action_obstack, buf, strlen (buf));
1024
89cab50d 1025 if (!no_lines_flag)
8c7ebe49 1026 {
2a91a95e
AD
1027 sprintf (buf, "#line %d %s\n",
1028 lineno, quotearg_style (c_quoting_style, infile));
8c7ebe49
AD
1029 obstack_grow (&action_obstack, buf, strlen (buf));
1030 }
1031 obstack_1grow (&action_obstack, '{');
1ff442ca
NF
1032
1033 count = 1;
a70083a3 1034 c = getc (finput);
1ff442ca
NF
1035
1036 while (count > 0)
1037 {
1038 while (c != '}')
a70083a3
AD
1039 {
1040 switch (c)
1ff442ca
NF
1041 {
1042 case '\n':
8c7ebe49 1043 obstack_1grow (&action_obstack, c);
1ff442ca
NF
1044 lineno++;
1045 break;
1046
1047 case '{':
8c7ebe49 1048 obstack_1grow (&action_obstack, c);
1ff442ca
NF
1049 count++;
1050 break;
1051
1052 case '\'':
1053 case '"':
337bab46 1054 copy_string (finput, &action_obstack, c);
1ff442ca
NF
1055 break;
1056
1057 case '/':
337bab46 1058 copy_comment (finput, &action_obstack);
1ff442ca
NF
1059 break;
1060
1061 case '$':
337bab46 1062 copy_dollar (finput, &action_obstack,
8c7ebe49 1063 rule, stack_offset);
1ff442ca
NF
1064 break;
1065
1066 case '@':
337bab46 1067 copy_at (finput, &action_obstack,
8c7ebe49 1068 stack_offset);
6666f98f 1069 break;
1ff442ca
NF
1070
1071 case EOF:
27821bff 1072 fatal (_("unmatched %s"), "`{'");
1ff442ca
NF
1073
1074 default:
8c7ebe49 1075 obstack_1grow (&action_obstack, c);
a70083a3
AD
1076 }
1077
1078 c = getc (finput);
1079 }
1080
1081 /* above loop exits when c is '}' */
1082
1083 if (--count)
1084 {
8c7ebe49 1085 obstack_1grow (&action_obstack, c);
a70083a3
AD
1086 c = getc (finput);
1087 }
1088 }
1089
ff4423cc 1090 obstack_sgrow (&action_obstack, ";\n break;}");
a70083a3
AD
1091}
1092\f
1093/*-------------------------------------------------------------------.
1094| After `%guard' is seen in the input file, copy the actual guard |
1095| into the guards file. If the guard is followed by an action, copy |
1096| that into the actions file. STACK_OFFSET is the number of values |
1097| in the current rule so far, which says where to find `$0' with |
1098| respect to the top of the stack, for the simple parser in which |
1099| the stack is not popped until after the guard is run. |
1100`-------------------------------------------------------------------*/
1101
1102static void
79282c5a 1103copy_guard (symbol_list *rule, int stack_offset)
a70083a3
AD
1104{
1105 int c;
a70083a3 1106 int count;
a70083a3
AD
1107 int brace_flag = 0;
1108
1109 /* offset is always 0 if parser has already popped the stack pointer */
1110 if (semantic_parser)
1111 stack_offset = 0;
1112
ea5607fd 1113 obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
89cab50d 1114 if (!no_lines_flag)
ea5607fd
AD
1115 obstack_fgrow2 (&guard_obstack, "#line %d %s\n",
1116 lineno, quotearg_style (c_quoting_style, infile));
1117 obstack_1grow (&guard_obstack, '{');
a70083a3
AD
1118
1119 count = 0;
1120 c = getc (finput);
1121
1122 while (brace_flag ? (count > 0) : (c != ';'))
1123 {
1124 switch (c)
1125 {
1126 case '\n':
ea5607fd 1127 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1128 lineno++;
1129 break;
1130
1131 case '{':
ea5607fd 1132 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1133 brace_flag = 1;
1134 count++;
1135 break;
1136
1137 case '}':
ea5607fd 1138 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1139 if (count > 0)
1140 count--;
1141 else
1142 {
1143 complain (_("unmatched %s"), "`}'");
1144 c = getc (finput); /* skip it */
1145 }
1146 break;
1147
1148 case '\'':
1149 case '"':
337bab46 1150 copy_string (finput, &guard_obstack, c);
a70083a3
AD
1151 break;
1152
1153 case '/':
337bab46 1154 copy_comment (finput, &guard_obstack);
a70083a3
AD
1155 break;
1156
1157 case '$':
337bab46 1158 copy_dollar (finput, &guard_obstack, rule, stack_offset);
a70083a3 1159 break;
1ff442ca 1160
a70083a3 1161 case '@':
337bab46 1162 copy_at (finput, &guard_obstack, stack_offset);
a70083a3 1163 break;
1ff442ca 1164
a70083a3
AD
1165 case EOF:
1166 fatal ("%s", _("unterminated %guard clause"));
1ff442ca 1167
a70083a3 1168 default:
ea5607fd 1169 obstack_1grow (&guard_obstack, c);
1ff442ca 1170 }
a70083a3
AD
1171
1172 if (c != '}' || count != 0)
1173 c = getc (finput);
1ff442ca
NF
1174 }
1175
a70083a3
AD
1176 c = skip_white_space ();
1177
ff4423cc 1178 obstack_sgrow (&guard_obstack, ";\n break;}");
a70083a3
AD
1179 if (c == '{')
1180 copy_action (rule, stack_offset);
1181 else if (c == '=')
1182 {
1183 c = getc (finput); /* why not skip_white_space -wjh */
1184 if (c == '{')
1185 copy_action (rule, stack_offset);
1186 }
1187 else
1188 ungetc (c, finput);
1ff442ca 1189}
a70083a3
AD
1190\f
1191
1192static void
1193record_rule_line (void)
1194{
1195 /* Record each rule's source line number in rline table. */
1ff442ca 1196
a70083a3
AD
1197 if (nrules >= rline_allocated)
1198 {
1199 rline_allocated = nrules * 2;
d7913476 1200 rline = XREALLOC (rline, short, rline_allocated);
a70083a3
AD
1201 }
1202 rline[nrules] = lineno;
1203}
1ff442ca
NF
1204
1205
a70083a3
AD
1206/*-------------------------------------------------------------------.
1207| Generate a dummy symbol, a nonterminal, whose name cannot conflict |
1208| with the user's names. |
1209`-------------------------------------------------------------------*/
1ff442ca 1210
4a120d45 1211static bucket *
118fb205 1212gensym (void)
1ff442ca 1213{
274d42ce
AD
1214 /* Incremented for each generated symbol */
1215 static int gensym_count = 0;
1216 static char buf[256];
1217
a70083a3 1218 bucket *sym;
1ff442ca 1219
274d42ce
AD
1220 sprintf (buf, "@%d", ++gensym_count);
1221 token_buffer = buf;
a70083a3 1222 sym = getsym (token_buffer);
d7020c20 1223 sym->class = nterm_sym;
1ff442ca 1224 sym->value = nvars++;
36281465 1225 return sym;
1ff442ca
NF
1226}
1227
a70083a3
AD
1228#if 0
1229/*------------------------------------------------------------------.
1230| read in a %type declaration and record its information for |
1231| get_type_name to access. This is unused. It is only called from |
1232| the #if 0 part of readgram |
1233`------------------------------------------------------------------*/
1234
1235static int
1236get_type (void)
1237{
1238 int k;
f17bcd1f 1239 token_t token;
a70083a3
AD
1240 char *name;
1241
f17bcd1f 1242 token = lex ();
a70083a3 1243
f17bcd1f 1244 if (token != tok_typename)
a70083a3
AD
1245 {
1246 complain (_("invalid %s declaration"), "%type");
1247 return t;
1248 }
1249
95e36146 1250 name = xstrdup (token_buffer);
a70083a3
AD
1251
1252 for (;;)
1253 {
f17bcd1f 1254 token = lex ();
a70083a3 1255
f17bcd1f 1256 switch (token)
a70083a3 1257 {
511e79b3 1258 case tok_semicolon:
a70083a3
AD
1259 return lex ();
1260
511e79b3 1261 case tok_comma:
a70083a3
AD
1262 break;
1263
511e79b3 1264 case tok_identifier:
a70083a3
AD
1265 if (symval->type_name == NULL)
1266 symval->type_name = name;
1267 else if (strcmp (name, symval->type_name) != 0)
1268 complain (_("type redeclaration for %s"), symval->tag);
1269
1270 break;
1271
1272 default:
f17bcd1f 1273 return token;
a70083a3
AD
1274 }
1275 }
1276}
1ff442ca 1277
a70083a3
AD
1278#endif
1279\f
1280/*------------------------------------------------------------------.
1281| Parse the input grammar into a one symbol_list structure. Each |
1282| rule is represented by a sequence of symbols: the left hand side |
1283| followed by the contents of the right hand side, followed by a |
1284| null pointer instead of a symbol to terminate the rule. The next |
1285| symbol is the lhs of the following rule. |
1286| |
1287| All guards and actions are copied out to the appropriate files, |
1288| labelled by the rule number they apply to. |
1289`------------------------------------------------------------------*/
1ff442ca 1290
4a120d45 1291static void
118fb205 1292readgram (void)
1ff442ca 1293{
f17bcd1f 1294 token_t t;
a70083a3
AD
1295 bucket *lhs = NULL;
1296 symbol_list *p;
1297 symbol_list *p1;
1298 bucket *bp;
1ff442ca 1299
ff4a34be
AD
1300 /* Points to first symbol_list of current rule. its symbol is the
1301 lhs of the rule. */
1302 symbol_list *crule;
1303 /* Points to the symbol_list preceding crule. */
1304 symbol_list *crule1;
1ff442ca
NF
1305
1306 p1 = NULL;
1307
a70083a3 1308 t = lex ();
1ff442ca 1309
511e79b3 1310 while (t != tok_two_percents && t != tok_eof)
1ff442ca 1311 {
511e79b3 1312 if (t == tok_identifier || t == tok_bar)
1ff442ca 1313 {
89cab50d 1314 int action_flag = 0;
ff4a34be
AD
1315 /* Number of symbols in rhs of this rule so far */
1316 int rulelength = 0;
1ff442ca
NF
1317 int xactions = 0; /* JF for error checking */
1318 bucket *first_rhs = 0;
1319
511e79b3 1320 if (t == tok_identifier)
1ff442ca
NF
1321 {
1322 lhs = symval;
943819bf
RS
1323
1324 if (!start_flag)
1325 {
1326 startval = lhs;
1327 start_flag = 1;
1328 }
a083fbbf 1329
a70083a3 1330 t = lex ();
511e79b3 1331 if (t != tok_colon)
943819bf 1332 {
a0f6b076 1333 complain (_("ill-formed rule: initial symbol not followed by colon"));
a70083a3 1334 unlex (t);
943819bf 1335 }
1ff442ca
NF
1336 }
1337
511e79b3 1338 if (nrules == 0 && t == tok_bar)
1ff442ca 1339 {
a0f6b076 1340 complain (_("grammar starts with vertical bar"));
943819bf 1341 lhs = symval; /* BOGUS: use a random symval */
1ff442ca 1342 }
1ff442ca
NF
1343 /* start a new rule and record its lhs. */
1344
1345 nrules++;
1346 nitems++;
1347
1348 record_rule_line ();
1349
d7913476 1350 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1351 p->sym = lhs;
1352
1353 crule1 = p1;
1354 if (p1)
1355 p1->next = p;
1356 else
1357 grammar = p;
1358
1359 p1 = p;
1360 crule = p;
1361
1362 /* mark the rule's lhs as a nonterminal if not already so. */
1363
d7020c20 1364 if (lhs->class == unknown_sym)
1ff442ca 1365 {
d7020c20 1366 lhs->class = nterm_sym;
1ff442ca
NF
1367 lhs->value = nvars;
1368 nvars++;
1369 }
d7020c20 1370 else if (lhs->class == token_sym)
a0f6b076 1371 complain (_("rule given for %s, which is a token"), lhs->tag);
1ff442ca
NF
1372
1373 /* read the rhs of the rule. */
1374
1375 for (;;)
1376 {
a70083a3 1377 t = lex ();
511e79b3 1378 if (t == tok_prec)
943819bf 1379 {
a70083a3 1380 t = lex ();
943819bf 1381 crule->ruleprec = symval;
a70083a3 1382 t = lex ();
943819bf 1383 }
1ff442ca 1384
511e79b3 1385 if (!(t == tok_identifier || t == tok_left_curly))
a70083a3 1386 break;
1ff442ca
NF
1387
1388 /* If next token is an identifier, see if a colon follows it.
a70083a3 1389 If one does, exit this rule now. */
511e79b3 1390 if (t == tok_identifier)
1ff442ca 1391 {
a70083a3 1392 bucket *ssave;
f17bcd1f 1393 token_t t1;
1ff442ca
NF
1394
1395 ssave = symval;
a70083a3
AD
1396 t1 = lex ();
1397 unlex (t1);
1ff442ca 1398 symval = ssave;
511e79b3 1399 if (t1 == tok_colon)
a70083a3 1400 break;
1ff442ca 1401
a70083a3 1402 if (!first_rhs) /* JF */
1ff442ca
NF
1403 first_rhs = symval;
1404 /* Not followed by colon =>
1405 process as part of this rule's rhs. */
1406 }
1407
1408 /* If we just passed an action, that action was in the middle
a70083a3
AD
1409 of a rule, so make a dummy rule to reduce it to a
1410 non-terminal. */
89cab50d 1411 if (action_flag)
1ff442ca 1412 {
a70083a3 1413 bucket *sdummy;
1ff442ca 1414
f282676b
AD
1415 /* Since the action was written out with this rule's
1416 number, we must give the new rule this number by
1417 inserting the new rule before it. */
1ff442ca
NF
1418
1419 /* Make a dummy nonterminal, a gensym. */
a70083a3 1420 sdummy = gensym ();
1ff442ca
NF
1421
1422 /* Make a new rule, whose body is empty,
1423 before the current one, so that the action
1424 just read can belong to it. */
1425 nrules++;
1426 nitems++;
1427 record_rule_line ();
d7913476 1428 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1429 if (crule1)
1430 crule1->next = p;
a70083a3
AD
1431 else
1432 grammar = p;
1ff442ca 1433 p->sym = sdummy;
d7913476 1434 crule1 = XCALLOC (symbol_list, 1);
1ff442ca
NF
1435 p->next = crule1;
1436 crule1->next = crule;
1437
f282676b
AD
1438 /* Insert the dummy generated by that rule into this
1439 rule. */
1ff442ca 1440 nitems++;
d7913476 1441 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1442 p->sym = sdummy;
1443 p1->next = p;
1444 p1 = p;
1445
89cab50d 1446 action_flag = 0;
1ff442ca
NF
1447 }
1448
511e79b3 1449 if (t == tok_identifier)
1ff442ca
NF
1450 {
1451 nitems++;
d7913476 1452 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1453 p->sym = symval;
1454 p1->next = p;
1455 p1 = p;
1456 }
a70083a3 1457 else /* handle an action. */
1ff442ca 1458 {
a70083a3 1459 copy_action (crule, rulelength);
89cab50d 1460 action_flag = 1;
1ff442ca
NF
1461 xactions++; /* JF */
1462 }
1463 rulelength++;
a70083a3 1464 } /* end of read rhs of rule */
1ff442ca
NF
1465
1466 /* Put an empty link in the list to mark the end of this rule */
d7913476 1467 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1468 p1->next = p;
1469 p1 = p;
1470
511e79b3 1471 if (t == tok_prec)
1ff442ca 1472 {
a0f6b076 1473 complain (_("two @prec's in a row"));
a70083a3 1474 t = lex ();
1ff442ca 1475 crule->ruleprec = symval;
a70083a3 1476 t = lex ();
1ff442ca 1477 }
511e79b3 1478 if (t == tok_guard)
1ff442ca 1479 {
a70083a3 1480 if (!semantic_parser)
ff4a34be 1481 complain (_("%%guard present but %%semantic_parser not specified"));
1ff442ca 1482
a70083a3
AD
1483 copy_guard (crule, rulelength);
1484 t = lex ();
1ff442ca 1485 }
511e79b3 1486 else if (t == tok_left_curly)
1ff442ca 1487 {
a70083a3 1488 /* This case never occurs -wjh */
89cab50d 1489 if (action_flag)
a0f6b076 1490 complain (_("two actions at end of one rule"));
a70083a3 1491 copy_action (crule, rulelength);
89cab50d 1492 action_flag = 1;
943819bf 1493 xactions++; /* -wjh */
a70083a3 1494 t = lex ();
1ff442ca 1495 }
a0f6b076 1496 /* If $$ is being set in default way, report if any type
6666f98f
AD
1497 mismatch. */
1498 else if (!xactions
a70083a3 1499 && first_rhs && lhs->type_name != first_rhs->type_name)
1ff442ca 1500 {
6666f98f
AD
1501 if (lhs->type_name == 0
1502 || first_rhs->type_name == 0
a70083a3 1503 || strcmp (lhs->type_name, first_rhs->type_name))
a0f6b076
AD
1504 complain (_("type clash (`%s' `%s') on default action"),
1505 lhs->type_name ? lhs->type_name : "",
a70083a3 1506 first_rhs->type_name ? first_rhs->type_name : "");
1ff442ca
NF
1507 }
1508 /* Warn if there is no default for $$ but we need one. */
1509 else if (!xactions && !first_rhs && lhs->type_name != 0)
a0f6b076 1510 complain (_("empty rule for typed nonterminal, and no action"));
511e79b3 1511 if (t == tok_semicolon)
a70083a3 1512 t = lex ();
a083fbbf 1513 }
943819bf 1514#if 0
a70083a3 1515 /* these things can appear as alternatives to rules. */
943819bf
RS
1516/* NO, they cannot.
1517 a) none of the documentation allows them
1518 b) most of them scan forward until finding a next %
1519 thus they may swallow lots of intervening rules
1520*/
511e79b3 1521 else if (t == tok_token)
1ff442ca 1522 {
d7020c20 1523 parse_token_decl (token_sym, nterm_sym);
a70083a3 1524 t = lex ();
1ff442ca 1525 }
511e79b3 1526 else if (t == tok_nterm)
1ff442ca 1527 {
d7020c20 1528 parse_token_decl (nterm_sym, token_sym);
a70083a3 1529 t = lex ();
1ff442ca 1530 }
511e79b3 1531 else if (t == tok_type)
1ff442ca 1532 {
a70083a3 1533 t = get_type ();
1ff442ca 1534 }
511e79b3 1535 else if (t == tok_union)
1ff442ca 1536 {
a70083a3
AD
1537 parse_union_decl ();
1538 t = lex ();
1ff442ca 1539 }
511e79b3 1540 else if (t == tok_expect)
1ff442ca 1541 {
a70083a3
AD
1542 parse_expect_decl ();
1543 t = lex ();
1ff442ca 1544 }
511e79b3 1545 else if (t == tok_start)
1ff442ca 1546 {
a70083a3
AD
1547 parse_start_decl ();
1548 t = lex ();
1ff442ca 1549 }
943819bf
RS
1550#endif
1551
1ff442ca 1552 else
943819bf 1553 {
d01c415b 1554 complain (_("invalid input: %s"), quote (token_buffer));
a70083a3 1555 t = lex ();
943819bf 1556 }
1ff442ca
NF
1557 }
1558
943819bf
RS
1559 /* grammar has been read. Do some checking */
1560
1ff442ca 1561 if (nsyms > MAXSHORT)
a0f6b076
AD
1562 fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
1563 MAXSHORT);
1ff442ca 1564 if (nrules == 0)
a0f6b076 1565 fatal (_("no rules in the input grammar"));
1ff442ca 1566
ff4a34be
AD
1567 /* JF put out same default YYSTYPE as YACC does */
1568 if (typed == 0
1ff442ca
NF
1569 && !value_components_used)
1570 {
1571 /* We used to use `unsigned long' as YYSTYPE on MSDOS,
a70083a3
AD
1572 but it seems better to be consistent.
1573 Most programs should declare their own type anyway. */
ff4423cc 1574 obstack_sgrow (&attrs_obstack,
573c1d9f 1575 "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
896fe5c1 1576 if (defines_flag)
ff4423cc 1577 obstack_sgrow (&defines_obstack, "\
896fe5c1
AD
1578#ifndef YYSTYPE\n\
1579# define YYSTYPE int\n\
1580#endif\n");
1ff442ca
NF
1581 }
1582
1583 /* Report any undefined symbols and consider them nonterminals. */
1584
1585 for (bp = firstsymbol; bp; bp = bp->next)
d7020c20 1586 if (bp->class == unknown_sym)
1ff442ca 1587 {
a70083a3
AD
1588 complain (_
1589 ("symbol %s is used, but is not defined as a token and has no rules"),
ff4a34be 1590 bp->tag);
d7020c20 1591 bp->class = nterm_sym;
1ff442ca
NF
1592 bp->value = nvars++;
1593 }
1594
1595 ntokens = nsyms - nvars;
1596}
a70083a3
AD
1597\f
1598/*--------------------------------------------------------------.
1599| For named tokens, but not literal ones, define the name. The |
1600| value is the user token number. |
1601`--------------------------------------------------------------*/
1ff442ca 1602
4a120d45 1603static void
896fe5c1 1604output_token_defines (struct obstack *oout)
1ff442ca 1605{
a70083a3
AD
1606 bucket *bp;
1607 char *cp, *symbol;
1608 char c;
1ff442ca 1609
a70083a3 1610 for (bp = firstsymbol; bp; bp = bp->next)
1ff442ca 1611 {
a70083a3
AD
1612 symbol = bp->tag; /* get symbol */
1613
1614 if (bp->value >= ntokens)
1615 continue;
1616 if (bp->user_token_number == SALIAS)
1617 continue;
1618 if ('\'' == *symbol)
1619 continue; /* skip literal character */
1620 if (bp == errtoken)
1621 continue; /* skip error token */
1622 if ('\"' == *symbol)
1ff442ca 1623 {
a70083a3
AD
1624 /* use literal string only if given a symbol with an alias */
1625 if (bp->alias)
1626 symbol = bp->alias->tag;
1627 else
1628 continue;
1629 }
1ff442ca 1630
a70083a3
AD
1631 /* Don't #define nonliteral tokens whose names contain periods. */
1632 cp = symbol;
1633 while ((c = *cp++) && c != '.');
1634 if (c != '\0')
1635 continue;
1ff442ca 1636
896fe5c1
AD
1637 obstack_fgrow2 (oout, "#define\t%s\t%d\n",
1638 symbol,
62ab6972 1639 (translations ? bp->user_token_number : bp->value));
a70083a3 1640 if (semantic_parser)
896fe5c1 1641 obstack_fgrow2 (oout, "#define\tT%s\t%d\n", symbol, bp->value);
1ff442ca 1642 }
a70083a3 1643
896fe5c1 1644 obstack_1grow (oout, '\n');
1ff442ca 1645}
1ff442ca
NF
1646
1647
a70083a3
AD
1648/*------------------------------------------------------------------.
1649| Assign symbol numbers, and write definition of token names into |
b2ca4022 1650| FDEFINES. Set up vectors TAGS and SPREC of names and precedences |
a70083a3
AD
1651| of symbols. |
1652`------------------------------------------------------------------*/
1ff442ca 1653
4a120d45 1654static void
118fb205 1655packsymbols (void)
1ff442ca 1656{
a70083a3
AD
1657 bucket *bp;
1658 int tokno = 1;
1659 int i;
1660 int last_user_token_number;
4a120d45 1661 static char DOLLAR[] = "$";
1ff442ca
NF
1662
1663 /* int lossage = 0; JF set but not used */
1664
d7913476 1665 tags = XCALLOC (char *, nsyms + 1);
4a120d45 1666 tags[0] = DOLLAR;
d7913476 1667 user_toknums = XCALLOC (short, nsyms + 1);
943819bf 1668 user_toknums[0] = 0;
1ff442ca 1669
d7913476
AD
1670 sprec = XCALLOC (short, nsyms);
1671 sassoc = XCALLOC (short, nsyms);
1ff442ca
NF
1672
1673 max_user_token_number = 256;
1674 last_user_token_number = 256;
1675
1676 for (bp = firstsymbol; bp; bp = bp->next)
1677 {
d7020c20 1678 if (bp->class == nterm_sym)
1ff442ca
NF
1679 {
1680 bp->value += ntokens;
1681 }
943819bf
RS
1682 else if (bp->alias)
1683 {
0a6384c4
AD
1684 /* this symbol and its alias are a single token defn.
1685 allocate a tokno, and assign to both check agreement of
1686 ->prec and ->assoc fields and make both the same */
1687 if (bp->value == 0)
1688 bp->value = bp->alias->value = tokno++;
943819bf 1689
0a6384c4
AD
1690 if (bp->prec != bp->alias->prec)
1691 {
1692 if (bp->prec != 0 && bp->alias->prec != 0
1693 && bp->user_token_number == SALIAS)
a0f6b076
AD
1694 complain (_("conflicting precedences for %s and %s"),
1695 bp->tag, bp->alias->tag);
0a6384c4
AD
1696 if (bp->prec != 0)
1697 bp->alias->prec = bp->prec;
1698 else
1699 bp->prec = bp->alias->prec;
1700 }
943819bf 1701
0a6384c4
AD
1702 if (bp->assoc != bp->alias->assoc)
1703 {
a0f6b076
AD
1704 if (bp->assoc != 0 && bp->alias->assoc != 0
1705 && bp->user_token_number == SALIAS)
1706 complain (_("conflicting assoc values for %s and %s"),
1707 bp->tag, bp->alias->tag);
1708 if (bp->assoc != 0)
1709 bp->alias->assoc = bp->assoc;
1710 else
1711 bp->assoc = bp->alias->assoc;
1712 }
0a6384c4
AD
1713
1714 if (bp->user_token_number == SALIAS)
a70083a3 1715 continue; /* do not do processing below for SALIASs */
943819bf 1716
a70083a3 1717 }
d7020c20 1718 else /* bp->class == token_sym */
943819bf
RS
1719 {
1720 bp->value = tokno++;
1721 }
1722
d7020c20 1723 if (bp->class == token_sym)
1ff442ca
NF
1724 {
1725 if (translations && !(bp->user_token_number))
1726 bp->user_token_number = ++last_user_token_number;
1727 if (bp->user_token_number > max_user_token_number)
1728 max_user_token_number = bp->user_token_number;
1ff442ca
NF
1729 }
1730
1731 tags[bp->value] = bp->tag;
943819bf 1732 user_toknums[bp->value] = bp->user_token_number;
1ff442ca
NF
1733 sprec[bp->value] = bp->prec;
1734 sassoc[bp->value] = bp->assoc;
1735
1736 }
1737
1738 if (translations)
1739 {
a70083a3 1740 int j;
1ff442ca 1741
d7913476 1742 token_translations = XCALLOC (short, max_user_token_number + 1);
1ff442ca 1743
0a6384c4 1744 /* initialize all entries for literal tokens to 2, the internal
a70083a3
AD
1745 token number for $undefined., which represents all invalid
1746 inputs. */
4a120d45 1747 for (j = 0; j <= max_user_token_number; j++)
a70083a3 1748 token_translations[j] = 2;
1ff442ca 1749
943819bf 1750 for (bp = firstsymbol; bp; bp = bp->next)
a70083a3
AD
1751 {
1752 if (bp->value >= ntokens)
1753 continue; /* non-terminal */
1754 if (bp->user_token_number == SALIAS)
0a6384c4 1755 continue;
a70083a3 1756 if (token_translations[bp->user_token_number] != 2)
a0f6b076
AD
1757 complain (_("tokens %s and %s both assigned number %d"),
1758 tags[token_translations[bp->user_token_number]],
a70083a3
AD
1759 bp->tag, bp->user_token_number);
1760 token_translations[bp->user_token_number] = bp->value;
1761 }
1ff442ca
NF
1762 }
1763
1764 error_token_number = errtoken->value;
1765
89cab50d 1766 if (!no_parser_flag)
896fe5c1 1767 output_token_defines (&table_obstack);
1ff442ca 1768
d7020c20 1769 if (startval->class == unknown_sym)
a0f6b076 1770 fatal (_("the start symbol %s is undefined"), startval->tag);
d7020c20 1771 else if (startval->class == token_sym)
a0f6b076 1772 fatal (_("the start symbol %s is a token"), startval->tag);
1ff442ca
NF
1773
1774 start_symbol = startval->value;
1775
89cab50d 1776 if (defines_flag)
1ff442ca 1777 {
896fe5c1 1778 output_token_defines (&defines_obstack);
1ff442ca
NF
1779
1780 if (!pure_parser)
1781 {
1782 if (spec_name_prefix)
896fe5c1
AD
1783 obstack_fgrow1 (&defines_obstack, "\nextern YYSTYPE %slval;\n",
1784 spec_name_prefix);
1ff442ca 1785 else
ff4423cc 1786 obstack_sgrow (&defines_obstack,
573c1d9f 1787 "\nextern YYSTYPE yylval;\n");
1ff442ca
NF
1788 }
1789
1790 if (semantic_parser)
1791 for (i = ntokens; i < nsyms; i++)
1792 {
1793 /* don't make these for dummy nonterminals made by gensym. */
1794 if (*tags[i] != '@')
896fe5c1
AD
1795 obstack_fgrow2 (&defines_obstack,
1796 "#define\tNT%s\t%d\n", tags[i], i);
1ff442ca
NF
1797 }
1798#if 0
1799 /* `fdefines' is now a temporary file, so we need to copy its
1800 contents in `done', so we can't close it here. */
a70083a3 1801 fclose (fdefines);
1ff442ca
NF
1802 fdefines = NULL;
1803#endif
1804 }
1805}
a083fbbf 1806
1ff442ca 1807
a70083a3
AD
1808/*---------------------------------------------------------------.
1809| Convert the rules into the representation using RRHS, RLHS and |
1810| RITEMS. |
1811`---------------------------------------------------------------*/
1ff442ca 1812
4a120d45 1813static void
118fb205 1814packgram (void)
1ff442ca 1815{
a70083a3
AD
1816 int itemno;
1817 int ruleno;
1818 symbol_list *p;
1ff442ca
NF
1819
1820 bucket *ruleprec;
1821
d7913476
AD
1822 ritem = XCALLOC (short, nitems + 1);
1823 rlhs = XCALLOC (short, nrules) - 1;
1824 rrhs = XCALLOC (short, nrules) - 1;
1825 rprec = XCALLOC (short, nrules) - 1;
1826 rprecsym = XCALLOC (short, nrules) - 1;
1827 rassoc = XCALLOC (short, nrules) - 1;
1ff442ca
NF
1828
1829 itemno = 0;
1830 ruleno = 1;
1831
1832 p = grammar;
1833 while (p)
1834 {
1835 rlhs[ruleno] = p->sym->value;
1836 rrhs[ruleno] = itemno;
1837 ruleprec = p->ruleprec;
1838
1839 p = p->next;
1840 while (p && p->sym)
1841 {
1842 ritem[itemno++] = p->sym->value;
1843 /* A rule gets by default the precedence and associativity
1844 of the last token in it. */
d7020c20 1845 if (p->sym->class == token_sym)
1ff442ca
NF
1846 {
1847 rprec[ruleno] = p->sym->prec;
1848 rassoc[ruleno] = p->sym->assoc;
1849 }
a70083a3
AD
1850 if (p)
1851 p = p->next;
1ff442ca
NF
1852 }
1853
1854 /* If this rule has a %prec,
a70083a3 1855 the specified symbol's precedence replaces the default. */
1ff442ca
NF
1856 if (ruleprec)
1857 {
a70083a3
AD
1858 rprec[ruleno] = ruleprec->prec;
1859 rassoc[ruleno] = ruleprec->assoc;
1ff442ca
NF
1860 rprecsym[ruleno] = ruleprec->value;
1861 }
1862
1863 ritem[itemno++] = -ruleno;
1864 ruleno++;
1865
a70083a3
AD
1866 if (p)
1867 p = p->next;
1ff442ca
NF
1868 }
1869
1870 ritem[itemno] = 0;
1871}
a70083a3
AD
1872\f
1873/*-------------------------------------------------------------------.
1874| Read in the grammar specification and record it in the format |
ea5607fd 1875| described in gram.h. All guards are copied into the GUARD_OBSTACK |
8c7ebe49
AD
1876| and all actions into ACTION_OBSTACK, in each case forming the body |
1877| of a C function (YYGUARD or YYACTION) which contains a switch |
1878| statement to decide which guard or action to execute. |
a70083a3
AD
1879`-------------------------------------------------------------------*/
1880
1881void
1882reader (void)
1883{
1884 start_flag = 0;
1885 startval = NULL; /* start symbol not specified yet. */
1886
1887#if 0
1888 /* initially assume token number translation not needed. */
1889 translations = 0;
1890#endif
1891 /* Nowadays translations is always set to 1, since we give `error' a
1892 user-token-number to satisfy the Posix demand for YYERRCODE==256.
1893 */
1894 translations = 1;
1895
1896 nsyms = 1;
1897 nvars = 0;
1898 nrules = 0;
1899 nitems = 0;
1900 rline_allocated = 10;
d7913476 1901 rline = XCALLOC (short, rline_allocated);
a70083a3
AD
1902
1903 typed = 0;
1904 lastprec = 0;
1905
a70083a3
AD
1906 semantic_parser = 0;
1907 pure_parser = 0;
a70083a3
AD
1908
1909 grammar = NULL;
1910
1911 init_lex ();
1912 lineno = 1;
1913
1914 /* Initialize the symbol table. */
1915 tabinit ();
1916 /* Construct the error token */
1917 errtoken = getsym ("error");
d7020c20 1918 errtoken->class = token_sym;
a70083a3
AD
1919 errtoken->user_token_number = 256; /* Value specified by POSIX. */
1920 /* Construct a token that represents all undefined literal tokens.
1921 It is always token number 2. */
1922 undeftoken = getsym ("$undefined.");
d7020c20 1923 undeftoken->class = token_sym;
a70083a3
AD
1924 undeftoken->user_token_number = 2;
1925
896fe5c1
AD
1926 /* Read the declaration section. Copy %{ ... %} groups to
1927 TABLE_OBSTACK and FDEFINES file. Also notice any %token, %left,
1928 etc. found there. */
1929 obstack_1grow (&table_obstack, '\n');
1930 obstack_fgrow3 (&table_obstack, "\
a70083a3
AD
1931/* %s, made from %s\n\
1932 by GNU bison %s. */\n\
896fe5c1
AD
1933\n",
1934 no_parser_flag ? "Bison-generated parse tables" : "A Bison parser",
1935 infile, VERSION);
a70083a3 1936
ff4423cc 1937 obstack_sgrow (&table_obstack,
896fe5c1 1938 "#define YYBISON 1 /* Identify Bison output. */\n\n");
a70083a3
AD
1939 read_declarations ();
1940 /* Start writing the guard and action files, if they are needed. */
1941 output_headers ();
1942 /* Read in the grammar, build grammar in list form. Write out
1943 guards and actions. */
1944 readgram ();
1945 /* Now we know whether we need the line-number stack. If we do,
1946 write its type into the .tab.h file. */
896fe5c1
AD
1947 if (defines_flag)
1948 reader_output_yylsp (&defines_obstack);
a70083a3
AD
1949 /* Write closing delimiters for actions and guards. */
1950 output_trailers ();
89cab50d 1951 if (locations_flag)
ff4423cc 1952 obstack_sgrow (&table_obstack, "#define YYLSP_NEEDED 1\n\n");
a70083a3
AD
1953 /* Assign the symbols their symbol numbers. Write #defines for the
1954 token symbols into FDEFINES if requested. */
1955 packsymbols ();
1956 /* Convert the grammar into the format described in gram.h. */
1957 packgram ();
1958 /* Free the symbol table data structure since symbols are now all
1959 referred to by symbol number. */
1960 free_symtab ();
1961}
1962
d7020c20 1963
3abcd459
AD
1964/*------------------------------------------------------------------.
1965| Define YYLTYPE. Cannot be in the skeleton since we might have to |
1966| output it in the headers if --defines is used. |
1967`------------------------------------------------------------------*/
1968
a70083a3 1969void
896fe5c1 1970reader_output_yylsp (struct obstack *oout)
a70083a3 1971{
89cab50d 1972 if (locations_flag)
ff4423cc 1973 obstack_sgrow (oout, "\
d7020c20
AD
1974\n\
1975#ifndef YYLTYPE\n\
89cab50d
AD
1976typedef struct yyltype\n\
1977{\n\
89cab50d 1978 int first_line;\n\
3abcd459 1979 int first_column;\n\
d7020c20 1980\n\
89cab50d
AD
1981 int last_line;\n\
1982 int last_column;\n\
89cab50d 1983} yyltype;\n\
d7020c20 1984\n\
89cab50d 1985# define YYLTYPE yyltype\n\
d7020c20 1986#endif\n\
896fe5c1 1987\n");
a70083a3 1988}