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