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