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