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