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