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