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