]> git.saurik.com Git - bison.git/blame - src/reader.c
(stack_offset;): Change some warni to warns.
[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;
125
126/* Nonzero if any action or guard uses the @n construct. */
127static int yylsp_needed;
128
129extern char *version_string;
130
943819bf
RS
131
132static void
133skip_to_char(target)
134 int target;
135{
136 int c;
137 if (target == '\n')
a083fbbf 138 warn(_(" Skipping to next \\n"));
943819bf 139 else
a083fbbf 140 warni(_(" Skipping to next %c"), target);
943819bf
RS
141
142 do
143 c = skip_white_space();
144 while (c != target && c != EOF);
a083fbbf 145 if (c != EOF)
943819bf
RS
146 ungetc(c, finput);
147}
148
149
1ff442ca
NF
150void
151reader()
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. */
572909b5 193 getsym("$undefined.")->class = STOKEN;
1ff442ca
NF
194 /* Read the declaration section. Copy %{ ... %} groups to ftable and fdefines file.
195 Also notice any %token, %left, etc. found there. */
a083fbbf 196 if (noparserflag)
943819bf
RS
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);
1ff442ca
NF
202 fprintf(ftable, "#define YYBISON 1 /* Identify Bison output. */\n\n");
203 read_declarations();
1ff442ca
NF
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. */
943819bf
RS
210 if (fdefines)
211 reader_output_yylsp(fdefines);
1ff442ca
NF
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
943819bf
RS
226void
227reader_output_yylsp(f)
228 FILE *f;
229{
230 if (yylsp_needed)
231 fprintf(f, LTYPESTR);
232}
1ff442ca
NF
233
234/* read from finput until %% is seen. Discard the %%.
235Handle any % declarations,
236and copy the contents of any %{ ... %} groups to fattrs. */
237
238void
239read_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;
a083fbbf 264
1ff442ca
NF
265 case NTERM:
266 parse_token_decl (SNTERM, STOKEN);
267 break;
a083fbbf 268
1ff442ca
NF
269 case TYPE:
270 parse_type_decl();
271 break;
a083fbbf 272
1ff442ca
NF
273 case START:
274 parse_start_decl();
275 break;
a083fbbf 276
1ff442ca
NF
277 case UNION:
278 parse_union_decl();
279 break;
a083fbbf 280
1ff442ca
NF
281 case EXPECT:
282 parse_expect_decl();
283 break;
943819bf
RS
284 case THONG:
285 parse_thong_decl();
286 break;
1ff442ca
NF
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
943819bf
RS
311 case NOOP:
312 break;
313
1ff442ca 314 default:
a083fbbf 315 warns(_("unrecognized: %s"), token_buffer);
943819bf
RS
316 skip_to_char('%');
317 }
1ff442ca
NF
318 }
319 else if (c == EOF)
a083fbbf 320 fatal(_("no input grammar"));
1ff442ca 321 else
943819bf
RS
322 {
323 char buff[100];
a083fbbf 324 sprintf(buff, _("unknown character: %s"), printable_version(c));
943819bf
RS
325 warn(buff);
326 skip_to_char('%');
327 }
1ff442ca
NF
328 }
329}
330
331
332/* copy the contents of a %{ ... %} into the definitions file.
333The %{ has already been read. Return after reading the %}. */
334
335void
336copy_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;
a083fbbf 363
1ff442ca
NF
364 case '\'':
365 case '"':
366 match = c;
367 putc(c, fattrs);
368 c = getc(finput);
369
370 while (c != match)
371 {
943819bf 372 if (c == EOF)
a083fbbf 373 fatal(_("unterminated string at end of file"));
943819bf
RS
374 if (c == '\n')
375 {
a083fbbf 376 warn(_("unterminated string"));
943819bf
RS
377 ungetc(c, finput);
378 c = match;
379 continue;
380 }
1ff442ca
NF
381
382 putc(c, fattrs);
a083fbbf 383
1ff442ca
NF
384 if (c == '\\')
385 {
386 c = getc(finput);
387 if (c == EOF)
a083fbbf 388 fatal(_("unterminated string at end of file"));
1ff442ca
NF
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)
a083fbbf 437 fatal(_("unterminated comment in `%{' definition"));
1ff442ca
NF
438 else
439 {
440 putc(c, fattrs);
441 c = getc(finput);
442 }
443 }
444
445 break;
446
447 case EOF:
a083fbbf 448 fatal(_("unterminated `%{' definition"));
1ff442ca
NF
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.
471For %token, what_is is STOKEN and what_is_not is SNTERM.
472For %nterm, the arguments are reversed. */
473
474void
475parse_token_decl (what_is, what_is_not)
476 int what_is, what_is_not;
477{
1ff442ca 478 register int token = 0;
1ff442ca 479 register char *typename = 0;
943819bf 480 register struct bucket *symbol = NULL; /* pts to symbol being defined */
1ff442ca
NF
481 int k;
482
1ff442ca
NF
483 for (;;)
484 {
485 if(ungetc(skip_white_space(), finput) == '%')
486 return;
1ff442ca
NF
487 token = lex();
488 if (token == COMMA)
943819bf
RS
489 {
490 symbol = NULL;
491 continue;
492 }
1ff442ca
NF
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;
943819bf
RS
499 symbol = NULL;
500 }
501 else if (token == IDENTIFIER && *symval->tag == '\"'
a083fbbf 502 && symbol)
943819bf
RS
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
a083fbbf
RS
510 symval->alias = symbol;
511 symbol->alias = symval;
943819bf
RS
512 symbol = NULL;
513
514 nsyms--; /* symbol and symval combined are only one symbol */
1ff442ca
NF
515 }
516 else if (token == IDENTIFIER)
517 {
518 int oldclass = symval->class;
943819bf 519 symbol = symval;
1ff442ca 520
943819bf 521 if (symbol->class == what_is_not)
a083fbbf 522 warns(_("symbol %s redefined"), symbol->tag);
943819bf 523 symbol->class = what_is;
1ff442ca 524 if (what_is == SNTERM && oldclass != SNTERM)
943819bf 525 symbol->value = nvars++;
1ff442ca
NF
526
527 if (typename)
528 {
943819bf
RS
529 if (symbol->type_name == NULL)
530 symbol->type_name = typename;
531 else if (strcmp(typename, symbol->type_name) != 0)
a083fbbf 532 warns(_("type redeclaration for %s"), symbol->tag);
1ff442ca
NF
533 }
534 }
943819bf 535 else if (symbol && token == NUMBER)
1ff442ca 536 {
943819bf 537 symbol->user_token_number = numval;
1ff442ca
NF
538 translations = 1;
539 }
540 else
943819bf 541 {
a083fbbf
RS
542 warnss(_("`%s' is invalid in %s"),
543 token_buffer,
943819bf
RS
544 (what_is == STOKEN) ? "%token" : "%nterm");
545 skip_to_char('%');
546 }
1ff442ca
NF
547 }
548
549}
550
a083fbbf 551/* parse what comes after %thong
943819bf
RS
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.
a083fbbf 562
943819bf
RS
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
568void
569parse_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
a083fbbf 588 if (token != IDENTIFIER)
943819bf 589 {
a083fbbf 590 warns(_("unrecognized item %s, expected an identifier"),
943819bf
RS
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 */
a083fbbf 601
943819bf
RS
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
a083fbbf 610 if (token != IDENTIFIER || *symval->tag != '\"')
943819bf 611 {
a083fbbf 612 warns(_("expected string constant instead of %s"),
943819bf
RS
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
a083fbbf
RS
621 symval->alias = symbol;
622 symbol->alias = symval;
943819bf
RS
623
624 nsyms--; /* symbol and symval combined are only one symbol */
625}
1ff442ca
NF
626
627
628/* parse what comes after %start */
629
630void
631parse_start_decl ()
632{
633 if (start_flag)
a083fbbf 634 warn(_("multiple %start declarations"));
1ff442ca 635 if (lex() != IDENTIFIER)
a083fbbf 636 warn(_("invalid %start declaration"));
943819bf
RS
637 else
638 {
639 start_flag = 1;
640 startval = symval;
641 }
1ff442ca
NF
642}
643
644
645
646/* read in a %type declaration and record its information for get_type_name to access */
647
648void
649parse_type_decl ()
650{
651 register int k;
652 register char *name;
1ff442ca
NF
653
654 if (lex() != TYPENAME)
943819bf 655 {
a083fbbf 656 warn(_("%type declaration has no <typename>"));
943819bf
RS
657 skip_to_char('%');
658 return;
659 }
1ff442ca
NF
660
661 k = strlen(token_buffer);
662 name = NEW2(k + 1, char);
663 strcpy(name, token_buffer);
664
1ff442ca
NF
665 for (;;)
666 {
667 register int t;
668
669 if(ungetc(skip_white_space(), finput) == '%')
670 return;
671
1ff442ca
NF
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;
943819bf 684 else if (strcmp(name, symval->type_name) != 0)
a083fbbf 685 warns(_("type redeclaration for %s"), symval->tag);
1ff442ca
NF
686
687 break;
688
689 default:
a083fbbf 690 warns(_("invalid %%type declaration due to item: `%s'"), token_buffer);
943819bf 691 skip_to_char('%');
1ff442ca
NF
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
701void
702parse_assoc_decl (assoc)
703int assoc;
704{
705 register int k;
706 register char *name = NULL;
943819bf 707 register int prev = 0;
1ff442ca
NF
708
709 lastprec++; /* Assign a new precedence level, never 0. */
710
1ff442ca
NF
711 for (;;)
712 {
713 register int t;
714
715 if(ungetc(skip_white_space(), finput) == '%')
716 return;
717
1ff442ca
NF
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)
a083fbbf 734 warns(_("redefining precedence of %s"), symval->tag);
1ff442ca
NF
735 symval->prec = lastprec;
736 symval->assoc = assoc;
737 if (symval->class == SNTERM)
a083fbbf 738 warns(_("symbol %s redefined"), symval->tag);
1ff442ca
NF
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;
943819bf 744 else if (strcmp(name, symval->type_name) != 0)
a083fbbf 745 warns(_("type redeclaration for %s"), symval->tag);
1ff442ca
NF
746 }
747 break;
748
749 case NUMBER:
750 if (prev == IDENTIFIER)
751 {
752 symval->user_token_number = numval;
753 translations = 1;
754 }
a083fbbf 755 else
943819bf 756 {
a083fbbf 757 warns(_("invalid text (%s) - number should be after identifier"),
943819bf
RS
758 token_buffer);
759 skip_to_char('%');
760 }
1ff442ca
NF
761 break;
762
763 case SEMICOLON:
764 return;
765
766 default:
a083fbbf 767 warns(_("unexpected item: %s"), token_buffer);
943819bf 768 skip_to_char('%');
1ff442ca
NF
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
782void
783parse_union_decl()
784{
785 register int c;
786 register int count;
787 register int in_comment;
788 int cplus_comment;
789
790 if (typed)
a083fbbf 791 warn(_("multiple %union declarations"));
1ff442ca
NF
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)
a083fbbf 849 fatal(_("unterminated comment at end of file"));
1ff442ca
NF
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)
a083fbbf 875 warn (_("unmatched close-brace (`}')"));
1ff442ca 876 count--;
943819bf 877 if (count <= 0)
1ff442ca
NF
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
896void
897parse_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
943819bf 918 if (count <= 0 || count > 10)
a083fbbf 919 warn(_("argument of %expect is not an integer"));
1ff442ca
NF
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
927char *
928get_type_name(n, rule)
929int n;
930symbol_list *rule;
931{
a083fbbf 932 static char *msg = N_("invalid $ value");
1ff442ca
NF
933
934 register int i;
935 register symbol_list *rp;
936
937 if (n < 0)
943819bf 938 {
a083fbbf 939 warn(_(msg));
943819bf
RS
940 return NULL;
941 }
1ff442ca
NF
942
943 rp = rule;
944 i = 0;
945
946 while (i < n)
947 {
948 rp = rp->next;
949 if (rp == NULL || rp->sym == NULL)
943819bf 950 {
a083fbbf 951 warn(_(msg));
943819bf
RS
952 return NULL;
953 }
1ff442ca
NF
954 i++;
955 }
956
957 return (rp->sym->type_name);
958}
959
960
1ff442ca
NF
961/* after %guard is seen in the input file,
962copy the actual guard into the guards file.
963If the guard is followed by an action, copy that into the actions file.
964stack_offset is the number of values in the current rule so far,
965which says where to find $0 with respect to the top of the stack,
966for the simple parser in which the stack is not popped until after the guard is run. */
967
968void
969copy_guard(rule, stack_offset)
970symbol_list *rule;
971int 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--;
a083fbbf 1012 else
943819bf 1013 {
a083fbbf 1014 warn(_("unmatched right brace (`}')"));
943819bf
RS
1015 c = getc(finput); /* skip it */
1016 }
1ff442ca
NF
1017 break;
1018
1019 case '\'':
1020 case '"':
1021 match = c;
1022 putc(c, fguard);
1023 c = getc(finput);
1024
1025 while (c != match)
1026 {
943819bf 1027 if (c == EOF)
a083fbbf
RS
1028 fatal(_("unterminated string at end of file"));
1029 if (c == '\n')
943819bf 1030 {
a083fbbf 1031 warn(_("unterminated string"));
943819bf
RS
1032 ungetc(c, finput);
1033 c = match; /* invent terminator */
1034 continue;
1035 }
1ff442ca
NF
1036
1037 putc(c, fguard);
a083fbbf 1038
1ff442ca
NF
1039 if (c == '\\')
1040 {
1041 c = getc(finput);
1042 if (c == EOF)
a083fbbf 1043 fatal(_("unterminated string"));
1ff442ca
NF
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)
a083fbbf 1092 fatal(_("unterminated comment"));
1ff442ca
NF
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);
943819bf 1124 if(!type_name && typed)
a083fbbf 1125 warns(_("$$ of `%s' has no declared type"), rule->sym->tag);
1ff442ca
NF
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);
943819bf 1140 if(!type_name && typed)
a083fbbf 1141 warnss(_("$%s of `%s' has no declared type"), int_to_string(n), rule->sym->tag);
1ff442ca
NF
1142 continue;
1143 }
1144 else
aba5ca6d 1145 warns(_("$%s is invalid"), printable_version(c));
1ff442ca
NF
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
943819bf 1158 {
aba5ca6d 1159 warns(_("@%s is invalid"), printable_version(c));
943819bf
RS
1160 n = 1;
1161 }
1ff442ca
NF
1162
1163 fprintf(fguard, "yylsp[%d]", n - stack_offset);
1164 yylsp_needed = 1;
1165
1166 continue;
1167
1168 case EOF:
a083fbbf 1169 fatal(_("unterminated %%guard clause"));
1ff442ca
NF
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 {
943819bf 1186 c = getc(finput); /* why not skip_white_space -wjh */
1ff442ca
NF
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 }
1197into the actions file.
1198stack_offset is the number of values in the current rule so far,
1199which says where to find $0 with respect to the top of the stack. */
1200
1201void
1202copy_action(rule, stack_offset)
1203symbol_list *rule;
1204int 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 {
943819bf
RS
1249 if (c == '\n')
1250 {
a083fbbf 1251 warn(_("unterminated string"));
943819bf
RS
1252 ungetc(c, finput);
1253 c = match;
1254 continue;
1255 }
1256 else if (c == EOF)
a083fbbf 1257 fatal(_("unterminated string at end of file"));
1ff442ca
NF
1258
1259 putc(c, faction);
1260
1261 if (c == '\\')
1262 {
1263 c = getc(finput);
1264 if (c == EOF)
a083fbbf 1265 fatal(_("unterminated string"));
1ff442ca
NF
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)
a083fbbf 1314 fatal(_("unterminated comment"));
1ff442ca
NF
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);
a083fbbf
RS
1346 if(!type_name && typed)
1347 warns(_("$$ of `%s' has no declared type"), rule->sym->tag);
1ff442ca
NF
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);
a083fbbf
RS
1361 if(!type_name && typed)
1362 warnss(_("$%s of `%s' has no declared type"),
943819bf 1363 int_to_string(n), rule->sym->tag);
1ff442ca
NF
1364 continue;
1365 }
1366 else
aba5ca6d 1367 warns(_("$%s is invalid"), printable_version(c));
1ff442ca
NF
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
943819bf 1380 {
a083fbbf 1381 warn(_("invalid @-construct"));
943819bf
RS
1382 n = 1;
1383 }
1ff442ca
NF
1384
1385 fprintf(faction, "yylsp[%d]", n - stack_offset);
1386 yylsp_needed = 1;
1387
1388 continue;
1389
1390 case EOF:
a083fbbf 1391 fatal(_("unmatched `{'"));
1ff442ca
NF
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,
1415whose name cannot conflict with the user's names. */
1416
1417bucket *
1418gensym()
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.
1430Each rule is represented by a sequence of symbols: the left hand side
1431followed by the contents of the right hand side, followed by a null pointer
1432instead of a symbol to terminate the rule.
1433The next symbol is the lhs of the following rule.
1434
1435All guards and actions are copied out to the appropriate files,
1436labelled by the rule number they apply to. */
1437
1438void
1439readgram()
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;
943819bf
RS
1467
1468 if (!start_flag)
1469 {
1470 startval = lhs;
1471 start_flag = 1;
1472 }
a083fbbf 1473
1ff442ca
NF
1474 t = lex();
1475 if (t != COLON)
943819bf 1476 {
a083fbbf 1477 warn(_("ill-formed rule: initial symbol not followed by colon"));
943819bf
RS
1478 unlex(t);
1479 }
1ff442ca
NF
1480 }
1481
943819bf 1482 if (nrules == 0 && t == BAR)
1ff442ca 1483 {
a083fbbf 1484 warn(_("grammar starts with vertical bar"));
943819bf 1485 lhs = symval; /* BOGUS: use a random symval */
1ff442ca 1486 }
1ff442ca
NF
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)
a083fbbf 1515 warns(_("rule given for %s, which is a token"), lhs->tag);
1ff442ca
NF
1516
1517 /* read the rhs of the rule. */
1518
1519 for (;;)
1520 {
1521 t = lex();
943819bf
RS
1522 if (t == PREC)
1523 {
1524 t = lex();
1525 crule->ruleprec = symval;
1526 t = lex();
1527 }
1ff442ca
NF
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 */
943819bf 1558 /* number, we must give the new rule this number */
1ff442ca
NF
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++;
943819bf 1604 } /* end of read rhs of rule */
1ff442ca
NF
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 {
a083fbbf 1613 warn(_("two @prec's in a row"));
1ff442ca
NF
1614 t = lex();
1615 crule->ruleprec = symval;
1616 t = lex();
1617 }
1618 if (t == GUARD)
1619 {
1620 if (! semantic_parser)
a083fbbf 1621 warn(_("%%guard present but %%semantic_parser not specified"));
1ff442ca
NF
1622
1623 copy_guard(crule, rulelength);
1624 t = lex();
1625 }
1626 else if (t == LEFT_CURLY)
1627 {
943819bf 1628 /* This case never occurs -wjh */
a083fbbf 1629 if (actionflag) warn(_("two actions at end of one rule"));
1ff442ca 1630 copy_action(crule, rulelength);
943819bf
RS
1631 actionflag = 1;
1632 xactions++; /* -wjh */
1ff442ca
NF
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))
a083fbbf 1641 warnss(_("type clash (`%s' `%s') on default action"),
1ff442ca
NF
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)
a083fbbf 1647 warn(_("empty rule for typed nonterminal, and no action"));
1ff442ca
NF
1648 if (t == SEMICOLON)
1649 t = lex();
a083fbbf 1650 }
943819bf
RS
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*/
1ff442ca
NF
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 }
943819bf
RS
1687#endif
1688
1ff442ca 1689 else
943819bf 1690 {
a083fbbf 1691 warns(_("invalid input: %s"), token_buffer);
943819bf
RS
1692 t = lex();
1693 }
1ff442ca
NF
1694 }
1695
943819bf
RS
1696 /* grammar has been read. Do some checking */
1697
1ff442ca 1698 if (nsyms > MAXSHORT)
a083fbbf 1699 fatals(_("too many symbols (tokens plus nonterminals); maximum %s"),
943819bf 1700 int_to_string(MAXSHORT));
1ff442ca 1701 if (nrules == 0)
a083fbbf 1702 fatal(_("no rules in the input grammar"));
1ff442ca
NF
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 {
a083fbbf 1720 warns(_("symbol %s is used, but is not defined as a token and has no rules"),
1ff442ca 1721 bp->tag);
1ff442ca
NF
1722 bp->class = SNTERM;
1723 bp->value = nvars++;
1724 }
1725
1726 ntokens = nsyms - nvars;
1727}
1728
1729
1730void
1731record_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;
9a1af7e6 1738 rline = (short *) xrealloc (rline,
943819bf 1739 rline_allocated * sizeof (short));
1ff442ca
NF
1740 }
1741 rline[nrules] = lineno;
1742}
1743
1744
1745/* read in a %type declaration and record its information for get_type_name to access */
943819bf
RS
1746/* this is unused. it is only called from the #if 0 part of readgram */
1747static int
1ff442ca
NF
1748get_type()
1749{
1750 register int k;
1751 register int t;
1752 register char *name;
1753
1754 t = lex();
1755
a083fbbf 1756 if (t != TYPENAME)
943819bf 1757 {
a083fbbf 1758 warn(_("ill-formed %type declaration"));
943819bf
RS
1759 return t;
1760 }
1ff442ca
NF
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;
943819bf 1781 else if (strcmp(name, symval->type_name) != 0)
a083fbbf 1782 warns(_("type redeclaration for %s"), symval->tag);
1ff442ca
NF
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.
1795Set up vectors tags and sprec of names and precedences of symbols. */
1796
1797void
1798packsymbols()
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] = "$";
943819bf
RS
1809 user_toknums = NEW2(nsyms + 1, int);
1810 user_toknums[0] = 0;
1ff442ca
NF
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 }
943819bf
RS
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
a083fbbf 1828 check agreement of ->prec and ->assoc fields
943819bf
RS
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)
a083fbbf 1837 warnss(_("conflicting precedences for %s and %s"),
943819bf
RS
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)
a083fbbf 1846 warnss(_("conflicting assoc values for %s and %s"),
943819bf
RS
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)
1ff442ca
NF
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;
1ff442ca
NF
1867 }
1868
1869 tags[bp->value] = bp->tag;
943819bf 1870 user_toknums[bp->value] = bp->user_token_number;
1ff442ca
NF
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,
572909b5
RS
1883 the internal token number for $undefined.,
1884 which represents all invalid inputs. */
1ff442ca 1885 for (i = 0; i <= max_user_token_number; i++)
a083fbbf 1886 token_translations[i] = 2;
1ff442ca 1887
943819bf
RS
1888 for (bp = firstsymbol; bp; bp = bp->next)
1889 {
1890 if (bp->value >= ntokens) continue; /* non-terminal */
a083fbbf 1891 if (bp->user_token_number == SALIAS) continue;
943819bf 1892 if (token_translations[bp->user_token_number] != 2)
a083fbbf 1893 warnsss(_("tokens %s and %s both assigned number %s"),
1ff442ca
NF
1894 tags[token_translations[bp->user_token_number]],
1895 bp->tag,
943819bf
RS
1896 int_to_string(bp->user_token_number));
1897 token_translations[bp->user_token_number] = bp->value;
1898 }
1ff442ca
NF
1899 }
1900
1901 error_token_number = errtoken->value;
1902
943819bf
RS
1903 if (! noparserflag)
1904 output_token_defines(ftable);
1ff442ca
NF
1905
1906 if (startval->class == SUNKNOWN)
a083fbbf 1907 fatals(_("the start symbol %s is undefined"), startval->tag);
1ff442ca 1908 else if (startval->class == STOKEN)
a083fbbf 1909 fatals(_("the start symbol %s is a token"), startval->tag);
1ff442ca
NF
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}
a083fbbf
RS
1940
1941/* For named tokens, but not literal ones, define the name.
1942 The value is the user token number.
943819bf 1943*/
1ff442ca
NF
1944void
1945output_token_defines(file)
1946FILE *file;
1947{
1948 bucket *bp;
943819bf
RS
1949 register char *cp, *symbol;
1950 register char c;
1ff442ca
NF
1951
1952 for (bp = firstsymbol; bp; bp = bp->next)
1953 {
943819bf 1954 symbol = bp->tag; /* get symbol */
1ff442ca 1955
943819bf
RS
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 */
a083fbbf 1960 if ('\"' == *symbol)
1ff442ca 1961 {
943819bf
RS
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 }
1ff442ca 1968
943819bf
RS
1969 /* Don't #define nonliteral tokens whose names contain periods. */
1970 cp = symbol;
1971 while ((c = *cp++) && c != '.');
1972 if (c != '\0') continue;
1ff442ca 1973
943819bf 1974 fprintf(file, "#define\t%s\t%d\n", symbol,
a083fbbf
RS
1975 ((translations && ! rawtoknumflag)
1976 ? bp->user_token_number
943819bf
RS
1977 : bp->value));
1978 if (semantic_parser)
1979 fprintf(file, "#define\tT%s\t%d\n", symbol, bp->value);
1ff442ca
NF
1980 }
1981
1982 putc('\n', file);
1983}
1984
1985
1986
1987/* convert the rules into the representation using rrhs, rlhs and ritems. */
1988
1989void
1990packgram()
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
2050int
2051read_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}