]>
git.saurik.com Git - bison.git/blob - src/reader.c
3f7cb0e347098e384b80b423a835196511c50eae
1 /* Input parser for bison
2 Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
4 This file is part of Bison, the GNU Compiler Compiler.
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)
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.
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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.
26 The entry point is reader(). */
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"
43 /* Number of slots allocated (but not necessarily used yet) in `rline' */
46 extern char *program_name
;
47 extern int definesflag
;
48 extern int nolinesflag
;
49 extern bucket
*symval
;
52 extern int expected_conflicts
;
53 extern char *token_buffer
;
57 extern void init_lex();
58 extern void tabinit();
59 extern void output_headers();
60 extern void output_trailers();
61 extern void free_symtab();
62 extern void open_extra_files();
68 extern int skip_white_space();
69 extern int parse_percent_token();
72 void read_declarations();
73 void copy_definition();
74 void parse_token_decl();
75 void parse_start_decl();
76 void parse_type_decl();
77 void parse_assoc_decl();
78 void parse_union_decl();
79 void parse_expect_decl();
82 void record_rule_line();
84 void output_token_defines();
86 int read_signed_integer();
92 struct symbol_list
*next
;
101 symbol_list
*grammar
;
106 /* Nonzero if components of semantic values are used, implying
107 they must be unions. */
108 static int value_components_used
;
110 static int typed
; /* nonzero if %union has been seen. */
112 static int lastprec
; /* incremented for each %left, %right or %nonassoc seen */
114 static int gensym_count
; /* incremented for each generated symbol */
116 static bucket
*errtoken
;
118 /* Nonzero if any action or guard uses the @n construct. */
119 static int yylsp_needed
;
121 extern char *version_string
;
127 startval
= NULL
; /* start symbol not specified yet. */
130 translations
= 0; /* initially assume token number translation not needed. */
132 /* Nowadays translations is always set to 1,
133 since we give `error' a user-token-number
134 to satisfy the Posix demand for YYERRCODE==256. */
141 rline_allocated
= 10;
142 rline
= NEW2(rline_allocated
, short);
158 /* initialize the symbol table. */
160 /* construct the error token */
161 errtoken
= getsym("error");
162 errtoken
->class = STOKEN
;
163 errtoken
->user_token_number
= 256; /* Value specified by posix. */
164 /* construct a token that represents all undefined literal tokens. */
165 /* it is always token number 2. */
166 getsym("$illegal.")->class = STOKEN
;
167 /* Read the declaration section. Copy %{ ... %} groups to ftable and fdefines file.
168 Also notice any %token, %left, etc. found there. */
169 fprintf(ftable
, "\n/* A Bison parser, made from %s", infile
);
170 fprintf(ftable
, " with Bison version %s */\n\n", version_string
);
171 fprintf(ftable
, "#define YYBISON 1 /* Identify Bison output. */\n\n");
173 /* output the definition of YYLTYPE into the fattrs and fdefines files. */
174 /* fattrs winds up in the .tab.c file, before bison.simple. */
175 fprintf(fattrs
, LTYPESTR
);
176 /* start writing the guard and action files, if they are needed. */
178 /* read in the grammar, build grammar in list form. write out guards and actions. */
180 /* Now we know whether we need the line-number stack.
181 If we do, write its type into the .tab.h file. */
185 fprintf(fdefines
, LTYPESTR
);
187 /* write closing delimiters for actions and guards. */
190 fprintf(ftable
, "#define YYLSP_NEEDED\n\n");
191 /* assign the symbols their symbol numbers.
192 Write #defines for the token symbols into fdefines if requested. */
194 /* convert the grammar into the format described in gram.h. */
196 /* free the symbol table data structure
197 since symbols are now all referred to by symbol number. */
203 /* read from finput until %% is seen. Discard the %%.
204 Handle any % declarations,
205 and copy the contents of any %{ ... %} groups to fattrs. */
215 c
= skip_white_space();
219 tok
= parse_percent_token();
226 case PERCENT_LEFT_CURLY
:
231 parse_token_decl (STOKEN
, SNTERM
);
235 parse_token_decl (SNTERM
, STOKEN
);
255 parse_assoc_decl(LEFT_ASSOC
);
259 parse_assoc_decl(RIGHT_ASSOC
);
263 parse_assoc_decl(NON_ASSOC
);
266 case SEMANTIC_PARSER
:
267 if (semantic_parser
== 0)
279 fatal("junk after `%%' in definition section");
283 fatal("no input grammar");
284 else if (c
>= 040 && c
<= 0177)
285 fatals ("unknown character `%c' in declaration section", c
);
287 fatals ("unknown character with code 0x%x in declaration section", c
);
292 /* copy the contents of a %{ ... %} into the definitions file.
293 The %{ has already been read. Return after reading the %}. */
301 register int after_percent
; /* -1 while reading a character if prev char was % */
305 fprintf(fattrs
, "#line %d \"%s\"\n", lineno
, infile
);
332 if (c
== EOF
|| c
== '\n')
333 fatal("unterminated string");
341 fatal("unterminated string");
356 if (c
!= '*' && c
!= '/')
359 cplus_comment
= (c
== '/');
366 if (!cplus_comment
&& c
== '*')
390 fatal("unterminated comment in `%{' definition");
401 fatal("unterminated `%{' definition");
423 /* parse what comes after %token or %nterm.
424 For %token, what_is is STOKEN and what_is_not is SNTERM.
425 For %nterm, the arguments are reversed. */
428 parse_token_decl (what_is
, what_is_not
)
429 int what_is
, what_is_not
;
431 /* register int start_lineno; JF */
432 register int token
= 0;
434 register char *typename
= 0;
437 /* start_lineno = lineno; JF */
441 if(ungetc(skip_white_space(), finput
) == '%')
444 /* if (lineno != start_lineno)
447 /* we have not passed a newline, so the token now starting is in this declaration */
453 if (token
== TYPENAME
)
455 k
= strlen(token_buffer
);
456 typename
= NEW2(k
+ 1, char);
457 strcpy(typename
, token_buffer
);
458 value_components_used
= 1;
460 else if (token
== IDENTIFIER
)
462 int oldclass
= symval
->class;
464 if (symval
->class == what_is_not
)
465 fatals("symbol %s redefined", symval
->tag
);
466 symval
->class = what_is
;
467 if (what_is
== SNTERM
&& oldclass
!= SNTERM
)
468 symval
->value
= nvars
++;
472 if (symval
->type_name
== NULL
)
473 symval
->type_name
= typename
;
475 fatals("type redeclaration for %s", symval
->tag
);
478 else if (prev
== IDENTIFIER
&& token
== NUMBER
)
480 symval
->user_token_number
= numval
;
484 fatal("invalid text in %token or %nterm declaration");
491 /* parse what comes after %start */
497 fatal("multiple %start declarations");
499 if (lex() != IDENTIFIER
)
500 fatal("invalid %start declaration");
506 /* read in a %type declaration and record its information for get_type_name to access */
513 /* register int start_lineno; JF */
515 if (lex() != TYPENAME
)
516 fatal("ill-formed %type declaration");
518 k
= strlen(token_buffer
);
519 name
= NEW2(k
+ 1, char);
520 strcpy(name
, token_buffer
);
522 /* start_lineno = lineno; */
528 if(ungetc(skip_white_space(), finput
) == '%')
531 /* if (lineno != start_lineno)
534 /* we have not passed a newline, so the token now starting is in this declaration */
546 if (symval
->type_name
== NULL
)
547 symval
->type_name
= name
;
549 fatals("type redeclaration for %s", symval
->tag
);
554 fatal("invalid %type declaration");
561 /* read in a %left, %right or %nonassoc declaration and record its information. */
562 /* assoc is either LEFT_ASSOC, RIGHT_ASSOC or NON_ASSOC. */
565 parse_assoc_decl (assoc
)
569 register char *name
= NULL
;
570 /* register int start_lineno; JF */
571 register int prev
= 0; /* JF added = 0 to keep lint happy */
573 lastprec
++; /* Assign a new precedence level, never 0. */
575 /* start_lineno = lineno; */
581 if(ungetc(skip_white_space(), finput
) == '%')
584 /* if (lineno != start_lineno)
587 /* we have not passed a newline, so the token now starting is in this declaration */
595 k
= strlen(token_buffer
);
596 name
= NEW2(k
+ 1, char);
597 strcpy(name
, token_buffer
);
604 if (symval
->prec
!= 0)
605 fatals("redefining precedence of %s", symval
->tag
);
606 symval
->prec
= lastprec
;
607 symval
->assoc
= assoc
;
608 if (symval
->class == SNTERM
)
609 fatals("symbol %s redefined", symval
->tag
);
610 symval
->class = STOKEN
;
612 { /* record the type, if one is specified */
613 if (symval
->type_name
== NULL
)
614 symval
->type_name
= name
;
616 fatals("type redeclaration for %s", symval
->tag
);
621 if (prev
== IDENTIFIER
)
623 symval
->user_token_number
= numval
;
627 fatal("invalid text in association declaration");
634 fatal("malformatted association declaration");
644 /* copy the union declaration into fattrs (and fdefines),
645 where it is made into the
646 definition of YYSTYPE, the type of elements of the parser value stack. */
653 register int in_comment
;
657 fatal("multiple %union declarations");
662 fprintf(fattrs
, "\n#line %d \"%s\"\n", lineno
, infile
);
664 fprintf(fattrs
, "\n");
666 fprintf(fattrs
, "typedef union");
668 fprintf(fdefines
, "typedef union");
689 if (c
!= '*' && c
!= '/')
696 cplus_comment
= (c
== '/');
715 fatal("unterminated comment");
717 if (!cplus_comment
&& c
== '*')
741 fatal ("unmatched close-brace (`}')");
745 fprintf(fattrs
, " YYSTYPE;\n");
747 fprintf(fdefines
, " YYSTYPE;\n");
748 /* JF don't choke on trailing semi */
749 c
=skip_white_space();
750 if(c
!=';') ungetc(c
,finput
);
759 /* parse the declaration %expect N which says to expect N
760 shift-reduce conflicts. */
770 while (c
== ' ' || c
== '\t')
774 while (c
>= '0' && c
<= '9')
784 expected_conflicts
= atoi (buffer
);
787 /* that's all of parsing the declaration section */
789 /* Get the data type (alternative in the union) of the value for symbol n in rule rule. */
792 get_type_name(n
, rule
)
796 static char *msg
= "invalid $ value";
799 register symbol_list
*rp
;
810 if (rp
== NULL
|| rp
->sym
== NULL
)
815 return (rp
->sym
->type_name
);
820 /* after %guard is seen in the input file,
821 copy the actual guard into the guards file.
822 If the guard is followed by an action, copy that into the actions file.
823 stack_offset is the number of values in the current rule so far,
824 which says where to find $0 with respect to the top of the stack,
825 for the simple parser in which the stack is not popped until after the guard is run. */
828 copy_guard(rule
, stack_offset
)
837 register char *type_name
;
841 /* offset is always 0 if parser has already popped the stack pointer */
842 if (semantic_parser
) stack_offset
= 0;
844 fprintf(fguard
, "\ncase %d:\n", nrules
);
846 fprintf(fguard
, "#line %d \"%s\"\n", lineno
, infile
);
852 while (brace_flag
? (count
> 0) : (c
!= ';'))
872 fatal("unmatched right brace ('}')");
883 if (c
== EOF
|| c
== '\n')
884 fatal("unterminated string");
892 fatal("unterminated string");
907 if (c
!= '*' && c
!= '/')
910 cplus_comment
= (c
== '/');
917 if (!cplus_comment
&& c
== '*')
941 fatal("unterminated comment");
957 register char *cp
= token_buffer
;
959 while ((c
= getc(finput
)) != '>' && c
> 0)
962 type_name
= token_buffer
;
969 fprintf(fguard
, "yyval");
970 if (!type_name
) type_name
= rule
->sym
->type_name
;
972 fprintf(fguard
, ".%s", type_name
);
973 if(!type_name
&& typed
) /* JF */
974 fprintf(stderr
,"%s:%d: warning: $$ of '%s' has no declared type.\n",infile
,lineno
,rule
->sym
->tag
);
977 else if (isdigit(c
) || c
== '-')
980 n
= read_signed_integer(finput
);
983 if (!type_name
&& n
> 0)
984 type_name
= get_type_name(n
, rule
);
986 fprintf(fguard
, "yyvsp[%d]", n
- stack_offset
);
988 fprintf(fguard
, ".%s", type_name
);
989 if(!type_name
&& typed
) /* JF */
990 fprintf(stderr
,"%s:%d: warning: $%d of '%s' has no declared type.\n",infile
,lineno
,n
,rule
->sym
->tag
);
994 fatals("$%c is invalid",c
); /* JF changed style */
1000 if (isdigit(c
) || c
== '-')
1003 n
= read_signed_integer(finput
);
1007 fatals("@%c is invalid",c
); /* JF changed style */
1009 fprintf(fguard
, "yylsp[%d]", n
- stack_offset
);
1015 fatal("unterminated %guard clause");
1021 if (c
!= '}' || count
!= 0)
1025 c
= skip_white_space();
1027 fprintf(fguard
, ";\n break;}");
1029 copy_action(rule
, stack_offset
);
1034 copy_action(rule
, stack_offset
);
1042 /* Assuming that a { has just been seen, copy everything up to the matching }
1043 into the actions file.
1044 stack_offset is the number of values in the current rule so far,
1045 which says where to find $0 with respect to the top of the stack. */
1048 copy_action(rule
, stack_offset
)
1057 register char *type_name
;
1060 /* offset is always 0 if parser has already popped the stack pointer */
1061 if (semantic_parser
) stack_offset
= 0;
1063 fprintf(faction
, "\ncase %d:\n", nrules
);
1065 fprintf(faction
, "#line %d \"%s\"\n", lineno
, infile
);
1095 if (c
== EOF
|| c
== '\n')
1096 fatal("unterminated string");
1104 fatal("unterminated string");
1119 if (c
!= '*' && c
!= '/')
1122 cplus_comment
= (c
== '/');
1129 if (!cplus_comment
&& c
== '*')
1153 fatal("unterminated comment");
1169 register char *cp
= token_buffer
;
1171 while ((c
= getc(finput
)) != '>' && c
> 0)
1174 type_name
= token_buffer
;
1175 value_components_used
= 1;
1181 fprintf(faction
, "yyval");
1182 if (!type_name
) type_name
= get_type_name(0, rule
);
1184 fprintf(faction
, ".%s", type_name
);
1185 if(!type_name
&& typed
) /* JF */
1186 fprintf(stderr
,"%s:%d: warning: $$ of '%s' has no declared type.\n",infile
,lineno
,rule
->sym
->tag
);
1188 else if (isdigit(c
) || c
== '-')
1191 n
= read_signed_integer(finput
);
1194 if (!type_name
&& n
> 0)
1195 type_name
= get_type_name(n
, rule
);
1197 fprintf(faction
, "yyvsp[%d]", n
- stack_offset
);
1199 fprintf(faction
, ".%s", type_name
);
1200 if(!type_name
&& typed
) /* JF */
1201 fprintf(stderr
,"%s:%d: warning: $%d of '%s' has no declared type.\n",infile
,lineno
,n
,rule
->sym
->tag
);
1205 fatals("$%c is invalid",c
); /* JF changed format */
1211 if (isdigit(c
) || c
== '-')
1214 n
= read_signed_integer(finput
);
1218 fatal("invalid @-construct");
1220 fprintf(faction
, "yylsp[%d]", n
- stack_offset
);
1226 fatal("unmatched '{'");
1235 /* above loop exits when c is '}' */
1244 fprintf(faction
, ";\n break;}");
1249 /* generate a dummy symbol, a nonterminal,
1250 whose name cannot conflict with the user's names. */
1255 register bucket
*sym
;
1257 sprintf (token_buffer
, "@%d", ++gensym_count
);
1258 sym
= getsym(token_buffer
);
1259 sym
->class = SNTERM
;
1260 sym
->value
= nvars
++;
1264 /* Parse the input grammar into a one symbol_list structure.
1265 Each rule is represented by a sequence of symbols: the left hand side
1266 followed by the contents of the right hand side, followed by a null pointer
1267 instead of a symbol to terminate the rule.
1268 The next symbol is the lhs of the following rule.
1270 All guards and actions are copied out to the appropriate files,
1271 labelled by the rule number they apply to. */
1277 register bucket
*lhs
;
1278 register symbol_list
*p
;
1279 register symbol_list
*p1
;
1280 register bucket
*bp
;
1282 symbol_list
*crule
; /* points to first symbol_list of current rule. */
1283 /* its symbol is the lhs of the rule. */
1284 symbol_list
*crule1
; /* points to the symbol_list preceding crule. */
1290 while (t
!= TWO_PERCENTS
&& t
!= ENDFILE
)
1292 if (t
== IDENTIFIER
|| t
== BAR
)
1294 register int actionflag
= 0;
1295 int rulelength
= 0; /* number of symbols in rhs of this rule so far */
1296 int xactions
= 0; /* JF for error checking */
1297 bucket
*first_rhs
= 0;
1299 if (t
== IDENTIFIER
)
1305 fatal("ill-formed rule");
1311 fatal("grammar starts with vertical bar");
1317 /* start a new rule and record its lhs. */
1322 record_rule_line ();
1324 p
= NEW(symbol_list
);
1336 /* mark the rule's lhs as a nonterminal if not already so. */
1338 if (lhs
->class == SUNKNOWN
)
1340 lhs
->class = SNTERM
;
1344 else if (lhs
->class == STOKEN
)
1345 fatals("rule given for %s, which is a token", lhs
->tag
);
1347 /* read the rhs of the rule. */
1353 if (! (t
== IDENTIFIER
|| t
== LEFT_CURLY
)) break;
1355 /* If next token is an identifier, see if a colon follows it.
1356 If one does, exit this rule now. */
1357 if (t
== IDENTIFIER
)
1359 register bucket
*ssave
;
1366 if (t1
== COLON
) break;
1368 if(!first_rhs
) /* JF */
1370 /* Not followed by colon =>
1371 process as part of this rule's rhs. */
1374 /* If we just passed an action, that action was in the middle
1375 of a rule, so make a dummy rule to reduce it to a
1379 register bucket
*sdummy
;
1381 /* Since the action was written out with this rule's */
1382 /* number, we must write give the new rule this number */
1383 /* by inserting the new rule before it. */
1385 /* Make a dummy nonterminal, a gensym. */
1388 /* Make a new rule, whose body is empty,
1389 before the current one, so that the action
1390 just read can belong to it. */
1393 record_rule_line ();
1394 p
= NEW(symbol_list
);
1399 crule1
= NEW(symbol_list
);
1401 crule1
->next
= crule
;
1403 /* insert the dummy generated by that rule into this rule. */
1405 p
= NEW(symbol_list
);
1413 if (t
== IDENTIFIER
)
1416 p
= NEW(symbol_list
);
1421 else /* handle an action. */
1423 copy_action(crule
, rulelength
);
1425 xactions
++; /* JF */
1430 /* Put an empty link in the list to mark the end of this rule */
1431 p
= NEW(symbol_list
);
1438 crule
->ruleprec
= symval
;
1443 if (! semantic_parser
)
1444 fatal("%guard present but %semantic_parser not specified");
1446 copy_guard(crule
, rulelength
);
1449 else if (t
== LEFT_CURLY
)
1451 if (actionflag
) fatal("two actions at end of one rule");
1452 copy_action(crule
, rulelength
);
1455 /* If $$ is being set in default way,
1456 warn if any type mismatch. */
1457 else if (!xactions
&& first_rhs
&& lhs
->type_name
!= first_rhs
->type_name
)
1459 if (lhs
->type_name
== 0 || first_rhs
->type_name
== 0
1460 || strcmp(lhs
->type_name
,first_rhs
->type_name
))
1461 fprintf(stderr
, "%s:%d: warning: type clash ('%s' '%s') on default action\n",
1464 lhs
->type_name
? lhs
->type_name
: "",
1465 first_rhs
->type_name
? first_rhs
->type_name
: "");
1467 /* Warn if there is no default for $$ but we need one. */
1468 else if (!xactions
&& !first_rhs
&& lhs
->type_name
!= 0)
1470 "%s:%d: warning: empty rule for typed nonterminal, and no action\n",
1476 /* these things can appear as alternatives to rules. */
1477 else if (t
== TOKEN
)
1479 parse_token_decl(STOKEN
, SNTERM
);
1482 else if (t
== NTERM
)
1484 parse_token_decl(SNTERM
, STOKEN
);
1491 else if (t
== UNION
)
1496 else if (t
== EXPECT
)
1498 parse_expect_decl();
1501 else if (t
== START
)
1507 fatal("invalid input");
1510 if (nsyms
> MAXSHORT
)
1511 fatals("too many symbols (tokens plus nonterminals); maximum %d",
1514 fatal("no input grammar");
1516 if (typed
== 0 /* JF put out same default YYSTYPE as YACC does */
1517 && !value_components_used
)
1519 /* We used to use `unsigned long' as YYSTYPE on MSDOS,
1520 but it seems better to be consistent.
1521 Most programs should declare their own type anyway. */
1522 fprintf(fattrs
, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
1524 fprintf(fdefines
, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
1527 /* Report any undefined symbols and consider them nonterminals. */
1529 for (bp
= firstsymbol
; bp
; bp
= bp
->next
)
1530 if (bp
->class == SUNKNOWN
)
1532 fprintf(stderr
, "symbol %s used, not defined as token, and no rules for it\n",
1536 bp
->value
= nvars
++;
1539 ntokens
= nsyms
- nvars
;
1546 /* Record each rule's source line number in rline table. */
1548 if (nrules
>= rline_allocated
)
1550 rline_allocated
= nrules
* 2;
1551 rline
= (short *) xrealloc (rline
,
1552 rline_allocated
* sizeof (short));
1554 rline
[nrules
] = lineno
;
1558 /* read in a %type declaration and record its information for get_type_name to access */
1565 register char *name
;
1570 fatal("ill-formed %type declaration");
1572 k
= strlen(token_buffer
);
1573 name
= NEW2(k
+ 1, char);
1574 strcpy(name
, token_buffer
);
1589 if (symval
->type_name
== NULL
)
1590 symval
->type_name
= name
;
1592 fatals("type redeclaration for %s", symval
->tag
);
1604 /* assign symbol numbers, and write definition of token names into fdefines.
1605 Set up vectors tags and sprec of names and precedences of symbols. */
1610 register bucket
*bp
;
1611 register int tokno
= 1;
1613 register int last_user_token_number
;
1615 /* int lossage = 0; JF set but not used */
1617 tags
= NEW2(nsyms
+ 1, char *);
1620 sprec
= NEW2(nsyms
, short);
1621 sassoc
= NEW2(nsyms
, short);
1623 max_user_token_number
= 256;
1624 last_user_token_number
= 256;
1626 for (bp
= firstsymbol
; bp
; bp
= bp
->next
)
1628 if (bp
->class == SNTERM
)
1630 bp
->value
+= ntokens
;
1634 if (translations
&& !(bp
->user_token_number
))
1635 bp
->user_token_number
= ++last_user_token_number
;
1636 if (bp
->user_token_number
> max_user_token_number
)
1637 max_user_token_number
= bp
->user_token_number
;
1638 bp
->value
= tokno
++;
1641 tags
[bp
->value
] = bp
->tag
;
1642 sprec
[bp
->value
] = bp
->prec
;
1643 sassoc
[bp
->value
] = bp
->assoc
;
1651 token_translations
= NEW2(max_user_token_number
+1, short);
1653 /* initialize all entries for literal tokens to 2,
1654 the internal token number for $illegal., which represents all invalid inputs. */
1655 for (i
= 0; i
<= max_user_token_number
; i
++)
1656 token_translations
[i
] = 2;
1659 for (bp
= firstsymbol
; bp
; bp
= bp
->next
)
1661 if (bp
->value
>= ntokens
) continue;
1664 if (token_translations
[bp
->user_token_number
] != 2)
1666 /* JF made this a call to fatals() */
1667 fatals( "tokens %s and %s both assigned number %d",
1668 tags
[token_translations
[bp
->user_token_number
]],
1670 bp
->user_token_number
);
1672 token_translations
[bp
->user_token_number
] = bp
->value
;
1676 error_token_number
= errtoken
->value
;
1678 output_token_defines(ftable
);
1680 if (startval
->class == SUNKNOWN
)
1681 fatals("the start symbol %s is undefined", startval
->tag
);
1682 else if (startval
->class == STOKEN
)
1683 fatals("the start symbol %s is a token", startval
->tag
);
1685 start_symbol
= startval
->value
;
1689 output_token_defines(fdefines
);
1693 if (spec_name_prefix
)
1694 fprintf(fdefines
, "\nextern YYSTYPE %slval;\n", spec_name_prefix
);
1696 fprintf(fdefines
, "\nextern YYSTYPE yylval;\n");
1699 if (semantic_parser
)
1700 for (i
= ntokens
; i
< nsyms
; i
++)
1702 /* don't make these for dummy nonterminals made by gensym. */
1703 if (*tags
[i
] != '@')
1704 fprintf(fdefines
, "#define\tNT%s\t%d\n", tags
[i
], i
);
1707 /* `fdefines' is now a temporary file, so we need to copy its
1708 contents in `done', so we can't close it here. */
1717 output_token_defines(file
)
1722 for (bp
= firstsymbol
; bp
; bp
= bp
->next
)
1724 if (bp
->value
>= ntokens
) continue;
1726 /* For named tokens, but not literal ones, define the name. */
1727 /* The value is the user token number. */
1729 if ('\'' != *tags
[bp
->value
] && bp
!= errtoken
)
1731 register char *cp
= tags
[bp
->value
];
1734 /* Don't #define nonliteral tokens whose names contain periods. */
1736 while ((c
= *cp
++) && c
!= '.');
1739 fprintf(file
, "#define\t%s\t%d\n", tags
[bp
->value
],
1740 (translations
? bp
->user_token_number
: bp
->value
));
1741 if (semantic_parser
)
1742 fprintf(file
, "#define\tT%s\t%d\n", tags
[bp
->value
],
1753 /* convert the rules into the representation using rrhs, rlhs and ritems. */
1758 register int itemno
;
1759 register int ruleno
;
1760 register symbol_list
*p
;
1761 /* register bucket *bp; JF unused */
1765 ritem
= NEW2(nitems
+ 1, short);
1766 rlhs
= NEW2(nrules
, short) - 1;
1767 rrhs
= NEW2(nrules
, short) - 1;
1768 rprec
= NEW2(nrules
, short) - 1;
1769 rprecsym
= NEW2(nrules
, short) - 1;
1770 rassoc
= NEW2(nrules
, short) - 1;
1778 rlhs
[ruleno
] = p
->sym
->value
;
1779 rrhs
[ruleno
] = itemno
;
1780 ruleprec
= p
->ruleprec
;
1785 ritem
[itemno
++] = p
->sym
->value
;
1786 /* A rule gets by default the precedence and associativity
1787 of the last token in it. */
1788 if (p
->sym
->class == STOKEN
)
1790 rprec
[ruleno
] = p
->sym
->prec
;
1791 rassoc
[ruleno
] = p
->sym
->assoc
;
1796 /* If this rule has a %prec,
1797 the specified symbol's precedence replaces the default. */
1800 rprec
[ruleno
] = ruleprec
->prec
;
1801 rassoc
[ruleno
] = ruleprec
->assoc
;
1802 rprecsym
[ruleno
] = ruleprec
->value
;
1805 ritem
[itemno
++] = -ruleno
;
1814 /* Read a signed integer from STREAM and return its value. */
1817 read_signed_integer (stream
)
1820 register int c
= getc(stream
);
1821 register int sign
= 1;
1832 n
= 10*n
+ (c
- '0');