]> git.saurik.com Git - bison.git/blob - src/reader.c
1dfe020b588343831a07b5ea140c5873fab6c1a4
[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 "xalloc.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 = XCALLOC (char, k + 1);
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 = XCALLOC (char, k + 1);
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 = XCALLOC (char, k + 1);
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 = XCALLOC (char, k + 1);
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 = XREALLOC (rline, short, rline_allocated);
1220 }
1221 rline[nrules] = lineno;
1222 }
1223
1224
1225 /*-------------------------------------------------------------------.
1226 | Generate a dummy symbol, a nonterminal, whose name cannot conflict |
1227 | with the user's names. |
1228 `-------------------------------------------------------------------*/
1229
1230 static bucket *
1231 gensym (void)
1232 {
1233 bucket *sym;
1234
1235 sprintf (token_buffer, "@%d", ++gensym_count);
1236 sym = getsym (token_buffer);
1237 sym->class = SNTERM;
1238 sym->value = nvars++;
1239 return sym;
1240 }
1241
1242 #if 0
1243 /*------------------------------------------------------------------.
1244 | read in a %type declaration and record its information for |
1245 | get_type_name to access. This is unused. It is only called from |
1246 | the #if 0 part of readgram |
1247 `------------------------------------------------------------------*/
1248
1249 static int
1250 get_type (void)
1251 {
1252 int k;
1253 int t;
1254 char *name;
1255
1256 t = lex ();
1257
1258 if (t != TYPENAME)
1259 {
1260 complain (_("invalid %s declaration"), "%type");
1261 return t;
1262 }
1263
1264 k = strlen (token_buffer);
1265 name = XCALLOC (char, k + 1);
1266 strcpy (name, token_buffer);
1267
1268 for (;;)
1269 {
1270 t = lex ();
1271
1272 switch (t)
1273 {
1274 case SEMICOLON:
1275 return lex ();
1276
1277 case COMMA:
1278 break;
1279
1280 case IDENTIFIER:
1281 if (symval->type_name == NULL)
1282 symval->type_name = name;
1283 else if (strcmp (name, symval->type_name) != 0)
1284 complain (_("type redeclaration for %s"), symval->tag);
1285
1286 break;
1287
1288 default:
1289 return t;
1290 }
1291 }
1292 }
1293
1294 #endif
1295 \f
1296 /*------------------------------------------------------------------.
1297 | Parse the input grammar into a one symbol_list structure. Each |
1298 | rule is represented by a sequence of symbols: the left hand side |
1299 | followed by the contents of the right hand side, followed by a |
1300 | null pointer instead of a symbol to terminate the rule. The next |
1301 | symbol is the lhs of the following rule. |
1302 | |
1303 | All guards and actions are copied out to the appropriate files, |
1304 | labelled by the rule number they apply to. |
1305 `------------------------------------------------------------------*/
1306
1307 static void
1308 readgram (void)
1309 {
1310 int t;
1311 bucket *lhs = NULL;
1312 symbol_list *p;
1313 symbol_list *p1;
1314 bucket *bp;
1315
1316 symbol_list *crule; /* points to first symbol_list of current rule. */
1317 /* its symbol is the lhs of the rule. */
1318 symbol_list *crule1; /* points to the symbol_list preceding crule. */
1319
1320 p1 = NULL;
1321
1322 t = lex ();
1323
1324 while (t != TWO_PERCENTS && t != ENDFILE)
1325 {
1326 if (t == IDENTIFIER || t == BAR)
1327 {
1328 int actionflag = 0;
1329 int rulelength = 0; /* number of symbols in rhs of this rule so far */
1330 int xactions = 0; /* JF for error checking */
1331 bucket *first_rhs = 0;
1332
1333 if (t == IDENTIFIER)
1334 {
1335 lhs = symval;
1336
1337 if (!start_flag)
1338 {
1339 startval = lhs;
1340 start_flag = 1;
1341 }
1342
1343 t = lex ();
1344 if (t != COLON)
1345 {
1346 complain (_("ill-formed rule: initial symbol not followed by colon"));
1347 unlex (t);
1348 }
1349 }
1350
1351 if (nrules == 0 && t == BAR)
1352 {
1353 complain (_("grammar starts with vertical bar"));
1354 lhs = symval; /* BOGUS: use a random symval */
1355 }
1356 /* start a new rule and record its lhs. */
1357
1358 nrules++;
1359 nitems++;
1360
1361 record_rule_line ();
1362
1363 p = XCALLOC (symbol_list, 1);
1364 p->sym = lhs;
1365
1366 crule1 = p1;
1367 if (p1)
1368 p1->next = p;
1369 else
1370 grammar = p;
1371
1372 p1 = p;
1373 crule = p;
1374
1375 /* mark the rule's lhs as a nonterminal if not already so. */
1376
1377 if (lhs->class == SUNKNOWN)
1378 {
1379 lhs->class = SNTERM;
1380 lhs->value = nvars;
1381 nvars++;
1382 }
1383 else if (lhs->class == STOKEN)
1384 complain (_("rule given for %s, which is a token"), lhs->tag);
1385
1386 /* read the rhs of the rule. */
1387
1388 for (;;)
1389 {
1390 t = lex ();
1391 if (t == PREC)
1392 {
1393 t = lex ();
1394 crule->ruleprec = symval;
1395 t = lex ();
1396 }
1397
1398 if (!(t == IDENTIFIER || t == LEFT_CURLY))
1399 break;
1400
1401 /* If next token is an identifier, see if a colon follows it.
1402 If one does, exit this rule now. */
1403 if (t == IDENTIFIER)
1404 {
1405 bucket *ssave;
1406 int t1;
1407
1408 ssave = symval;
1409 t1 = lex ();
1410 unlex (t1);
1411 symval = ssave;
1412 if (t1 == COLON)
1413 break;
1414
1415 if (!first_rhs) /* JF */
1416 first_rhs = symval;
1417 /* Not followed by colon =>
1418 process as part of this rule's rhs. */
1419 }
1420
1421 /* If we just passed an action, that action was in the middle
1422 of a rule, so make a dummy rule to reduce it to a
1423 non-terminal. */
1424 if (actionflag)
1425 {
1426 bucket *sdummy;
1427
1428 /* Since the action was written out with this rule's */
1429 /* number, we must give the new rule this number */
1430 /* by inserting the new rule before it. */
1431
1432 /* Make a dummy nonterminal, a gensym. */
1433 sdummy = gensym ();
1434
1435 /* Make a new rule, whose body is empty,
1436 before the current one, so that the action
1437 just read can belong to it. */
1438 nrules++;
1439 nitems++;
1440 record_rule_line ();
1441 p = XCALLOC (symbol_list, 1);
1442 if (crule1)
1443 crule1->next = p;
1444 else
1445 grammar = p;
1446 p->sym = sdummy;
1447 crule1 = XCALLOC (symbol_list, 1);
1448 p->next = crule1;
1449 crule1->next = crule;
1450
1451 /* insert the dummy generated by that rule into this rule. */
1452 nitems++;
1453 p = XCALLOC (symbol_list, 1);
1454 p->sym = sdummy;
1455 p1->next = p;
1456 p1 = p;
1457
1458 actionflag = 0;
1459 }
1460
1461 if (t == IDENTIFIER)
1462 {
1463 nitems++;
1464 p = XCALLOC (symbol_list, 1);
1465 p->sym = symval;
1466 p1->next = p;
1467 p1 = p;
1468 }
1469 else /* handle an action. */
1470 {
1471 copy_action (crule, rulelength);
1472 actionflag = 1;
1473 xactions++; /* JF */
1474 }
1475 rulelength++;
1476 } /* end of read rhs of rule */
1477
1478 /* Put an empty link in the list to mark the end of this rule */
1479 p = XCALLOC (symbol_list, 1);
1480 p1->next = p;
1481 p1 = p;
1482
1483 if (t == PREC)
1484 {
1485 complain (_("two @prec's in a row"));
1486 t = lex ();
1487 crule->ruleprec = symval;
1488 t = lex ();
1489 }
1490 if (t == GUARD)
1491 {
1492 if (!semantic_parser)
1493 complain ("%s",
1494 _
1495 ("%guard present but %semantic_parser not specified"));
1496
1497 copy_guard (crule, rulelength);
1498 t = lex ();
1499 }
1500 else if (t == LEFT_CURLY)
1501 {
1502 /* This case never occurs -wjh */
1503 if (actionflag)
1504 complain (_("two actions at end of one rule"));
1505 copy_action (crule, rulelength);
1506 actionflag = 1;
1507 xactions++; /* -wjh */
1508 t = lex ();
1509 }
1510 /* If $$ is being set in default way, report if any type
1511 mismatch. */
1512 else if (!xactions
1513 && first_rhs && lhs->type_name != first_rhs->type_name)
1514 {
1515 if (lhs->type_name == 0
1516 || first_rhs->type_name == 0
1517 || strcmp (lhs->type_name, first_rhs->type_name))
1518 complain (_("type clash (`%s' `%s') on default action"),
1519 lhs->type_name ? lhs->type_name : "",
1520 first_rhs->type_name ? first_rhs->type_name : "");
1521 }
1522 /* Warn if there is no default for $$ but we need one. */
1523 else if (!xactions && !first_rhs && lhs->type_name != 0)
1524 complain (_("empty rule for typed nonterminal, and no action"));
1525 if (t == SEMICOLON)
1526 t = lex ();
1527 }
1528 #if 0
1529 /* these things can appear as alternatives to rules. */
1530 /* NO, they cannot.
1531 a) none of the documentation allows them
1532 b) most of them scan forward until finding a next %
1533 thus they may swallow lots of intervening rules
1534 */
1535 else if (t == TOKEN)
1536 {
1537 parse_token_decl (STOKEN, SNTERM);
1538 t = lex ();
1539 }
1540 else if (t == NTERM)
1541 {
1542 parse_token_decl (SNTERM, STOKEN);
1543 t = lex ();
1544 }
1545 else if (t == TYPE)
1546 {
1547 t = get_type ();
1548 }
1549 else if (t == UNION)
1550 {
1551 parse_union_decl ();
1552 t = lex ();
1553 }
1554 else if (t == EXPECT)
1555 {
1556 parse_expect_decl ();
1557 t = lex ();
1558 }
1559 else if (t == START)
1560 {
1561 parse_start_decl ();
1562 t = lex ();
1563 }
1564 #endif
1565
1566 else
1567 {
1568 complain (_("invalid input: %s"), token_buffer);
1569 t = lex ();
1570 }
1571 }
1572
1573 /* grammar has been read. Do some checking */
1574
1575 if (nsyms > MAXSHORT)
1576 fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
1577 MAXSHORT);
1578 if (nrules == 0)
1579 fatal (_("no rules in the input grammar"));
1580
1581 if (typed == 0 /* JF put out same default YYSTYPE as YACC does */
1582 && !value_components_used)
1583 {
1584 /* We used to use `unsigned long' as YYSTYPE on MSDOS,
1585 but it seems better to be consistent.
1586 Most programs should declare their own type anyway. */
1587 fprintf (fattrs, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
1588 if (fdefines)
1589 fprintf (fdefines, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
1590 }
1591
1592 /* Report any undefined symbols and consider them nonterminals. */
1593
1594 for (bp = firstsymbol; bp; bp = bp->next)
1595 if (bp->class == SUNKNOWN)
1596 {
1597 complain (_
1598 ("symbol %s is used, but is not defined as a token and has no rules"),
1599 bp->tag);
1600 bp->class = SNTERM;
1601 bp->value = nvars++;
1602 }
1603
1604 ntokens = nsyms - nvars;
1605 }
1606 \f
1607 /*--------------------------------------------------------------.
1608 | For named tokens, but not literal ones, define the name. The |
1609 | value is the user token number. |
1610 `--------------------------------------------------------------*/
1611
1612 static void
1613 output_token_defines (FILE *file)
1614 {
1615 bucket *bp;
1616 char *cp, *symbol;
1617 char c;
1618
1619 for (bp = firstsymbol; bp; bp = bp->next)
1620 {
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)
1632 {
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 }
1639
1640 /* Don't #define nonliteral tokens whose names contain periods. */
1641 cp = symbol;
1642 while ((c = *cp++) && c != '.');
1643 if (c != '\0')
1644 continue;
1645
1646 fprintf (file, "#define\t%s\t%d\n", symbol,
1647 ((translations && !rawtoknumflag)
1648 ? bp->user_token_number : bp->value));
1649 if (semantic_parser)
1650 fprintf (file, "#define\tT%s\t%d\n", symbol, bp->value);
1651 }
1652
1653 putc ('\n', file);
1654 }
1655
1656
1657 /*------------------------------------------------------------------.
1658 | Assign symbol numbers, and write definition of token names into |
1659 | FDEFINES. Set up vectors TAGS and SPREC of names and precedences |
1660 | of symbols. |
1661 `------------------------------------------------------------------*/
1662
1663 static void
1664 packsymbols (void)
1665 {
1666 bucket *bp;
1667 int tokno = 1;
1668 int i;
1669 int last_user_token_number;
1670 static char DOLLAR[] = "$";
1671
1672 /* int lossage = 0; JF set but not used */
1673
1674 tags = XCALLOC (char *, nsyms + 1);
1675 tags[0] = DOLLAR;
1676 user_toknums = XCALLOC (short, nsyms + 1);
1677 user_toknums[0] = 0;
1678
1679 sprec = XCALLOC (short, nsyms);
1680 sassoc = XCALLOC (short, nsyms);
1681
1682 max_user_token_number = 256;
1683 last_user_token_number = 256;
1684
1685 for (bp = firstsymbol; bp; bp = bp->next)
1686 {
1687 if (bp->class == SNTERM)
1688 {
1689 bp->value += ntokens;
1690 }
1691 else if (bp->alias)
1692 {
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++;
1698
1699 if (bp->prec != bp->alias->prec)
1700 {
1701 if (bp->prec != 0 && bp->alias->prec != 0
1702 && bp->user_token_number == SALIAS)
1703 complain (_("conflicting precedences for %s and %s"),
1704 bp->tag, bp->alias->tag);
1705 if (bp->prec != 0)
1706 bp->alias->prec = bp->prec;
1707 else
1708 bp->prec = bp->alias->prec;
1709 }
1710
1711 if (bp->assoc != bp->alias->assoc)
1712 {
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 }
1722
1723 if (bp->user_token_number == SALIAS)
1724 continue; /* do not do processing below for SALIASs */
1725
1726 }
1727 else /* bp->class == STOKEN */
1728 {
1729 bp->value = tokno++;
1730 }
1731
1732 if (bp->class == STOKEN)
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;
1738 }
1739
1740 tags[bp->value] = bp->tag;
1741 user_toknums[bp->value] = bp->user_token_number;
1742 sprec[bp->value] = bp->prec;
1743 sassoc[bp->value] = bp->assoc;
1744
1745 }
1746
1747 if (translations)
1748 {
1749 int j;
1750
1751 token_translations = XCALLOC (short, max_user_token_number + 1);
1752
1753 /* initialize all entries for literal tokens to 2, the internal
1754 token number for $undefined., which represents all invalid
1755 inputs. */
1756 for (j = 0; j <= max_user_token_number; j++)
1757 token_translations[j] = 2;
1758
1759 for (bp = firstsymbol; bp; bp = bp->next)
1760 {
1761 if (bp->value >= ntokens)
1762 continue; /* non-terminal */
1763 if (bp->user_token_number == SALIAS)
1764 continue;
1765 if (token_translations[bp->user_token_number] != 2)
1766 complain (_("tokens %s and %s both assigned number %d"),
1767 tags[token_translations[bp->user_token_number]],
1768 bp->tag, bp->user_token_number);
1769 token_translations[bp->user_token_number] = bp->value;
1770 }
1771 }
1772
1773 error_token_number = errtoken->value;
1774
1775 if (!noparserflag)
1776 output_token_defines (ftable);
1777
1778 if (startval->class == SUNKNOWN)
1779 fatal (_("the start symbol %s is undefined"), startval->tag);
1780 else if (startval->class == STOKEN)
1781 fatal (_("the start symbol %s is a token"), startval->tag);
1782
1783 start_symbol = startval->value;
1784
1785 if (definesflag)
1786 {
1787 output_token_defines (fdefines);
1788
1789 if (!pure_parser)
1790 {
1791 if (spec_name_prefix)
1792 fprintf (fdefines, "\nextern YYSTYPE %slval;\n",
1793 spec_name_prefix);
1794 else
1795 fprintf (fdefines, "\nextern YYSTYPE yylval;\n");
1796 }
1797
1798 if (semantic_parser)
1799 for (i = ntokens; i < nsyms; i++)
1800 {
1801 /* don't make these for dummy nonterminals made by gensym. */
1802 if (*tags[i] != '@')
1803 fprintf (fdefines, "#define\tNT%s\t%d\n", tags[i], i);
1804 }
1805 #if 0
1806 /* `fdefines' is now a temporary file, so we need to copy its
1807 contents in `done', so we can't close it here. */
1808 fclose (fdefines);
1809 fdefines = NULL;
1810 #endif
1811 }
1812 }
1813
1814
1815 /*---------------------------------------------------------------.
1816 | Convert the rules into the representation using RRHS, RLHS and |
1817 | RITEMS. |
1818 `---------------------------------------------------------------*/
1819
1820 static void
1821 packgram (void)
1822 {
1823 int itemno;
1824 int ruleno;
1825 symbol_list *p;
1826
1827 bucket *ruleprec;
1828
1829 ritem = XCALLOC (short, nitems + 1);
1830 rlhs = XCALLOC (short, nrules) - 1;
1831 rrhs = XCALLOC (short, nrules) - 1;
1832 rprec = XCALLOC (short, nrules) - 1;
1833 rprecsym = XCALLOC (short, nrules) - 1;
1834 rassoc = XCALLOC (short, nrules) - 1;
1835
1836 itemno = 0;
1837 ruleno = 1;
1838
1839 p = grammar;
1840 while (p)
1841 {
1842 rlhs[ruleno] = p->sym->value;
1843 rrhs[ruleno] = itemno;
1844 ruleprec = p->ruleprec;
1845
1846 p = p->next;
1847 while (p && p->sym)
1848 {
1849 ritem[itemno++] = p->sym->value;
1850 /* A rule gets by default the precedence and associativity
1851 of the last token in it. */
1852 if (p->sym->class == STOKEN)
1853 {
1854 rprec[ruleno] = p->sym->prec;
1855 rassoc[ruleno] = p->sym->assoc;
1856 }
1857 if (p)
1858 p = p->next;
1859 }
1860
1861 /* If this rule has a %prec,
1862 the specified symbol's precedence replaces the default. */
1863 if (ruleprec)
1864 {
1865 rprec[ruleno] = ruleprec->prec;
1866 rassoc[ruleno] = ruleprec->assoc;
1867 rprecsym[ruleno] = ruleprec->value;
1868 }
1869
1870 ritem[itemno++] = -ruleno;
1871 ruleno++;
1872
1873 if (p)
1874 p = p->next;
1875 }
1876
1877 ritem[itemno] = 0;
1878 }
1879 \f
1880 /*-------------------------------------------------------------------.
1881 | Read in the grammar specification and record it in the format |
1882 | described in gram.h. All guards are copied into the FGUARD file |
1883 | and all actions into FACTION, in each case forming the body of a C |
1884 | function (YYGUARD or YYACTION) which contains a switch statement |
1885 | to decide which guard or action to execute. |
1886 `-------------------------------------------------------------------*/
1887
1888 void
1889 reader (void)
1890 {
1891 start_flag = 0;
1892 startval = NULL; /* start symbol not specified yet. */
1893
1894 #if 0
1895 /* initially assume token number translation not needed. */
1896 translations = 0;
1897 #endif
1898 /* Nowadays translations is always set to 1, since we give `error' a
1899 user-token-number to satisfy the Posix demand for YYERRCODE==256.
1900 */
1901 translations = 1;
1902
1903 nsyms = 1;
1904 nvars = 0;
1905 nrules = 0;
1906 nitems = 0;
1907 rline_allocated = 10;
1908 rline = XCALLOC (short, rline_allocated);
1909
1910 typed = 0;
1911 lastprec = 0;
1912
1913 gensym_count = 0;
1914
1915 semantic_parser = 0;
1916 pure_parser = 0;
1917 yylsp_needed = 0;
1918
1919 grammar = NULL;
1920
1921 init_lex ();
1922 lineno = 1;
1923
1924 /* Initialize the symbol table. */
1925 tabinit ();
1926 /* Construct the error token */
1927 errtoken = getsym ("error");
1928 errtoken->class = STOKEN;
1929 errtoken->user_token_number = 256; /* Value specified by POSIX. */
1930 /* Construct a token that represents all undefined literal tokens.
1931 It is always token number 2. */
1932 undeftoken = getsym ("$undefined.");
1933 undeftoken->class = STOKEN;
1934 undeftoken->user_token_number = 2;
1935
1936 /* Read the declaration section. Copy %{ ... %} groups to FTABLE
1937 and FDEFINES file. Also notice any %token, %left, etc. found
1938 there. */
1939 putc ('\n', ftable);
1940 fprintf (ftable, "\
1941 /* %s, made from %s\n\
1942 by GNU bison %s. */\n\
1943 \n", noparserflag ? "Bison-generated parse tables" : "A Bison parser", infile, VERSION);
1944
1945 fputs ("#define YYBISON 1 /* Identify Bison output. */\n\n", ftable);
1946 read_declarations ();
1947 /* Start writing the guard and action files, if they are needed. */
1948 output_headers ();
1949 /* Read in the grammar, build grammar in list form. Write out
1950 guards and actions. */
1951 readgram ();
1952 /* Now we know whether we need the line-number stack. If we do,
1953 write its type into the .tab.h file. */
1954 if (fdefines)
1955 reader_output_yylsp (fdefines);
1956 /* Write closing delimiters for actions and guards. */
1957 output_trailers ();
1958 if (yylsp_needed)
1959 fputs ("#define YYLSP_NEEDED\n\n", ftable);
1960 /* Assign the symbols their symbol numbers. Write #defines for the
1961 token symbols into FDEFINES if requested. */
1962 packsymbols ();
1963 /* Convert the grammar into the format described in gram.h. */
1964 packgram ();
1965 /* Free the symbol table data structure since symbols are now all
1966 referred to by symbol number. */
1967 free_symtab ();
1968 }
1969
1970 void
1971 reader_output_yylsp (FILE *f)
1972 {
1973 if (yylsp_needed)
1974 fprintf (f, LTYPESTR);
1975 }