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