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