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