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