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