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