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