]> git.saurik.com Git - bison.git/blame - src/reader.c
* src/getargs.c, src/getarg.h (skeleton)): Constify.
[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
d7020c20 877
a70083a3
AD
878/*----------------------------------------------------------------.
879| Read from finput until `%%' is seen. Discard the `%%'. Handle |
880| any `%' declarations, and copy the contents of any `%{ ... %}' |
dd60faec 881| groups to ATTRS_OBSTACK. |
a70083a3 882`----------------------------------------------------------------*/
1ff442ca 883
4a120d45 884static void
a70083a3 885read_declarations (void)
1ff442ca 886{
a70083a3
AD
887 int c;
888 int tok;
1ff442ca 889
a70083a3 890 for (;;)
1ff442ca 891 {
a70083a3 892 c = skip_white_space ();
1ff442ca 893
a70083a3
AD
894 if (c == '%')
895 {
896 tok = parse_percent_token ();
1ff442ca 897
a70083a3 898 switch (tok)
943819bf 899 {
511e79b3 900 case tok_two_percents:
a70083a3 901 return;
1ff442ca 902
511e79b3 903 case tok_percent_left_curly:
a70083a3
AD
904 copy_definition ();
905 break;
1ff442ca 906
511e79b3 907 case tok_token:
d7020c20 908 parse_token_decl (token_sym, nterm_sym);
a70083a3 909 break;
1ff442ca 910
511e79b3 911 case tok_nterm:
d7020c20 912 parse_token_decl (nterm_sym, token_sym);
a70083a3 913 break;
1ff442ca 914
511e79b3 915 case tok_type:
a70083a3
AD
916 parse_type_decl ();
917 break;
1ff442ca 918
511e79b3 919 case tok_start:
a70083a3
AD
920 parse_start_decl ();
921 break;
118fb205 922
511e79b3 923 case tok_union:
a70083a3
AD
924 parse_union_decl ();
925 break;
1ff442ca 926
511e79b3 927 case tok_expect:
a70083a3
AD
928 parse_expect_decl ();
929 break;
6deb4447 930
511e79b3 931 case tok_thong:
a70083a3
AD
932 parse_thong_decl ();
933 break;
d7020c20 934
511e79b3 935 case tok_left:
d7020c20 936 parse_assoc_decl (left_assoc);
a70083a3 937 break;
1ff442ca 938
511e79b3 939 case tok_right:
d7020c20 940 parse_assoc_decl (right_assoc);
a70083a3 941 break;
1ff442ca 942
511e79b3 943 case tok_nonassoc:
d7020c20 944 parse_assoc_decl (non_assoc);
a70083a3 945 break;
1ff442ca 946
511e79b3 947 case tok_noop:
a70083a3 948 break;
1ff442ca 949
a70083a3
AD
950 default:
951 complain (_("unrecognized: %s"), token_buffer);
952 skip_to_char ('%');
953 }
954 }
955 else if (c == EOF)
956 fatal (_("no input grammar"));
957 else
958 {
ff4a34be
AD
959 char buf[] = "c";
960 buf[0] = c;
961 complain (_("unknown character: %s"), quote (buf));
a70083a3 962 skip_to_char ('%');
1ff442ca 963 }
1ff442ca 964 }
1ff442ca 965}
a70083a3
AD
966\f
967/*-------------------------------------------------------------------.
968| Assuming that a `{' has just been seen, copy everything up to the |
969| matching `}' into the actions file. STACK_OFFSET is the number of |
970| values in the current rule so far, which says where to find `$0' |
971| with respect to the top of the stack. |
972`-------------------------------------------------------------------*/
1ff442ca 973
4a120d45 974static void
79282c5a 975copy_action (symbol_list *rule, int stack_offset)
1ff442ca 976{
a70083a3 977 int c;
a70083a3 978 int count;
8c7ebe49 979 char buf[4096];
1ff442ca
NF
980
981 /* offset is always 0 if parser has already popped the stack pointer */
41aca2e0
AD
982 if (semantic_parser)
983 stack_offset = 0;
1ff442ca 984
8c7ebe49
AD
985 sprintf (buf, "\ncase %d:\n", nrules);
986 obstack_grow (&action_obstack, buf, strlen (buf));
987
89cab50d 988 if (!no_lines_flag)
8c7ebe49 989 {
2a91a95e
AD
990 sprintf (buf, "#line %d %s\n",
991 lineno, quotearg_style (c_quoting_style, infile));
8c7ebe49
AD
992 obstack_grow (&action_obstack, buf, strlen (buf));
993 }
994 obstack_1grow (&action_obstack, '{');
1ff442ca
NF
995
996 count = 1;
a70083a3 997 c = getc (finput);
1ff442ca
NF
998
999 while (count > 0)
1000 {
1001 while (c != '}')
a70083a3
AD
1002 {
1003 switch (c)
1ff442ca
NF
1004 {
1005 case '\n':
8c7ebe49 1006 obstack_1grow (&action_obstack, c);
1ff442ca
NF
1007 lineno++;
1008 break;
1009
1010 case '{':
8c7ebe49 1011 obstack_1grow (&action_obstack, c);
1ff442ca
NF
1012 count++;
1013 break;
1014
1015 case '\'':
1016 case '"':
337bab46 1017 copy_string (finput, &action_obstack, c);
1ff442ca
NF
1018 break;
1019
1020 case '/':
337bab46 1021 copy_comment (finput, &action_obstack);
1ff442ca
NF
1022 break;
1023
1024 case '$':
337bab46 1025 copy_dollar (finput, &action_obstack,
8c7ebe49 1026 rule, stack_offset);
1ff442ca
NF
1027 break;
1028
1029 case '@':
337bab46 1030 copy_at (finput, &action_obstack,
8c7ebe49 1031 stack_offset);
6666f98f 1032 break;
1ff442ca
NF
1033
1034 case EOF:
27821bff 1035 fatal (_("unmatched %s"), "`{'");
1ff442ca
NF
1036
1037 default:
8c7ebe49 1038 obstack_1grow (&action_obstack, c);
a70083a3
AD
1039 }
1040
1041 c = getc (finput);
1042 }
1043
1044 /* above loop exits when c is '}' */
1045
1046 if (--count)
1047 {
8c7ebe49 1048 obstack_1grow (&action_obstack, c);
a70083a3
AD
1049 c = getc (finput);
1050 }
1051 }
1052
ff4423cc 1053 obstack_sgrow (&action_obstack, ";\n break;}");
a70083a3
AD
1054}
1055\f
1056/*-------------------------------------------------------------------.
1057| After `%guard' is seen in the input file, copy the actual guard |
1058| into the guards file. If the guard is followed by an action, copy |
1059| that into the actions file. STACK_OFFSET is the number of values |
1060| in the current rule so far, which says where to find `$0' with |
1061| respect to the top of the stack, for the simple parser in which |
1062| the stack is not popped until after the guard is run. |
1063`-------------------------------------------------------------------*/
1064
1065static void
79282c5a 1066copy_guard (symbol_list *rule, int stack_offset)
a70083a3
AD
1067{
1068 int c;
a70083a3 1069 int count;
a70083a3
AD
1070 int brace_flag = 0;
1071
1072 /* offset is always 0 if parser has already popped the stack pointer */
1073 if (semantic_parser)
1074 stack_offset = 0;
1075
ea5607fd 1076 obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
89cab50d 1077 if (!no_lines_flag)
ea5607fd
AD
1078 obstack_fgrow2 (&guard_obstack, "#line %d %s\n",
1079 lineno, quotearg_style (c_quoting_style, infile));
1080 obstack_1grow (&guard_obstack, '{');
a70083a3
AD
1081
1082 count = 0;
1083 c = getc (finput);
1084
1085 while (brace_flag ? (count > 0) : (c != ';'))
1086 {
1087 switch (c)
1088 {
1089 case '\n':
ea5607fd 1090 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1091 lineno++;
1092 break;
1093
1094 case '{':
ea5607fd 1095 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1096 brace_flag = 1;
1097 count++;
1098 break;
1099
1100 case '}':
ea5607fd 1101 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1102 if (count > 0)
1103 count--;
1104 else
1105 {
1106 complain (_("unmatched %s"), "`}'");
1107 c = getc (finput); /* skip it */
1108 }
1109 break;
1110
1111 case '\'':
1112 case '"':
337bab46 1113 copy_string (finput, &guard_obstack, c);
a70083a3
AD
1114 break;
1115
1116 case '/':
337bab46 1117 copy_comment (finput, &guard_obstack);
a70083a3
AD
1118 break;
1119
1120 case '$':
337bab46 1121 copy_dollar (finput, &guard_obstack, rule, stack_offset);
a70083a3 1122 break;
1ff442ca 1123
a70083a3 1124 case '@':
337bab46 1125 copy_at (finput, &guard_obstack, stack_offset);
a70083a3 1126 break;
1ff442ca 1127
a70083a3
AD
1128 case EOF:
1129 fatal ("%s", _("unterminated %guard clause"));
1ff442ca 1130
a70083a3 1131 default:
ea5607fd 1132 obstack_1grow (&guard_obstack, c);
1ff442ca 1133 }
a70083a3
AD
1134
1135 if (c != '}' || count != 0)
1136 c = getc (finput);
1ff442ca
NF
1137 }
1138
a70083a3
AD
1139 c = skip_white_space ();
1140
ff4423cc 1141 obstack_sgrow (&guard_obstack, ";\n break;}");
a70083a3
AD
1142 if (c == '{')
1143 copy_action (rule, stack_offset);
1144 else if (c == '=')
1145 {
1146 c = getc (finput); /* why not skip_white_space -wjh */
1147 if (c == '{')
1148 copy_action (rule, stack_offset);
1149 }
1150 else
1151 ungetc (c, finput);
1ff442ca 1152}
a70083a3
AD
1153\f
1154
1155static void
1156record_rule_line (void)
1157{
1158 /* Record each rule's source line number in rline table. */
1ff442ca 1159
a70083a3
AD
1160 if (nrules >= rline_allocated)
1161 {
1162 rline_allocated = nrules * 2;
d7913476 1163 rline = XREALLOC (rline, short, rline_allocated);
a70083a3
AD
1164 }
1165 rline[nrules] = lineno;
1166}
1ff442ca
NF
1167
1168
a70083a3
AD
1169/*-------------------------------------------------------------------.
1170| Generate a dummy symbol, a nonterminal, whose name cannot conflict |
1171| with the user's names. |
1172`-------------------------------------------------------------------*/
1ff442ca 1173
4a120d45 1174static bucket *
118fb205 1175gensym (void)
1ff442ca 1176{
274d42ce
AD
1177 /* Incremented for each generated symbol */
1178 static int gensym_count = 0;
1179 static char buf[256];
1180
a70083a3 1181 bucket *sym;
1ff442ca 1182
274d42ce
AD
1183 sprintf (buf, "@%d", ++gensym_count);
1184 token_buffer = buf;
a70083a3 1185 sym = getsym (token_buffer);
d7020c20 1186 sym->class = nterm_sym;
1ff442ca 1187 sym->value = nvars++;
36281465 1188 return sym;
1ff442ca
NF
1189}
1190
a70083a3
AD
1191#if 0
1192/*------------------------------------------------------------------.
1193| read in a %type declaration and record its information for |
1194| get_type_name to access. This is unused. It is only called from |
1195| the #if 0 part of readgram |
1196`------------------------------------------------------------------*/
1197
1198static int
1199get_type (void)
1200{
1201 int k;
f17bcd1f 1202 token_t token;
a70083a3
AD
1203 char *name;
1204
f17bcd1f 1205 token = lex ();
a70083a3 1206
f17bcd1f 1207 if (token != tok_typename)
a70083a3
AD
1208 {
1209 complain (_("invalid %s declaration"), "%type");
1210 return t;
1211 }
1212
95e36146 1213 name = xstrdup (token_buffer);
a70083a3
AD
1214
1215 for (;;)
1216 {
f17bcd1f 1217 token = lex ();
a70083a3 1218
f17bcd1f 1219 switch (token)
a70083a3 1220 {
511e79b3 1221 case tok_semicolon:
a70083a3
AD
1222 return lex ();
1223
511e79b3 1224 case tok_comma:
a70083a3
AD
1225 break;
1226
511e79b3 1227 case tok_identifier:
a70083a3
AD
1228 if (symval->type_name == NULL)
1229 symval->type_name = name;
1230 else if (strcmp (name, symval->type_name) != 0)
1231 complain (_("type redeclaration for %s"), symval->tag);
1232
1233 break;
1234
1235 default:
f17bcd1f 1236 return token;
a70083a3
AD
1237 }
1238 }
1239}
1ff442ca 1240
a70083a3
AD
1241#endif
1242\f
1243/*------------------------------------------------------------------.
1244| Parse the input grammar into a one symbol_list structure. Each |
1245| rule is represented by a sequence of symbols: the left hand side |
1246| followed by the contents of the right hand side, followed by a |
1247| null pointer instead of a symbol to terminate the rule. The next |
1248| symbol is the lhs of the following rule. |
1249| |
1250| All guards and actions are copied out to the appropriate files, |
1251| labelled by the rule number they apply to. |
1252`------------------------------------------------------------------*/
1ff442ca 1253
4a120d45 1254static void
118fb205 1255readgram (void)
1ff442ca 1256{
f17bcd1f 1257 token_t t;
a70083a3
AD
1258 bucket *lhs = NULL;
1259 symbol_list *p;
1260 symbol_list *p1;
1261 bucket *bp;
1ff442ca 1262
ff4a34be
AD
1263 /* Points to first symbol_list of current rule. its symbol is the
1264 lhs of the rule. */
1265 symbol_list *crule;
1266 /* Points to the symbol_list preceding crule. */
1267 symbol_list *crule1;
1ff442ca
NF
1268
1269 p1 = NULL;
1270
a70083a3 1271 t = lex ();
1ff442ca 1272
511e79b3 1273 while (t != tok_two_percents && t != tok_eof)
1ff442ca 1274 {
511e79b3 1275 if (t == tok_identifier || t == tok_bar)
1ff442ca 1276 {
89cab50d 1277 int action_flag = 0;
ff4a34be
AD
1278 /* Number of symbols in rhs of this rule so far */
1279 int rulelength = 0;
1ff442ca
NF
1280 int xactions = 0; /* JF for error checking */
1281 bucket *first_rhs = 0;
1282
511e79b3 1283 if (t == tok_identifier)
1ff442ca
NF
1284 {
1285 lhs = symval;
943819bf
RS
1286
1287 if (!start_flag)
1288 {
1289 startval = lhs;
1290 start_flag = 1;
1291 }
a083fbbf 1292
a70083a3 1293 t = lex ();
511e79b3 1294 if (t != tok_colon)
943819bf 1295 {
a0f6b076 1296 complain (_("ill-formed rule: initial symbol not followed by colon"));
a70083a3 1297 unlex (t);
943819bf 1298 }
1ff442ca
NF
1299 }
1300
511e79b3 1301 if (nrules == 0 && t == tok_bar)
1ff442ca 1302 {
a0f6b076 1303 complain (_("grammar starts with vertical bar"));
943819bf 1304 lhs = symval; /* BOGUS: use a random symval */
1ff442ca 1305 }
1ff442ca
NF
1306 /* start a new rule and record its lhs. */
1307
1308 nrules++;
1309 nitems++;
1310
1311 record_rule_line ();
1312
d7913476 1313 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1314 p->sym = lhs;
1315
1316 crule1 = p1;
1317 if (p1)
1318 p1->next = p;
1319 else
1320 grammar = p;
1321
1322 p1 = p;
1323 crule = p;
1324
1325 /* mark the rule's lhs as a nonterminal if not already so. */
1326
d7020c20 1327 if (lhs->class == unknown_sym)
1ff442ca 1328 {
d7020c20 1329 lhs->class = nterm_sym;
1ff442ca
NF
1330 lhs->value = nvars;
1331 nvars++;
1332 }
d7020c20 1333 else if (lhs->class == token_sym)
a0f6b076 1334 complain (_("rule given for %s, which is a token"), lhs->tag);
1ff442ca
NF
1335
1336 /* read the rhs of the rule. */
1337
1338 for (;;)
1339 {
a70083a3 1340 t = lex ();
511e79b3 1341 if (t == tok_prec)
943819bf 1342 {
a70083a3 1343 t = lex ();
943819bf 1344 crule->ruleprec = symval;
a70083a3 1345 t = lex ();
943819bf 1346 }
1ff442ca 1347
511e79b3 1348 if (!(t == tok_identifier || t == tok_left_curly))
a70083a3 1349 break;
1ff442ca
NF
1350
1351 /* If next token is an identifier, see if a colon follows it.
a70083a3 1352 If one does, exit this rule now. */
511e79b3 1353 if (t == tok_identifier)
1ff442ca 1354 {
a70083a3 1355 bucket *ssave;
f17bcd1f 1356 token_t t1;
1ff442ca
NF
1357
1358 ssave = symval;
a70083a3
AD
1359 t1 = lex ();
1360 unlex (t1);
1ff442ca 1361 symval = ssave;
511e79b3 1362 if (t1 == tok_colon)
a70083a3 1363 break;
1ff442ca 1364
a70083a3 1365 if (!first_rhs) /* JF */
1ff442ca
NF
1366 first_rhs = symval;
1367 /* Not followed by colon =>
1368 process as part of this rule's rhs. */
1369 }
1370
1371 /* If we just passed an action, that action was in the middle
a70083a3
AD
1372 of a rule, so make a dummy rule to reduce it to a
1373 non-terminal. */
89cab50d 1374 if (action_flag)
1ff442ca 1375 {
a70083a3 1376 bucket *sdummy;
1ff442ca 1377
f282676b
AD
1378 /* Since the action was written out with this rule's
1379 number, we must give the new rule this number by
1380 inserting the new rule before it. */
1ff442ca
NF
1381
1382 /* Make a dummy nonterminal, a gensym. */
a70083a3 1383 sdummy = gensym ();
1ff442ca
NF
1384
1385 /* Make a new rule, whose body is empty,
1386 before the current one, so that the action
1387 just read can belong to it. */
1388 nrules++;
1389 nitems++;
1390 record_rule_line ();
d7913476 1391 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1392 if (crule1)
1393 crule1->next = p;
a70083a3
AD
1394 else
1395 grammar = p;
1ff442ca 1396 p->sym = sdummy;
d7913476 1397 crule1 = XCALLOC (symbol_list, 1);
1ff442ca
NF
1398 p->next = crule1;
1399 crule1->next = crule;
1400
f282676b
AD
1401 /* Insert the dummy generated by that rule into this
1402 rule. */
1ff442ca 1403 nitems++;
d7913476 1404 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1405 p->sym = sdummy;
1406 p1->next = p;
1407 p1 = p;
1408
89cab50d 1409 action_flag = 0;
1ff442ca
NF
1410 }
1411
511e79b3 1412 if (t == tok_identifier)
1ff442ca
NF
1413 {
1414 nitems++;
d7913476 1415 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1416 p->sym = symval;
1417 p1->next = p;
1418 p1 = p;
1419 }
a70083a3 1420 else /* handle an action. */
1ff442ca 1421 {
a70083a3 1422 copy_action (crule, rulelength);
89cab50d 1423 action_flag = 1;
1ff442ca
NF
1424 xactions++; /* JF */
1425 }
1426 rulelength++;
a70083a3 1427 } /* end of read rhs of rule */
1ff442ca
NF
1428
1429 /* Put an empty link in the list to mark the end of this rule */
d7913476 1430 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1431 p1->next = p;
1432 p1 = p;
1433
511e79b3 1434 if (t == tok_prec)
1ff442ca 1435 {
a0f6b076 1436 complain (_("two @prec's in a row"));
a70083a3 1437 t = lex ();
1ff442ca 1438 crule->ruleprec = symval;
a70083a3 1439 t = lex ();
1ff442ca 1440 }
511e79b3 1441 if (t == tok_guard)
1ff442ca 1442 {
a70083a3 1443 if (!semantic_parser)
ff4a34be 1444 complain (_("%%guard present but %%semantic_parser not specified"));
1ff442ca 1445
a70083a3
AD
1446 copy_guard (crule, rulelength);
1447 t = lex ();
1ff442ca 1448 }
511e79b3 1449 else if (t == tok_left_curly)
1ff442ca 1450 {
a70083a3 1451 /* This case never occurs -wjh */
89cab50d 1452 if (action_flag)
a0f6b076 1453 complain (_("two actions at end of one rule"));
a70083a3 1454 copy_action (crule, rulelength);
89cab50d 1455 action_flag = 1;
943819bf 1456 xactions++; /* -wjh */
a70083a3 1457 t = lex ();
1ff442ca 1458 }
a0f6b076 1459 /* If $$ is being set in default way, report if any type
6666f98f
AD
1460 mismatch. */
1461 else if (!xactions
a70083a3 1462 && first_rhs && lhs->type_name != first_rhs->type_name)
1ff442ca 1463 {
6666f98f
AD
1464 if (lhs->type_name == 0
1465 || first_rhs->type_name == 0
a70083a3 1466 || strcmp (lhs->type_name, first_rhs->type_name))
a0f6b076
AD
1467 complain (_("type clash (`%s' `%s') on default action"),
1468 lhs->type_name ? lhs->type_name : "",
a70083a3 1469 first_rhs->type_name ? first_rhs->type_name : "");
1ff442ca
NF
1470 }
1471 /* Warn if there is no default for $$ but we need one. */
1472 else if (!xactions && !first_rhs && lhs->type_name != 0)
a0f6b076 1473 complain (_("empty rule for typed nonterminal, and no action"));
511e79b3 1474 if (t == tok_semicolon)
a70083a3 1475 t = lex ();
a083fbbf 1476 }
943819bf 1477#if 0
a70083a3 1478 /* these things can appear as alternatives to rules. */
943819bf
RS
1479/* NO, they cannot.
1480 a) none of the documentation allows them
1481 b) most of them scan forward until finding a next %
1482 thus they may swallow lots of intervening rules
1483*/
511e79b3 1484 else if (t == tok_token)
1ff442ca 1485 {
d7020c20 1486 parse_token_decl (token_sym, nterm_sym);
a70083a3 1487 t = lex ();
1ff442ca 1488 }
511e79b3 1489 else if (t == tok_nterm)
1ff442ca 1490 {
d7020c20 1491 parse_token_decl (nterm_sym, token_sym);
a70083a3 1492 t = lex ();
1ff442ca 1493 }
511e79b3 1494 else if (t == tok_type)
1ff442ca 1495 {
a70083a3 1496 t = get_type ();
1ff442ca 1497 }
511e79b3 1498 else if (t == tok_union)
1ff442ca 1499 {
a70083a3
AD
1500 parse_union_decl ();
1501 t = lex ();
1ff442ca 1502 }
511e79b3 1503 else if (t == tok_expect)
1ff442ca 1504 {
a70083a3
AD
1505 parse_expect_decl ();
1506 t = lex ();
1ff442ca 1507 }
511e79b3 1508 else if (t == tok_start)
1ff442ca 1509 {
a70083a3
AD
1510 parse_start_decl ();
1511 t = lex ();
1ff442ca 1512 }
943819bf
RS
1513#endif
1514
1ff442ca 1515 else
943819bf 1516 {
d01c415b 1517 complain (_("invalid input: %s"), quote (token_buffer));
a70083a3 1518 t = lex ();
943819bf 1519 }
1ff442ca
NF
1520 }
1521
943819bf
RS
1522 /* grammar has been read. Do some checking */
1523
1ff442ca 1524 if (nsyms > MAXSHORT)
a0f6b076
AD
1525 fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
1526 MAXSHORT);
1ff442ca 1527 if (nrules == 0)
a0f6b076 1528 fatal (_("no rules in the input grammar"));
1ff442ca 1529
ff4a34be
AD
1530 /* JF put out same default YYSTYPE as YACC does */
1531 if (typed == 0
1ff442ca
NF
1532 && !value_components_used)
1533 {
1534 /* We used to use `unsigned long' as YYSTYPE on MSDOS,
a70083a3
AD
1535 but it seems better to be consistent.
1536 Most programs should declare their own type anyway. */
ff4423cc 1537 obstack_sgrow (&attrs_obstack,
573c1d9f 1538 "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
896fe5c1 1539 if (defines_flag)
ff4423cc 1540 obstack_sgrow (&defines_obstack, "\
896fe5c1
AD
1541#ifndef YYSTYPE\n\
1542# define YYSTYPE int\n\
1543#endif\n");
1ff442ca
NF
1544 }
1545
1546 /* Report any undefined symbols and consider them nonterminals. */
1547
1548 for (bp = firstsymbol; bp; bp = bp->next)
d7020c20 1549 if (bp->class == unknown_sym)
1ff442ca 1550 {
a70083a3
AD
1551 complain (_
1552 ("symbol %s is used, but is not defined as a token and has no rules"),
ff4a34be 1553 bp->tag);
d7020c20 1554 bp->class = nterm_sym;
1ff442ca
NF
1555 bp->value = nvars++;
1556 }
1557
1558 ntokens = nsyms - nvars;
1559}
a70083a3
AD
1560\f
1561/*--------------------------------------------------------------.
1562| For named tokens, but not literal ones, define the name. The |
1563| value is the user token number. |
1564`--------------------------------------------------------------*/
1ff442ca 1565
4a120d45 1566static void
896fe5c1 1567output_token_defines (struct obstack *oout)
1ff442ca 1568{
a70083a3
AD
1569 bucket *bp;
1570 char *cp, *symbol;
1571 char c;
1ff442ca 1572
a70083a3 1573 for (bp = firstsymbol; bp; bp = bp->next)
1ff442ca 1574 {
a70083a3
AD
1575 symbol = bp->tag; /* get symbol */
1576
1577 if (bp->value >= ntokens)
1578 continue;
1579 if (bp->user_token_number == SALIAS)
1580 continue;
1581 if ('\'' == *symbol)
1582 continue; /* skip literal character */
1583 if (bp == errtoken)
1584 continue; /* skip error token */
1585 if ('\"' == *symbol)
1ff442ca 1586 {
a70083a3
AD
1587 /* use literal string only if given a symbol with an alias */
1588 if (bp->alias)
1589 symbol = bp->alias->tag;
1590 else
1591 continue;
1592 }
1ff442ca 1593
a70083a3
AD
1594 /* Don't #define nonliteral tokens whose names contain periods. */
1595 cp = symbol;
1596 while ((c = *cp++) && c != '.');
1597 if (c != '\0')
1598 continue;
1ff442ca 1599
896fe5c1
AD
1600 obstack_fgrow2 (oout, "#define\t%s\t%d\n",
1601 symbol,
62ab6972 1602 (translations ? bp->user_token_number : bp->value));
a70083a3 1603 if (semantic_parser)
896fe5c1 1604 obstack_fgrow2 (oout, "#define\tT%s\t%d\n", symbol, bp->value);
1ff442ca 1605 }
a70083a3 1606
896fe5c1 1607 obstack_1grow (oout, '\n');
1ff442ca 1608}
1ff442ca
NF
1609
1610
a70083a3
AD
1611/*------------------------------------------------------------------.
1612| Assign symbol numbers, and write definition of token names into |
b2ca4022 1613| FDEFINES. Set up vectors TAGS and SPREC of names and precedences |
a70083a3
AD
1614| of symbols. |
1615`------------------------------------------------------------------*/
1ff442ca 1616
4a120d45 1617static void
118fb205 1618packsymbols (void)
1ff442ca 1619{
a70083a3
AD
1620 bucket *bp;
1621 int tokno = 1;
1622 int i;
1623 int last_user_token_number;
4a120d45 1624 static char DOLLAR[] = "$";
1ff442ca
NF
1625
1626 /* int lossage = 0; JF set but not used */
1627
d7913476 1628 tags = XCALLOC (char *, nsyms + 1);
4a120d45 1629 tags[0] = DOLLAR;
d7913476 1630 user_toknums = XCALLOC (short, nsyms + 1);
943819bf 1631 user_toknums[0] = 0;
1ff442ca 1632
d7913476
AD
1633 sprec = XCALLOC (short, nsyms);
1634 sassoc = XCALLOC (short, nsyms);
1ff442ca
NF
1635
1636 max_user_token_number = 256;
1637 last_user_token_number = 256;
1638
1639 for (bp = firstsymbol; bp; bp = bp->next)
1640 {
d7020c20 1641 if (bp->class == nterm_sym)
1ff442ca
NF
1642 {
1643 bp->value += ntokens;
1644 }
943819bf
RS
1645 else if (bp->alias)
1646 {
0a6384c4
AD
1647 /* this symbol and its alias are a single token defn.
1648 allocate a tokno, and assign to both check agreement of
1649 ->prec and ->assoc fields and make both the same */
1650 if (bp->value == 0)
1651 bp->value = bp->alias->value = tokno++;
943819bf 1652
0a6384c4
AD
1653 if (bp->prec != bp->alias->prec)
1654 {
1655 if (bp->prec != 0 && bp->alias->prec != 0
1656 && bp->user_token_number == SALIAS)
a0f6b076
AD
1657 complain (_("conflicting precedences for %s and %s"),
1658 bp->tag, bp->alias->tag);
0a6384c4
AD
1659 if (bp->prec != 0)
1660 bp->alias->prec = bp->prec;
1661 else
1662 bp->prec = bp->alias->prec;
1663 }
943819bf 1664
0a6384c4
AD
1665 if (bp->assoc != bp->alias->assoc)
1666 {
a0f6b076
AD
1667 if (bp->assoc != 0 && bp->alias->assoc != 0
1668 && bp->user_token_number == SALIAS)
1669 complain (_("conflicting assoc values for %s and %s"),
1670 bp->tag, bp->alias->tag);
1671 if (bp->assoc != 0)
1672 bp->alias->assoc = bp->assoc;
1673 else
1674 bp->assoc = bp->alias->assoc;
1675 }
0a6384c4
AD
1676
1677 if (bp->user_token_number == SALIAS)
a70083a3 1678 continue; /* do not do processing below for SALIASs */
943819bf 1679
a70083a3 1680 }
d7020c20 1681 else /* bp->class == token_sym */
943819bf
RS
1682 {
1683 bp->value = tokno++;
1684 }
1685
d7020c20 1686 if (bp->class == token_sym)
1ff442ca
NF
1687 {
1688 if (translations && !(bp->user_token_number))
1689 bp->user_token_number = ++last_user_token_number;
1690 if (bp->user_token_number > max_user_token_number)
1691 max_user_token_number = bp->user_token_number;
1ff442ca
NF
1692 }
1693
1694 tags[bp->value] = bp->tag;
943819bf 1695 user_toknums[bp->value] = bp->user_token_number;
1ff442ca
NF
1696 sprec[bp->value] = bp->prec;
1697 sassoc[bp->value] = bp->assoc;
1698
1699 }
1700
1701 if (translations)
1702 {
a70083a3 1703 int j;
1ff442ca 1704
d7913476 1705 token_translations = XCALLOC (short, max_user_token_number + 1);
1ff442ca 1706
0a6384c4 1707 /* initialize all entries for literal tokens to 2, the internal
a70083a3
AD
1708 token number for $undefined., which represents all invalid
1709 inputs. */
4a120d45 1710 for (j = 0; j <= max_user_token_number; j++)
a70083a3 1711 token_translations[j] = 2;
1ff442ca 1712
943819bf 1713 for (bp = firstsymbol; bp; bp = bp->next)
a70083a3
AD
1714 {
1715 if (bp->value >= ntokens)
1716 continue; /* non-terminal */
1717 if (bp->user_token_number == SALIAS)
0a6384c4 1718 continue;
a70083a3 1719 if (token_translations[bp->user_token_number] != 2)
a0f6b076
AD
1720 complain (_("tokens %s and %s both assigned number %d"),
1721 tags[token_translations[bp->user_token_number]],
a70083a3
AD
1722 bp->tag, bp->user_token_number);
1723 token_translations[bp->user_token_number] = bp->value;
1724 }
1ff442ca
NF
1725 }
1726
1727 error_token_number = errtoken->value;
1728
89cab50d 1729 if (!no_parser_flag)
896fe5c1 1730 output_token_defines (&table_obstack);
1ff442ca 1731
d7020c20 1732 if (startval->class == unknown_sym)
a0f6b076 1733 fatal (_("the start symbol %s is undefined"), startval->tag);
d7020c20 1734 else if (startval->class == token_sym)
a0f6b076 1735 fatal (_("the start symbol %s is a token"), startval->tag);
1ff442ca
NF
1736
1737 start_symbol = startval->value;
1738
89cab50d 1739 if (defines_flag)
1ff442ca 1740 {
896fe5c1 1741 output_token_defines (&defines_obstack);
1ff442ca
NF
1742
1743 if (!pure_parser)
1744 {
1745 if (spec_name_prefix)
896fe5c1
AD
1746 obstack_fgrow1 (&defines_obstack, "\nextern YYSTYPE %slval;\n",
1747 spec_name_prefix);
1ff442ca 1748 else
ff4423cc 1749 obstack_sgrow (&defines_obstack,
573c1d9f 1750 "\nextern YYSTYPE yylval;\n");
1ff442ca
NF
1751 }
1752
1753 if (semantic_parser)
1754 for (i = ntokens; i < nsyms; i++)
1755 {
1756 /* don't make these for dummy nonterminals made by gensym. */
1757 if (*tags[i] != '@')
896fe5c1
AD
1758 obstack_fgrow2 (&defines_obstack,
1759 "#define\tNT%s\t%d\n", tags[i], i);
1ff442ca
NF
1760 }
1761#if 0
1762 /* `fdefines' is now a temporary file, so we need to copy its
1763 contents in `done', so we can't close it here. */
a70083a3 1764 fclose (fdefines);
1ff442ca
NF
1765 fdefines = NULL;
1766#endif
1767 }
1768}
a083fbbf 1769
1ff442ca 1770
a70083a3
AD
1771/*---------------------------------------------------------------.
1772| Convert the rules into the representation using RRHS, RLHS and |
1773| RITEMS. |
1774`---------------------------------------------------------------*/
1ff442ca 1775
4a120d45 1776static void
118fb205 1777packgram (void)
1ff442ca 1778{
a70083a3
AD
1779 int itemno;
1780 int ruleno;
1781 symbol_list *p;
1ff442ca
NF
1782
1783 bucket *ruleprec;
1784
d7913476
AD
1785 ritem = XCALLOC (short, nitems + 1);
1786 rlhs = XCALLOC (short, nrules) - 1;
1787 rrhs = XCALLOC (short, nrules) - 1;
1788 rprec = XCALLOC (short, nrules) - 1;
1789 rprecsym = XCALLOC (short, nrules) - 1;
1790 rassoc = XCALLOC (short, nrules) - 1;
1ff442ca
NF
1791
1792 itemno = 0;
1793 ruleno = 1;
1794
1795 p = grammar;
1796 while (p)
1797 {
1798 rlhs[ruleno] = p->sym->value;
1799 rrhs[ruleno] = itemno;
1800 ruleprec = p->ruleprec;
1801
1802 p = p->next;
1803 while (p && p->sym)
1804 {
1805 ritem[itemno++] = p->sym->value;
1806 /* A rule gets by default the precedence and associativity
1807 of the last token in it. */
d7020c20 1808 if (p->sym->class == token_sym)
1ff442ca
NF
1809 {
1810 rprec[ruleno] = p->sym->prec;
1811 rassoc[ruleno] = p->sym->assoc;
1812 }
a70083a3
AD
1813 if (p)
1814 p = p->next;
1ff442ca
NF
1815 }
1816
1817 /* If this rule has a %prec,
a70083a3 1818 the specified symbol's precedence replaces the default. */
1ff442ca
NF
1819 if (ruleprec)
1820 {
a70083a3
AD
1821 rprec[ruleno] = ruleprec->prec;
1822 rassoc[ruleno] = ruleprec->assoc;
1ff442ca
NF
1823 rprecsym[ruleno] = ruleprec->value;
1824 }
1825
1826 ritem[itemno++] = -ruleno;
1827 ruleno++;
1828
a70083a3
AD
1829 if (p)
1830 p = p->next;
1ff442ca
NF
1831 }
1832
1833 ritem[itemno] = 0;
1834}
a70083a3
AD
1835\f
1836/*-------------------------------------------------------------------.
1837| Read in the grammar specification and record it in the format |
ea5607fd 1838| described in gram.h. All guards are copied into the GUARD_OBSTACK |
8c7ebe49
AD
1839| and all actions into ACTION_OBSTACK, in each case forming the body |
1840| of a C function (YYGUARD or YYACTION) which contains a switch |
1841| statement to decide which guard or action to execute. |
a70083a3
AD
1842`-------------------------------------------------------------------*/
1843
1844void
1845reader (void)
1846{
1847 start_flag = 0;
1848 startval = NULL; /* start symbol not specified yet. */
1849
1850#if 0
1851 /* initially assume token number translation not needed. */
1852 translations = 0;
1853#endif
1854 /* Nowadays translations is always set to 1, since we give `error' a
1855 user-token-number to satisfy the Posix demand for YYERRCODE==256.
1856 */
1857 translations = 1;
1858
1859 nsyms = 1;
1860 nvars = 0;
1861 nrules = 0;
1862 nitems = 0;
1863 rline_allocated = 10;
d7913476 1864 rline = XCALLOC (short, rline_allocated);
a70083a3
AD
1865
1866 typed = 0;
1867 lastprec = 0;
1868
a70083a3
AD
1869 semantic_parser = 0;
1870 pure_parser = 0;
a70083a3
AD
1871
1872 grammar = NULL;
1873
1874 init_lex ();
1875 lineno = 1;
1876
1877 /* Initialize the symbol table. */
1878 tabinit ();
1879 /* Construct the error token */
1880 errtoken = getsym ("error");
d7020c20 1881 errtoken->class = token_sym;
a70083a3
AD
1882 errtoken->user_token_number = 256; /* Value specified by POSIX. */
1883 /* Construct a token that represents all undefined literal tokens.
1884 It is always token number 2. */
1885 undeftoken = getsym ("$undefined.");
d7020c20 1886 undeftoken->class = token_sym;
a70083a3
AD
1887 undeftoken->user_token_number = 2;
1888
896fe5c1
AD
1889 /* Read the declaration section. Copy %{ ... %} groups to
1890 TABLE_OBSTACK and FDEFINES file. Also notice any %token, %left,
1891 etc. found there. */
1892 obstack_1grow (&table_obstack, '\n');
1893 obstack_fgrow3 (&table_obstack, "\
a70083a3
AD
1894/* %s, made from %s\n\
1895 by GNU bison %s. */\n\
896fe5c1
AD
1896\n",
1897 no_parser_flag ? "Bison-generated parse tables" : "A Bison parser",
1898 infile, VERSION);
a70083a3 1899
ff4423cc 1900 obstack_sgrow (&table_obstack,
896fe5c1 1901 "#define YYBISON 1 /* Identify Bison output. */\n\n");
a70083a3
AD
1902 read_declarations ();
1903 /* Start writing the guard and action files, if they are needed. */
1904 output_headers ();
1905 /* Read in the grammar, build grammar in list form. Write out
1906 guards and actions. */
1907 readgram ();
1908 /* Now we know whether we need the line-number stack. If we do,
1909 write its type into the .tab.h file. */
896fe5c1
AD
1910 if (defines_flag)
1911 reader_output_yylsp (&defines_obstack);
a70083a3
AD
1912 /* Write closing delimiters for actions and guards. */
1913 output_trailers ();
89cab50d 1914 if (locations_flag)
ff4423cc 1915 obstack_sgrow (&table_obstack, "#define YYLSP_NEEDED 1\n\n");
a70083a3
AD
1916 /* Assign the symbols their symbol numbers. Write #defines for the
1917 token symbols into FDEFINES if requested. */
1918 packsymbols ();
1919 /* Convert the grammar into the format described in gram.h. */
1920 packgram ();
1921 /* Free the symbol table data structure since symbols are now all
1922 referred to by symbol number. */
1923 free_symtab ();
1924}
1925
d7020c20 1926
3abcd459
AD
1927/*------------------------------------------------------------------.
1928| Define YYLTYPE. Cannot be in the skeleton since we might have to |
1929| output it in the headers if --defines is used. |
1930`------------------------------------------------------------------*/
1931
a70083a3 1932void
896fe5c1 1933reader_output_yylsp (struct obstack *oout)
a70083a3 1934{
89cab50d 1935 if (locations_flag)
ff4423cc 1936 obstack_sgrow (oout, "\
d7020c20
AD
1937\n\
1938#ifndef YYLTYPE\n\
89cab50d
AD
1939typedef struct yyltype\n\
1940{\n\
89cab50d 1941 int first_line;\n\
3abcd459 1942 int first_column;\n\
d7020c20 1943\n\
89cab50d
AD
1944 int last_line;\n\
1945 int last_column;\n\
89cab50d 1946} yyltype;\n\
d7020c20 1947\n\
89cab50d 1948# define YYLTYPE yyltype\n\
d7020c20 1949#endif\n\
896fe5c1 1950\n");
a70083a3 1951}