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