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