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