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