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