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