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