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