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