]> git.saurik.com Git - bison.git/blame - src/reader.c
* src/lex.h (MAXTOKEN, maxtoken, grow_token_buffer): Remove, private.
[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 {
ff4423cc 312 obstack_sgrow (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 {
ff4423cc 363 obstack_sgrow (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
ff4423cc 735 obstack_sgrow (&attrs_obstack, "typedef union");
896fe5c1 736 if (defines_flag)
ff4423cc 737 obstack_sgrow (&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 {
ff4423cc 767 obstack_sgrow (&attrs_obstack, " YYSTYPE;\n");
896fe5c1 768 if (defines_flag)
ff4423cc 769 obstack_sgrow (&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;
6deb4447 934
a70083a3
AD
935 case THONG:
936 parse_thong_decl ();
937 break;
d7020c20 938
a70083a3 939 case LEFT:
d7020c20 940 parse_assoc_decl (left_assoc);
a70083a3 941 break;
1ff442ca 942
a70083a3 943 case RIGHT:
d7020c20 944 parse_assoc_decl (right_assoc);
a70083a3 945 break;
1ff442ca 946
a70083a3 947 case NONASSOC:
d7020c20 948 parse_assoc_decl (non_assoc);
a70083a3 949 break;
1ff442ca 950
a70083a3
AD
951 case NOOP:
952 break;
1ff442ca 953
a70083a3
AD
954 default:
955 complain (_("unrecognized: %s"), token_buffer);
956 skip_to_char ('%');
957 }
958 }
959 else if (c == EOF)
960 fatal (_("no input grammar"));
961 else
962 {
ff4a34be
AD
963 char buf[] = "c";
964 buf[0] = c;
965 complain (_("unknown character: %s"), quote (buf));
a70083a3 966 skip_to_char ('%');
1ff442ca 967 }
1ff442ca 968 }
1ff442ca 969}
a70083a3
AD
970\f
971/*-------------------------------------------------------------------.
972| Assuming that a `{' has just been seen, copy everything up to the |
973| matching `}' into the actions file. STACK_OFFSET is the number of |
974| values in the current rule so far, which says where to find `$0' |
975| with respect to the top of the stack. |
976`-------------------------------------------------------------------*/
1ff442ca 977
4a120d45 978static void
79282c5a 979copy_action (symbol_list *rule, int stack_offset)
1ff442ca 980{
a70083a3 981 int c;
a70083a3 982 int count;
8c7ebe49 983 char buf[4096];
1ff442ca
NF
984
985 /* offset is always 0 if parser has already popped the stack pointer */
41aca2e0
AD
986 if (semantic_parser)
987 stack_offset = 0;
1ff442ca 988
8c7ebe49
AD
989 sprintf (buf, "\ncase %d:\n", nrules);
990 obstack_grow (&action_obstack, buf, strlen (buf));
991
89cab50d 992 if (!no_lines_flag)
8c7ebe49 993 {
2a91a95e
AD
994 sprintf (buf, "#line %d %s\n",
995 lineno, quotearg_style (c_quoting_style, infile));
8c7ebe49
AD
996 obstack_grow (&action_obstack, buf, strlen (buf));
997 }
998 obstack_1grow (&action_obstack, '{');
1ff442ca
NF
999
1000 count = 1;
a70083a3 1001 c = getc (finput);
1ff442ca
NF
1002
1003 while (count > 0)
1004 {
1005 while (c != '}')
a70083a3
AD
1006 {
1007 switch (c)
1ff442ca
NF
1008 {
1009 case '\n':
8c7ebe49 1010 obstack_1grow (&action_obstack, c);
1ff442ca
NF
1011 lineno++;
1012 break;
1013
1014 case '{':
8c7ebe49 1015 obstack_1grow (&action_obstack, c);
1ff442ca
NF
1016 count++;
1017 break;
1018
1019 case '\'':
1020 case '"':
337bab46 1021 copy_string (finput, &action_obstack, c);
1ff442ca
NF
1022 break;
1023
1024 case '/':
337bab46 1025 copy_comment (finput, &action_obstack);
1ff442ca
NF
1026 break;
1027
1028 case '$':
337bab46 1029 copy_dollar (finput, &action_obstack,
8c7ebe49 1030 rule, stack_offset);
1ff442ca
NF
1031 break;
1032
1033 case '@':
337bab46 1034 copy_at (finput, &action_obstack,
8c7ebe49 1035 stack_offset);
6666f98f 1036 break;
1ff442ca
NF
1037
1038 case EOF:
27821bff 1039 fatal (_("unmatched %s"), "`{'");
1ff442ca
NF
1040
1041 default:
8c7ebe49 1042 obstack_1grow (&action_obstack, c);
a70083a3
AD
1043 }
1044
1045 c = getc (finput);
1046 }
1047
1048 /* above loop exits when c is '}' */
1049
1050 if (--count)
1051 {
8c7ebe49 1052 obstack_1grow (&action_obstack, c);
a70083a3
AD
1053 c = getc (finput);
1054 }
1055 }
1056
ff4423cc 1057 obstack_sgrow (&action_obstack, ";\n break;}");
a70083a3
AD
1058}
1059\f
1060/*-------------------------------------------------------------------.
1061| After `%guard' is seen in the input file, copy the actual guard |
1062| into the guards file. If the guard is followed by an action, copy |
1063| that into the actions file. STACK_OFFSET is the number of values |
1064| in the current rule so far, which says where to find `$0' with |
1065| respect to the top of the stack, for the simple parser in which |
1066| the stack is not popped until after the guard is run. |
1067`-------------------------------------------------------------------*/
1068
1069static void
79282c5a 1070copy_guard (symbol_list *rule, int stack_offset)
a70083a3
AD
1071{
1072 int c;
a70083a3 1073 int count;
a70083a3
AD
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
ea5607fd 1080 obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
89cab50d 1081 if (!no_lines_flag)
ea5607fd
AD
1082 obstack_fgrow2 (&guard_obstack, "#line %d %s\n",
1083 lineno, quotearg_style (c_quoting_style, infile));
1084 obstack_1grow (&guard_obstack, '{');
a70083a3
AD
1085
1086 count = 0;
1087 c = getc (finput);
1088
1089 while (brace_flag ? (count > 0) : (c != ';'))
1090 {
1091 switch (c)
1092 {
1093 case '\n':
ea5607fd 1094 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1095 lineno++;
1096 break;
1097
1098 case '{':
ea5607fd 1099 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1100 brace_flag = 1;
1101 count++;
1102 break;
1103
1104 case '}':
ea5607fd 1105 obstack_1grow (&guard_obstack, c);
a70083a3
AD
1106 if (count > 0)
1107 count--;
1108 else
1109 {
1110 complain (_("unmatched %s"), "`}'");
1111 c = getc (finput); /* skip it */
1112 }
1113 break;
1114
1115 case '\'':
1116 case '"':
337bab46 1117 copy_string (finput, &guard_obstack, c);
a70083a3
AD
1118 break;
1119
1120 case '/':
337bab46 1121 copy_comment (finput, &guard_obstack);
a70083a3
AD
1122 break;
1123
1124 case '$':
337bab46 1125 copy_dollar (finput, &guard_obstack, rule, stack_offset);
a70083a3 1126 break;
1ff442ca 1127
a70083a3 1128 case '@':
337bab46 1129 copy_at (finput, &guard_obstack, stack_offset);
a70083a3 1130 break;
1ff442ca 1131
a70083a3
AD
1132 case EOF:
1133 fatal ("%s", _("unterminated %guard clause"));
1ff442ca 1134
a70083a3 1135 default:
ea5607fd 1136 obstack_1grow (&guard_obstack, c);
1ff442ca 1137 }
a70083a3
AD
1138
1139 if (c != '}' || count != 0)
1140 c = getc (finput);
1ff442ca
NF
1141 }
1142
a70083a3
AD
1143 c = skip_white_space ();
1144
ff4423cc 1145 obstack_sgrow (&guard_obstack, ";\n break;}");
a70083a3
AD
1146 if (c == '{')
1147 copy_action (rule, stack_offset);
1148 else if (c == '=')
1149 {
1150 c = getc (finput); /* why not skip_white_space -wjh */
1151 if (c == '{')
1152 copy_action (rule, stack_offset);
1153 }
1154 else
1155 ungetc (c, finput);
1ff442ca 1156}
a70083a3
AD
1157\f
1158
1159static void
1160record_rule_line (void)
1161{
1162 /* Record each rule's source line number in rline table. */
1ff442ca 1163
a70083a3
AD
1164 if (nrules >= rline_allocated)
1165 {
1166 rline_allocated = nrules * 2;
d7913476 1167 rline = XREALLOC (rline, short, rline_allocated);
a70083a3
AD
1168 }
1169 rline[nrules] = lineno;
1170}
1ff442ca
NF
1171
1172
a70083a3
AD
1173/*-------------------------------------------------------------------.
1174| Generate a dummy symbol, a nonterminal, whose name cannot conflict |
1175| with the user's names. |
1176`-------------------------------------------------------------------*/
1ff442ca 1177
4a120d45 1178static bucket *
118fb205 1179gensym (void)
1ff442ca 1180{
a70083a3 1181 bucket *sym;
1ff442ca
NF
1182
1183 sprintf (token_buffer, "@%d", ++gensym_count);
a70083a3 1184 sym = getsym (token_buffer);
d7020c20 1185 sym->class = nterm_sym;
1ff442ca 1186 sym->value = nvars++;
36281465 1187 return sym;
1ff442ca
NF
1188}
1189
a70083a3
AD
1190#if 0
1191/*------------------------------------------------------------------.
1192| read in a %type declaration and record its information for |
1193| get_type_name to access. This is unused. It is only called from |
1194| the #if 0 part of readgram |
1195`------------------------------------------------------------------*/
1196
1197static int
1198get_type (void)
1199{
1200 int k;
1201 int t;
1202 char *name;
1203
1204 t = lex ();
1205
1206 if (t != TYPENAME)
1207 {
1208 complain (_("invalid %s declaration"), "%type");
1209 return t;
1210 }
1211
95e36146 1212 name = xstrdup (token_buffer);
a70083a3
AD
1213
1214 for (;;)
1215 {
1216 t = lex ();
1217
1218 switch (t)
1219 {
1220 case SEMICOLON:
1221 return lex ();
1222
1223 case COMMA:
1224 break;
1225
1226 case IDENTIFIER:
1227 if (symval->type_name == NULL)
1228 symval->type_name = name;
1229 else if (strcmp (name, symval->type_name) != 0)
1230 complain (_("type redeclaration for %s"), symval->tag);
1231
1232 break;
1233
1234 default:
1235 return t;
1236 }
1237 }
1238}
1ff442ca 1239
a70083a3
AD
1240#endif
1241\f
1242/*------------------------------------------------------------------.
1243| Parse the input grammar into a one symbol_list structure. Each |
1244| rule is represented by a sequence of symbols: the left hand side |
1245| followed by the contents of the right hand side, followed by a |
1246| null pointer instead of a symbol to terminate the rule. The next |
1247| symbol is the lhs of the following rule. |
1248| |
1249| All guards and actions are copied out to the appropriate files, |
1250| labelled by the rule number they apply to. |
1251`------------------------------------------------------------------*/
1ff442ca 1252
4a120d45 1253static void
118fb205 1254readgram (void)
1ff442ca 1255{
a70083a3
AD
1256 int t;
1257 bucket *lhs = NULL;
1258 symbol_list *p;
1259 symbol_list *p1;
1260 bucket *bp;
1ff442ca 1261
ff4a34be
AD
1262 /* Points to first symbol_list of current rule. its symbol is the
1263 lhs of the rule. */
1264 symbol_list *crule;
1265 /* Points to the symbol_list preceding crule. */
1266 symbol_list *crule1;
1ff442ca
NF
1267
1268 p1 = NULL;
1269
a70083a3 1270 t = lex ();
1ff442ca
NF
1271
1272 while (t != TWO_PERCENTS && t != ENDFILE)
1273 {
1274 if (t == IDENTIFIER || t == BAR)
1275 {
89cab50d 1276 int action_flag = 0;
ff4a34be
AD
1277 /* Number of symbols in rhs of this rule so far */
1278 int rulelength = 0;
1ff442ca
NF
1279 int xactions = 0; /* JF for error checking */
1280 bucket *first_rhs = 0;
1281
1282 if (t == IDENTIFIER)
1283 {
1284 lhs = symval;
943819bf
RS
1285
1286 if (!start_flag)
1287 {
1288 startval = lhs;
1289 start_flag = 1;
1290 }
a083fbbf 1291
a70083a3 1292 t = lex ();
1ff442ca 1293 if (t != COLON)
943819bf 1294 {
a0f6b076 1295 complain (_("ill-formed rule: initial symbol not followed by colon"));
a70083a3 1296 unlex (t);
943819bf 1297 }
1ff442ca
NF
1298 }
1299
943819bf 1300 if (nrules == 0 && t == BAR)
1ff442ca 1301 {
a0f6b076 1302 complain (_("grammar starts with vertical bar"));
943819bf 1303 lhs = symval; /* BOGUS: use a random symval */
1ff442ca 1304 }
1ff442ca
NF
1305 /* start a new rule and record its lhs. */
1306
1307 nrules++;
1308 nitems++;
1309
1310 record_rule_line ();
1311
d7913476 1312 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1313 p->sym = lhs;
1314
1315 crule1 = p1;
1316 if (p1)
1317 p1->next = p;
1318 else
1319 grammar = p;
1320
1321 p1 = p;
1322 crule = p;
1323
1324 /* mark the rule's lhs as a nonterminal if not already so. */
1325
d7020c20 1326 if (lhs->class == unknown_sym)
1ff442ca 1327 {
d7020c20 1328 lhs->class = nterm_sym;
1ff442ca
NF
1329 lhs->value = nvars;
1330 nvars++;
1331 }
d7020c20 1332 else if (lhs->class == token_sym)
a0f6b076 1333 complain (_("rule given for %s, which is a token"), lhs->tag);
1ff442ca
NF
1334
1335 /* read the rhs of the rule. */
1336
1337 for (;;)
1338 {
a70083a3 1339 t = lex ();
943819bf
RS
1340 if (t == PREC)
1341 {
a70083a3 1342 t = lex ();
943819bf 1343 crule->ruleprec = symval;
a70083a3 1344 t = lex ();
943819bf 1345 }
1ff442ca 1346
a70083a3
AD
1347 if (!(t == IDENTIFIER || t == LEFT_CURLY))
1348 break;
1ff442ca
NF
1349
1350 /* If next token is an identifier, see if a colon follows it.
a70083a3 1351 If one does, exit this rule now. */
1ff442ca
NF
1352 if (t == IDENTIFIER)
1353 {
a70083a3
AD
1354 bucket *ssave;
1355 int t1;
1ff442ca
NF
1356
1357 ssave = symval;
a70083a3
AD
1358 t1 = lex ();
1359 unlex (t1);
1ff442ca 1360 symval = ssave;
a70083a3
AD
1361 if (t1 == COLON)
1362 break;
1ff442ca 1363
a70083a3 1364 if (!first_rhs) /* JF */
1ff442ca
NF
1365 first_rhs = symval;
1366 /* Not followed by colon =>
1367 process as part of this rule's rhs. */
1368 }
1369
1370 /* If we just passed an action, that action was in the middle
a70083a3
AD
1371 of a rule, so make a dummy rule to reduce it to a
1372 non-terminal. */
89cab50d 1373 if (action_flag)
1ff442ca 1374 {
a70083a3 1375 bucket *sdummy;
1ff442ca 1376
f282676b
AD
1377 /* Since the action was written out with this rule's
1378 number, we must give the new rule this number by
1379 inserting the new rule before it. */
1ff442ca
NF
1380
1381 /* Make a dummy nonterminal, a gensym. */
a70083a3 1382 sdummy = gensym ();
1ff442ca
NF
1383
1384 /* Make a new rule, whose body is empty,
1385 before the current one, so that the action
1386 just read can belong to it. */
1387 nrules++;
1388 nitems++;
1389 record_rule_line ();
d7913476 1390 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1391 if (crule1)
1392 crule1->next = p;
a70083a3
AD
1393 else
1394 grammar = p;
1ff442ca 1395 p->sym = sdummy;
d7913476 1396 crule1 = XCALLOC (symbol_list, 1);
1ff442ca
NF
1397 p->next = crule1;
1398 crule1->next = crule;
1399
f282676b
AD
1400 /* Insert the dummy generated by that rule into this
1401 rule. */
1ff442ca 1402 nitems++;
d7913476 1403 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1404 p->sym = sdummy;
1405 p1->next = p;
1406 p1 = p;
1407
89cab50d 1408 action_flag = 0;
1ff442ca
NF
1409 }
1410
1411 if (t == IDENTIFIER)
1412 {
1413 nitems++;
d7913476 1414 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1415 p->sym = symval;
1416 p1->next = p;
1417 p1 = p;
1418 }
a70083a3 1419 else /* handle an action. */
1ff442ca 1420 {
a70083a3 1421 copy_action (crule, rulelength);
89cab50d 1422 action_flag = 1;
1ff442ca
NF
1423 xactions++; /* JF */
1424 }
1425 rulelength++;
a70083a3 1426 } /* end of read rhs of rule */
1ff442ca
NF
1427
1428 /* Put an empty link in the list to mark the end of this rule */
d7913476 1429 p = XCALLOC (symbol_list, 1);
1ff442ca
NF
1430 p1->next = p;
1431 p1 = p;
1432
1433 if (t == PREC)
1434 {
a0f6b076 1435 complain (_("two @prec's in a row"));
a70083a3 1436 t = lex ();
1ff442ca 1437 crule->ruleprec = symval;
a70083a3 1438 t = lex ();
1ff442ca
NF
1439 }
1440 if (t == GUARD)
1441 {
a70083a3 1442 if (!semantic_parser)
ff4a34be 1443 complain (_("%%guard present but %%semantic_parser not specified"));
1ff442ca 1444
a70083a3
AD
1445 copy_guard (crule, rulelength);
1446 t = lex ();
1ff442ca
NF
1447 }
1448 else if (t == LEFT_CURLY)
1449 {
a70083a3 1450 /* This case never occurs -wjh */
89cab50d 1451 if (action_flag)
a0f6b076 1452 complain (_("two actions at end of one rule"));
a70083a3 1453 copy_action (crule, rulelength);
89cab50d 1454 action_flag = 1;
943819bf 1455 xactions++; /* -wjh */
a70083a3 1456 t = lex ();
1ff442ca 1457 }
a0f6b076 1458 /* If $$ is being set in default way, report if any type
6666f98f
AD
1459 mismatch. */
1460 else if (!xactions
a70083a3 1461 && first_rhs && lhs->type_name != first_rhs->type_name)
1ff442ca 1462 {
6666f98f
AD
1463 if (lhs->type_name == 0
1464 || first_rhs->type_name == 0
a70083a3 1465 || strcmp (lhs->type_name, first_rhs->type_name))
a0f6b076
AD
1466 complain (_("type clash (`%s' `%s') on default action"),
1467 lhs->type_name ? lhs->type_name : "",
a70083a3 1468 first_rhs->type_name ? first_rhs->type_name : "");
1ff442ca
NF
1469 }
1470 /* Warn if there is no default for $$ but we need one. */
1471 else if (!xactions && !first_rhs && lhs->type_name != 0)
a0f6b076 1472 complain (_("empty rule for typed nonterminal, and no action"));
1ff442ca 1473 if (t == SEMICOLON)
a70083a3 1474 t = lex ();
a083fbbf 1475 }
943819bf 1476#if 0
a70083a3 1477 /* these things can appear as alternatives to rules. */
943819bf
RS
1478/* NO, they cannot.
1479 a) none of the documentation allows them
1480 b) most of them scan forward until finding a next %
1481 thus they may swallow lots of intervening rules
1482*/
1ff442ca
NF
1483 else if (t == TOKEN)
1484 {
d7020c20 1485 parse_token_decl (token_sym, nterm_sym);
a70083a3 1486 t = lex ();
1ff442ca
NF
1487 }
1488 else if (t == NTERM)
1489 {
d7020c20 1490 parse_token_decl (nterm_sym, token_sym);
a70083a3 1491 t = lex ();
1ff442ca
NF
1492 }
1493 else if (t == TYPE)
1494 {
a70083a3 1495 t = get_type ();
1ff442ca
NF
1496 }
1497 else if (t == UNION)
1498 {
a70083a3
AD
1499 parse_union_decl ();
1500 t = lex ();
1ff442ca
NF
1501 }
1502 else if (t == EXPECT)
1503 {
a70083a3
AD
1504 parse_expect_decl ();
1505 t = lex ();
1ff442ca
NF
1506 }
1507 else if (t == START)
1508 {
a70083a3
AD
1509 parse_start_decl ();
1510 t = lex ();
1ff442ca 1511 }
943819bf
RS
1512#endif
1513
1ff442ca 1514 else
943819bf 1515 {
a0f6b076 1516 complain (_("invalid input: %s"), token_buffer);
a70083a3 1517 t = lex ();
943819bf 1518 }
1ff442ca
NF
1519 }
1520
943819bf
RS
1521 /* grammar has been read. Do some checking */
1522
1ff442ca 1523 if (nsyms > MAXSHORT)
a0f6b076
AD
1524 fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
1525 MAXSHORT);
1ff442ca 1526 if (nrules == 0)
a0f6b076 1527 fatal (_("no rules in the input grammar"));
1ff442ca 1528
ff4a34be
AD
1529 /* JF put out same default YYSTYPE as YACC does */
1530 if (typed == 0
1ff442ca
NF
1531 && !value_components_used)
1532 {
1533 /* We used to use `unsigned long' as YYSTYPE on MSDOS,
a70083a3
AD
1534 but it seems better to be consistent.
1535 Most programs should declare their own type anyway. */
ff4423cc 1536 obstack_sgrow (&attrs_obstack,
573c1d9f 1537 "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
896fe5c1 1538 if (defines_flag)
ff4423cc 1539 obstack_sgrow (&defines_obstack, "\
896fe5c1
AD
1540#ifndef YYSTYPE\n\
1541# define YYSTYPE int\n\
1542#endif\n");
1ff442ca
NF
1543 }
1544
1545 /* Report any undefined symbols and consider them nonterminals. */
1546
1547 for (bp = firstsymbol; bp; bp = bp->next)
d7020c20 1548 if (bp->class == unknown_sym)
1ff442ca 1549 {
a70083a3
AD
1550 complain (_
1551 ("symbol %s is used, but is not defined as a token and has no rules"),
ff4a34be 1552 bp->tag);
d7020c20 1553 bp->class = nterm_sym;
1ff442ca
NF
1554 bp->value = nvars++;
1555 }
1556
1557 ntokens = nsyms - nvars;
1558}
a70083a3
AD
1559\f
1560/*--------------------------------------------------------------.
1561| For named tokens, but not literal ones, define the name. The |
1562| value is the user token number. |
1563`--------------------------------------------------------------*/
1ff442ca 1564
4a120d45 1565static void
896fe5c1 1566output_token_defines (struct obstack *oout)
1ff442ca 1567{
a70083a3
AD
1568 bucket *bp;
1569 char *cp, *symbol;
1570 char c;
1ff442ca 1571
a70083a3 1572 for (bp = firstsymbol; bp; bp = bp->next)
1ff442ca 1573 {
a70083a3
AD
1574 symbol = bp->tag; /* get symbol */
1575
1576 if (bp->value >= ntokens)
1577 continue;
1578 if (bp->user_token_number == SALIAS)
1579 continue;
1580 if ('\'' == *symbol)
1581 continue; /* skip literal character */
1582 if (bp == errtoken)
1583 continue; /* skip error token */
1584 if ('\"' == *symbol)
1ff442ca 1585 {
a70083a3
AD
1586 /* use literal string only if given a symbol with an alias */
1587 if (bp->alias)
1588 symbol = bp->alias->tag;
1589 else
1590 continue;
1591 }
1ff442ca 1592
a70083a3
AD
1593 /* Don't #define nonliteral tokens whose names contain periods. */
1594 cp = symbol;
1595 while ((c = *cp++) && c != '.');
1596 if (c != '\0')
1597 continue;
1ff442ca 1598
896fe5c1
AD
1599 obstack_fgrow2 (oout, "#define\t%s\t%d\n",
1600 symbol,
1601 ((translations && !raw_flag)
1602 ? bp->user_token_number : bp->value));
a70083a3 1603 if (semantic_parser)
896fe5c1 1604 obstack_fgrow2 (oout, "#define\tT%s\t%d\n", symbol, bp->value);
1ff442ca 1605 }
a70083a3 1606
896fe5c1 1607 obstack_1grow (oout, '\n');
1ff442ca 1608}
1ff442ca
NF
1609
1610
a70083a3
AD
1611/*------------------------------------------------------------------.
1612| Assign symbol numbers, and write definition of token names into |
b2ca4022 1613| FDEFINES. Set up vectors TAGS and SPREC of names and precedences |
a70083a3
AD
1614| of symbols. |
1615`------------------------------------------------------------------*/
1ff442ca 1616
4a120d45 1617static void
118fb205 1618packsymbols (void)
1ff442ca 1619{
a70083a3
AD
1620 bucket *bp;
1621 int tokno = 1;
1622 int i;
1623 int last_user_token_number;
4a120d45 1624 static char DOLLAR[] = "$";
1ff442ca
NF
1625
1626 /* int lossage = 0; JF set but not used */
1627
d7913476 1628 tags = XCALLOC (char *, nsyms + 1);
4a120d45 1629 tags[0] = DOLLAR;
d7913476 1630 user_toknums = XCALLOC (short, nsyms + 1);
943819bf 1631 user_toknums[0] = 0;
1ff442ca 1632
d7913476
AD
1633 sprec = XCALLOC (short, nsyms);
1634 sassoc = XCALLOC (short, nsyms);
1ff442ca
NF
1635
1636 max_user_token_number = 256;
1637 last_user_token_number = 256;
1638
1639 for (bp = firstsymbol; bp; bp = bp->next)
1640 {
d7020c20 1641 if (bp->class == nterm_sym)
1ff442ca
NF
1642 {
1643 bp->value += ntokens;
1644 }
943819bf
RS
1645 else if (bp->alias)
1646 {
0a6384c4
AD
1647 /* this symbol and its alias are a single token defn.
1648 allocate a tokno, and assign to both check agreement of
1649 ->prec and ->assoc fields and make both the same */
1650 if (bp->value == 0)
1651 bp->value = bp->alias->value = tokno++;
943819bf 1652
0a6384c4
AD
1653 if (bp->prec != bp->alias->prec)
1654 {
1655 if (bp->prec != 0 && bp->alias->prec != 0
1656 && bp->user_token_number == SALIAS)
a0f6b076
AD
1657 complain (_("conflicting precedences for %s and %s"),
1658 bp->tag, bp->alias->tag);
0a6384c4
AD
1659 if (bp->prec != 0)
1660 bp->alias->prec = bp->prec;
1661 else
1662 bp->prec = bp->alias->prec;
1663 }
943819bf 1664
0a6384c4
AD
1665 if (bp->assoc != bp->alias->assoc)
1666 {
a0f6b076
AD
1667 if (bp->assoc != 0 && bp->alias->assoc != 0
1668 && bp->user_token_number == SALIAS)
1669 complain (_("conflicting assoc values for %s and %s"),
1670 bp->tag, bp->alias->tag);
1671 if (bp->assoc != 0)
1672 bp->alias->assoc = bp->assoc;
1673 else
1674 bp->assoc = bp->alias->assoc;
1675 }
0a6384c4
AD
1676
1677 if (bp->user_token_number == SALIAS)
a70083a3 1678 continue; /* do not do processing below for SALIASs */
943819bf 1679
a70083a3 1680 }
d7020c20 1681 else /* bp->class == token_sym */
943819bf
RS
1682 {
1683 bp->value = tokno++;
1684 }
1685
d7020c20 1686 if (bp->class == token_sym)
1ff442ca
NF
1687 {
1688 if (translations && !(bp->user_token_number))
1689 bp->user_token_number = ++last_user_token_number;
1690 if (bp->user_token_number > max_user_token_number)
1691 max_user_token_number = bp->user_token_number;
1ff442ca
NF
1692 }
1693
1694 tags[bp->value] = bp->tag;
943819bf 1695 user_toknums[bp->value] = bp->user_token_number;
1ff442ca
NF
1696 sprec[bp->value] = bp->prec;
1697 sassoc[bp->value] = bp->assoc;
1698
1699 }
1700
1701 if (translations)
1702 {
a70083a3 1703 int j;
1ff442ca 1704
d7913476 1705 token_translations = XCALLOC (short, max_user_token_number + 1);
1ff442ca 1706
0a6384c4 1707 /* initialize all entries for literal tokens to 2, the internal
a70083a3
AD
1708 token number for $undefined., which represents all invalid
1709 inputs. */
4a120d45 1710 for (j = 0; j <= max_user_token_number; j++)
a70083a3 1711 token_translations[j] = 2;
1ff442ca 1712
943819bf 1713 for (bp = firstsymbol; bp; bp = bp->next)
a70083a3
AD
1714 {
1715 if (bp->value >= ntokens)
1716 continue; /* non-terminal */
1717 if (bp->user_token_number == SALIAS)
0a6384c4 1718 continue;
a70083a3 1719 if (token_translations[bp->user_token_number] != 2)
a0f6b076
AD
1720 complain (_("tokens %s and %s both assigned number %d"),
1721 tags[token_translations[bp->user_token_number]],
a70083a3
AD
1722 bp->tag, bp->user_token_number);
1723 token_translations[bp->user_token_number] = bp->value;
1724 }
1ff442ca
NF
1725 }
1726
1727 error_token_number = errtoken->value;
1728
89cab50d 1729 if (!no_parser_flag)
896fe5c1 1730 output_token_defines (&table_obstack);
1ff442ca 1731
d7020c20 1732 if (startval->class == unknown_sym)
a0f6b076 1733 fatal (_("the start symbol %s is undefined"), startval->tag);
d7020c20 1734 else if (startval->class == token_sym)
a0f6b076 1735 fatal (_("the start symbol %s is a token"), startval->tag);
1ff442ca
NF
1736
1737 start_symbol = startval->value;
1738
89cab50d 1739 if (defines_flag)
1ff442ca 1740 {
896fe5c1 1741 output_token_defines (&defines_obstack);
1ff442ca
NF
1742
1743 if (!pure_parser)
1744 {
1745 if (spec_name_prefix)
896fe5c1
AD
1746 obstack_fgrow1 (&defines_obstack, "\nextern YYSTYPE %slval;\n",
1747 spec_name_prefix);
1ff442ca 1748 else
ff4423cc 1749 obstack_sgrow (&defines_obstack,
573c1d9f 1750 "\nextern YYSTYPE yylval;\n");
1ff442ca
NF
1751 }
1752
1753 if (semantic_parser)
1754 for (i = ntokens; i < nsyms; i++)
1755 {
1756 /* don't make these for dummy nonterminals made by gensym. */
1757 if (*tags[i] != '@')
896fe5c1
AD
1758 obstack_fgrow2 (&defines_obstack,
1759 "#define\tNT%s\t%d\n", tags[i], i);
1ff442ca
NF
1760 }
1761#if 0
1762 /* `fdefines' is now a temporary file, so we need to copy its
1763 contents in `done', so we can't close it here. */
a70083a3 1764 fclose (fdefines);
1ff442ca
NF
1765 fdefines = NULL;
1766#endif
1767 }
1768}
a083fbbf 1769
1ff442ca 1770
a70083a3
AD
1771/*---------------------------------------------------------------.
1772| Convert the rules into the representation using RRHS, RLHS and |
1773| RITEMS. |
1774`---------------------------------------------------------------*/
1ff442ca 1775
4a120d45 1776static void
118fb205 1777packgram (void)
1ff442ca 1778{
a70083a3
AD
1779 int itemno;
1780 int ruleno;
1781 symbol_list *p;
1ff442ca
NF
1782
1783 bucket *ruleprec;
1784
d7913476
AD
1785 ritem = XCALLOC (short, nitems + 1);
1786 rlhs = XCALLOC (short, nrules) - 1;
1787 rrhs = XCALLOC (short, nrules) - 1;
1788 rprec = XCALLOC (short, nrules) - 1;
1789 rprecsym = XCALLOC (short, nrules) - 1;
1790 rassoc = XCALLOC (short, nrules) - 1;
1ff442ca
NF
1791
1792 itemno = 0;
1793 ruleno = 1;
1794
1795 p = grammar;
1796 while (p)
1797 {
1798 rlhs[ruleno] = p->sym->value;
1799 rrhs[ruleno] = itemno;
1800 ruleprec = p->ruleprec;
1801
1802 p = p->next;
1803 while (p && p->sym)
1804 {
1805 ritem[itemno++] = p->sym->value;
1806 /* A rule gets by default the precedence and associativity
1807 of the last token in it. */
d7020c20 1808 if (p->sym->class == token_sym)
1ff442ca
NF
1809 {
1810 rprec[ruleno] = p->sym->prec;
1811 rassoc[ruleno] = p->sym->assoc;
1812 }
a70083a3
AD
1813 if (p)
1814 p = p->next;
1ff442ca
NF
1815 }
1816
1817 /* If this rule has a %prec,
a70083a3 1818 the specified symbol's precedence replaces the default. */
1ff442ca
NF
1819 if (ruleprec)
1820 {
a70083a3
AD
1821 rprec[ruleno] = ruleprec->prec;
1822 rassoc[ruleno] = ruleprec->assoc;
1ff442ca
NF
1823 rprecsym[ruleno] = ruleprec->value;
1824 }
1825
1826 ritem[itemno++] = -ruleno;
1827 ruleno++;
1828
a70083a3
AD
1829 if (p)
1830 p = p->next;
1ff442ca
NF
1831 }
1832
1833 ritem[itemno] = 0;
1834}
a70083a3
AD
1835\f
1836/*-------------------------------------------------------------------.
1837| Read in the grammar specification and record it in the format |
ea5607fd 1838| described in gram.h. All guards are copied into the GUARD_OBSTACK |
8c7ebe49
AD
1839| and all actions into ACTION_OBSTACK, in each case forming the body |
1840| of a C function (YYGUARD or YYACTION) which contains a switch |
1841| statement to decide which guard or action to execute. |
a70083a3
AD
1842`-------------------------------------------------------------------*/
1843
1844void
1845reader (void)
1846{
1847 start_flag = 0;
1848 startval = NULL; /* start symbol not specified yet. */
1849
1850#if 0
1851 /* initially assume token number translation not needed. */
1852 translations = 0;
1853#endif
1854 /* Nowadays translations is always set to 1, since we give `error' a
1855 user-token-number to satisfy the Posix demand for YYERRCODE==256.
1856 */
1857 translations = 1;
1858
1859 nsyms = 1;
1860 nvars = 0;
1861 nrules = 0;
1862 nitems = 0;
1863 rline_allocated = 10;
d7913476 1864 rline = XCALLOC (short, rline_allocated);
a70083a3
AD
1865
1866 typed = 0;
1867 lastprec = 0;
1868
1869 gensym_count = 0;
1870
1871 semantic_parser = 0;
1872 pure_parser = 0;
a70083a3
AD
1873
1874 grammar = NULL;
1875
1876 init_lex ();
1877 lineno = 1;
1878
1879 /* Initialize the symbol table. */
1880 tabinit ();
1881 /* Construct the error token */
1882 errtoken = getsym ("error");
d7020c20 1883 errtoken->class = token_sym;
a70083a3
AD
1884 errtoken->user_token_number = 256; /* Value specified by POSIX. */
1885 /* Construct a token that represents all undefined literal tokens.
1886 It is always token number 2. */
1887 undeftoken = getsym ("$undefined.");
d7020c20 1888 undeftoken->class = token_sym;
a70083a3
AD
1889 undeftoken->user_token_number = 2;
1890
896fe5c1
AD
1891 /* Read the declaration section. Copy %{ ... %} groups to
1892 TABLE_OBSTACK and FDEFINES file. Also notice any %token, %left,
1893 etc. found there. */
1894 obstack_1grow (&table_obstack, '\n');
1895 obstack_fgrow3 (&table_obstack, "\
a70083a3
AD
1896/* %s, made from %s\n\
1897 by GNU bison %s. */\n\
896fe5c1
AD
1898\n",
1899 no_parser_flag ? "Bison-generated parse tables" : "A Bison parser",
1900 infile, VERSION);
a70083a3 1901
ff4423cc 1902 obstack_sgrow (&table_obstack,
896fe5c1 1903 "#define YYBISON 1 /* Identify Bison output. */\n\n");
a70083a3
AD
1904 read_declarations ();
1905 /* Start writing the guard and action files, if they are needed. */
1906 output_headers ();
1907 /* Read in the grammar, build grammar in list form. Write out
1908 guards and actions. */
1909 readgram ();
1910 /* Now we know whether we need the line-number stack. If we do,
1911 write its type into the .tab.h file. */
896fe5c1
AD
1912 if (defines_flag)
1913 reader_output_yylsp (&defines_obstack);
a70083a3
AD
1914 /* Write closing delimiters for actions and guards. */
1915 output_trailers ();
89cab50d 1916 if (locations_flag)
ff4423cc 1917 obstack_sgrow (&table_obstack, "#define YYLSP_NEEDED 1\n\n");
a70083a3
AD
1918 /* Assign the symbols their symbol numbers. Write #defines for the
1919 token symbols into FDEFINES if requested. */
1920 packsymbols ();
1921 /* Convert the grammar into the format described in gram.h. */
1922 packgram ();
1923 /* Free the symbol table data structure since symbols are now all
1924 referred to by symbol number. */
1925 free_symtab ();
1926}
1927
d7020c20 1928
3abcd459
AD
1929/*------------------------------------------------------------------.
1930| Define YYLTYPE. Cannot be in the skeleton since we might have to |
1931| output it in the headers if --defines is used. |
1932`------------------------------------------------------------------*/
1933
a70083a3 1934void
896fe5c1 1935reader_output_yylsp (struct obstack *oout)
a70083a3 1936{
89cab50d 1937 if (locations_flag)
ff4423cc 1938 obstack_sgrow (oout, "\
d7020c20
AD
1939\n\
1940#ifndef YYLTYPE\n\
89cab50d
AD
1941typedef struct yyltype\n\
1942{\n\
89cab50d 1943 int first_line;\n\
3abcd459 1944 int first_column;\n\
d7020c20 1945\n\
89cab50d
AD
1946 int last_line;\n\
1947 int last_column;\n\
89cab50d 1948} yyltype;\n\
d7020c20 1949\n\
89cab50d 1950# define YYLTYPE yyltype\n\
d7020c20 1951#endif\n\
896fe5c1 1952\n");
a70083a3 1953}