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