]> git.saurik.com Git - bison.git/blame - src/output.c
Typos and Copyright.
[bison.git] / src / output.c
CommitLineData
c3e23647 1/* Output the generated parsing program for bison,
fabd3b43 2 Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
c3e23647 3
9ee3c97b 4 This file is part of Bison, the GNU Compiler Compiler.
c3e23647 5
9ee3c97b
AD
6 Bison is free software; you can redistribute it and/or modify it
7 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.
c3e23647 10
9ee3c97b
AD
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
c3e23647 15
9ee3c97b
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 the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
c3e23647
RS
20
21
6c89f1c1
AD
22/* The parser tables consist of these tables.
23 Starred ones needed only for the semantic parser.
24 Double starred are output only if switches are set.
c3e23647 25
6c89f1c1
AD
26 yytranslate = vector mapping yylex's token numbers into bison's token
27 numbers.
c3e23647 28
6c89f1c1 29 ** yytname = vector of string-names indexed by bison token number
c3e23647 30
6c89f1c1
AD
31 ** yytoknum = vector of yylex token numbers corresponding to entries
32 in yytname
c3e23647 33
6c89f1c1 34 yyrline = vector of line-numbers of all rules. For yydebug printouts.
c3e23647 35
6c89f1c1
AD
36 yyrhs = vector of items of all rules.
37 This is exactly what ritems contains. For yydebug and for semantic
38 parser.
c3e23647 39
6c89f1c1 40 yyprhs[r] = index in yyrhs of first item for rule r.
c3e23647 41
6c89f1c1 42 yyr1[r] = symbol number of symbol that rule r derives.
c3e23647 43
6c89f1c1 44 yyr2[r] = number of symbols composing right hand side of rule r.
c3e23647 45
6c89f1c1 46 * yystos[s] = the symbol number of the symbol that leads to state s.
e372befa 47
6c89f1c1
AD
48 yydefact[s] = default rule to reduce with in state s,
49 when yytable doesn't specify something else to do.
50 Zero means the default is an error.
c3e23647 51
6c89f1c1
AD
52 yydefgoto[i] = default state to go to after a reduction of a rule that
53 generates variable ntokens + i, except when yytable
54 specifies something else to do.
c3e23647 55
6c89f1c1
AD
56 yypact[s] = index in yytable of the portion describing state s.
57 The lookahead token's type is used to index that portion
58 to find out what to do.
c3e23647 59
6c89f1c1
AD
60 If the value in yytable is positive,
61 we shift the token and go to that state.
c3e23647 62
6c89f1c1 63 If the value is negative, it is minus a rule number to reduce by.
c3e23647 64
6c89f1c1 65 If the value is zero, the default action from yydefact[s] is used.
c3e23647 66
6c89f1c1
AD
67 yypgoto[i] = the index in yytable of the portion describing
68 what to do after reducing a rule that derives variable i + ntokens.
69 This portion is indexed by the parser state number, s,
70 as of before the text for this nonterminal was read.
71 The value from yytable is the state to go to if
72 the corresponding value in yycheck is s.
c3e23647 73
6c89f1c1
AD
74 yytable = a vector filled with portions for different uses,
75 found via yypact and yypgoto.
c3e23647 76
6c89f1c1
AD
77 yycheck = a vector indexed in parallel with yytable.
78 It indicates, in a roundabout way, the bounds of the
79 portion you are trying to examine.
c3e23647 80
6c89f1c1
AD
81 Suppose that the portion of yytable starts at index p
82 and the index to be examined within the portion is i.
83 Then if yycheck[p+i] != i, i is outside the bounds
84 of what is actually allocated, and the default
85 (from yydefact or yydefgoto) should be used.
86 Otherwise, yytable[p+i] should be used.
c3e23647 87
6c89f1c1
AD
88 YYFINAL = the state number of the termination state.
89 YYFLAG = most negative short int. Used to flag ??
90 YYNTBASE = ntokens.
c3e23647
RS
91*/
92
c3e23647 93#include "system.h"
8c7ebe49 94#include "obstack.h"
14d3eb9b 95#include "quotearg.h"
ceed8467 96#include "getargs.h"
d7913476 97#include "xalloc.h"
c3e23647
RS
98#include "files.h"
99#include "gram.h"
b2ca4022 100#include "LR0.h"
a0f6b076 101#include "complain.h"
6c89f1c1 102#include "output.h"
720d742f 103#include "lalr.h"
a70083a3 104#include "reader.h"
0619caf0 105#include "conflicts.h"
c3e23647 106
d019d655
AD
107extern void berror PARAMS((const char *));
108
d2729d44 109
c3e23647
RS
110
111static int nvectors;
112static int nentries;
113static short **froms;
114static short **tos;
115static short *tally;
116static short *width;
117static short *actrow;
118static short *state_count;
119static short *order;
120static short *base;
121static short *pos;
122static short *table;
123static short *check;
124static int lowzero;
125static int high;
126
127
128
d019d655 129static inline void
896fe5c1 130output_short_or_char_table (struct obstack *oout,
43591cec
AD
131 const char *comment,
132 const char *type,
133 const char *table_name,
134 short *short_table,
135 short first_value,
136 short begin, short end)
d019d655
AD
137{
138 int i, j;
139
1e9798d5 140 if (comment)
896fe5c1 141 obstack_fgrow1 (oout, "/* %s. */\n", comment);
d019d655 142
896fe5c1
AD
143 obstack_fgrow3 (oout, "static const %s %s[] =\n{\n %6d",
144 type, table_name, first_value);
1e9798d5
AD
145
146 j = 1;
d019d655
AD
147 for (i = begin; i < end; i++)
148 {
896fe5c1 149 obstack_1grow (oout, ',');
d019d655
AD
150
151 if (j >= 10)
152 {
ff4423cc 153 obstack_sgrow (oout, "\n ");
d019d655
AD
154 j = 1;
155 }
156 else
157 {
158 j++;
159 }
160
896fe5c1 161 obstack_fgrow1 (oout, "%6d", short_table[i]);
d019d655
AD
162 }
163
ff4423cc 164 obstack_sgrow (oout, "\n};\n");
d019d655
AD
165}
166
167
43591cec 168static inline void
896fe5c1 169output_short_table (struct obstack *oout,
43591cec
AD
170 const char *comment,
171 const char *table_name,
172 short *short_table,
173 short first_value,
174 short begin, short end)
175{
896fe5c1 176 output_short_or_char_table (oout, comment, "short", table_name, short_table,
43591cec
AD
177 first_value, begin, end);
178}
179
180
d019d655
AD
181/*--------------------------------------------------------------.
182| output_headers -- Output constant strings to the beginning of |
183| certain files. |
184`--------------------------------------------------------------*/
185
14d3eb9b
AD
186/* Don't put the `%s' insides quotes, since it quotearg puts them. */
187
ceed8467
AD
188#define GUARDSTR \
189"\n\
14d3eb9b 190#include %s\n\
ceed8467
AD
191extern int yyerror;\n\
192extern int yycost;\n\
193extern char * yymsg;\n\
194extern YYSTYPE yyval;\n\
195\n\
196yyguard(n, yyvsp, yylsp)\n\
197register int n;\n\
198register YYSTYPE *yyvsp;\n\
c3e23647 199register YYLTYPE *yylsp;\n\
ceed8467
AD
200{\n\
201 yyerror = 0;\n\
202 yycost = 0;\n\
203 yymsg = 0;\n\
204 switch (n)\n\
205 {"
206
207#define ACTSTR \
208"\n\
14d3eb9b 209#include %s\n\
8c7ebe49
AD
210extern YYSTYPE yyval;\n\
211extern int yychar;\n\
212\n\
213yyaction(n, yyvsp, yylsp)\n\
214register int n;\n\
215register YYSTYPE *yyvsp;\n\
216register YYLTYPE *yylsp;\n\
217{\n\
218 switch (n)\n\
219 {"
220
c3e23647
RS
221#define ACTSTR_SIMPLE "\n switch (yyn) {\n"
222
c3e23647 223void
d2729d44 224output_headers (void)
c3e23647 225{
6deb4447 226 char *attrsfile_quoted = 0;
14d3eb9b 227
c3e23647 228 if (semantic_parser)
6deb4447
AD
229 {
230 /* FIXME: This is *buggy*. ATTRSFILE is not computed yet, since
231 we are waiting for the full input file to have been read to
232 be sure of the output file name. So basically, here, a SEGV
233 is guaranteed. OTOH, currently semantic parsers are not
234 supported. */
235 attrsfile_quoted = quotearg_style (c_quoting_style, attrsfile);
236 obstack_fgrow1 (&guard_obstack, GUARDSTR, attrsfile_quoted);
237 }
e372befa 238
89cab50d 239 if (no_parser_flag)
ceed8467 240 return;
e372befa 241
8c7ebe49 242 if (semantic_parser)
14d3eb9b 243 obstack_fgrow1 (&action_obstack, ACTSTR, attrsfile_quoted);
8c7ebe49 244 else
ff4423cc 245 obstack_sgrow (&action_obstack, ACTSTR_SIMPLE);
8c7ebe49 246
c3e23647
RS
247 /* Rename certain symbols if -p was specified. */
248 if (spec_name_prefix)
249 {
896fe5c1 250 obstack_fgrow1 (&table_obstack,
14d3eb9b 251 "#define yyparse %sparse\n", spec_name_prefix);
896fe5c1 252 obstack_fgrow1 (&table_obstack,
14d3eb9b 253 "#define yylex %slex\n", spec_name_prefix);
896fe5c1 254 obstack_fgrow1 (&table_obstack,
14d3eb9b 255 "#define yyerror %serror\n", spec_name_prefix);
896fe5c1 256 obstack_fgrow1 (&table_obstack,
14d3eb9b 257 "#define yylval %slval\n", spec_name_prefix);
896fe5c1 258 obstack_fgrow1 (&table_obstack,
14d3eb9b 259 "#define yychar %schar\n", spec_name_prefix);
896fe5c1 260 obstack_fgrow1 (&table_obstack,
14d3eb9b 261 "#define yydebug %sdebug\n", spec_name_prefix);
896fe5c1 262 obstack_fgrow1 (&table_obstack,
14d3eb9b 263 "#define yynerrs %snerrs\n", spec_name_prefix);
c3e23647
RS
264 }
265}
266
267
6c89f1c1
AD
268/*-------------------------------------------------------.
269| Output constant strings to the ends of certain files. |
270`-------------------------------------------------------*/
271
c3e23647 272void
d2729d44 273output_trailers (void)
c3e23647
RS
274{
275 if (semantic_parser)
ff4423cc 276 obstack_sgrow (&guard_obstack, "\n }\n}\n");
e372befa 277
8c7ebe49 278 obstack_1grow (&action_obstack, '\n');
9ee3c97b 279
89cab50d 280 if (no_parser_flag)
ceed8467 281 return;
e372befa
RS
282
283 if (semantic_parser)
ff4423cc 284 obstack_sgrow (&action_obstack, " }\n");
14d3eb9b 285
ff4423cc 286 obstack_sgrow (&action_obstack, "}\n");
c3e23647
RS
287}
288
289
c3e23647 290
4a120d45 291static void
d2729d44 292output_token_translations (void)
c3e23647 293{
ff4423cc 294 obstack_sgrow (&table_obstack, "\
43591cec 295\n\
fabd3b43 296/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */\n");
896fe5c1 297
c3e23647
RS
298 if (translations)
299 {
896fe5c1 300 obstack_fgrow2 (&table_obstack,
43591cec
AD
301 "#define YYTRANSLATE(x) ((unsigned)(x) <= %d ? yytranslate[x] : %d)\
302\n\
303\n",
ceed8467 304 max_user_token_number, nsyms);
9ee3c97b 305
896fe5c1 306 output_short_or_char_table (&table_obstack,
fabd3b43 307 "YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX",
43591cec
AD
308 ntokens < 127 ? "char" : "short",
309 "yytranslate", token_translations,
310 0, 1, max_user_token_number + 1);
c3e23647
RS
311 }
312 else
313 {
ff4423cc 314 obstack_sgrow (&table_obstack,
573c1d9f 315 "\n#define YYTRANSLATE(x) (x)\n");
9ee3c97b 316 }
c3e23647
RS
317}
318
319
4a120d45 320static void
d2729d44 321output_gram (void)
c3e23647 322{
9ee3c97b 323 /* With the ordinary parser,
e372befa 324 yyprhs and yyrhs are needed only for yydebug. */
89cab50d
AD
325 /* With the no_parser option, all tables are generated */
326 if (!semantic_parser && !no_parser_flag)
ff4423cc 327 obstack_sgrow (&table_obstack, "\n#if YYDEBUG != 0\n");
c3e23647 328
896fe5c1 329 output_short_table (&table_obstack, NULL, "yyprhs", rrhs,
d019d655 330 0, 1, nrules + 1);
c3e23647 331
1e9798d5
AD
332 {
333 size_t yyrhs_size = 1;
334 short *yyrhs, *sp;
335 int i;
c3e23647 336
1e9798d5
AD
337 for (sp = ritem + 1; *sp; sp++)
338 ++yyrhs_size;
339 yyrhs = XMALLOC (short, yyrhs_size);
c3e23647 340
1e9798d5
AD
341 for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
342 yyrhs[i] = *sp > 0 ? *sp : 0;
c3e23647 343
896fe5c1 344 output_short_table (&table_obstack, NULL, "yyrhs", yyrhs,
1e9798d5
AD
345 ritem[0], 1, yyrhs_size);
346 XFREE (yyrhs);
347 }
c3e23647 348
89cab50d 349 if (!semantic_parser && !no_parser_flag)
ff4423cc 350 obstack_sgrow (&table_obstack, "\n#endif\n");
c3e23647
RS
351}
352
353
4a120d45 354static void
d2729d44 355output_stos (void)
c3e23647 356{
896fe5c1 357 output_short_table (&table_obstack, NULL, "yystos", accessing_symbol,
d019d655 358 0, 1, nstates);
c3e23647
RS
359}
360
361
4a120d45 362static void
d2729d44 363output_rule_data (void)
c3e23647 364{
6c89f1c1
AD
365 int i;
366 int j;
1e9798d5 367 short *short_tab = NULL;
c3e23647 368
ff4423cc 369 obstack_sgrow (&table_obstack, "\n\
896fe5c1 370#if YYDEBUG != 0\n");
c3e23647 371
896fe5c1 372 output_short_table (&table_obstack,
1e9798d5
AD
373 "YYRLINE[YYN] -- source line where rule number YYN was defined",
374 "yyrline", rline,
d019d655 375 0, 1, nrules + 1);
c3e23647 376
ff4423cc 377 obstack_sgrow (&table_obstack, "#endif\n\n");
e372befa 378
89cab50d 379 if (token_table_flag || no_parser_flag)
e372befa 380 {
896fe5c1
AD
381 obstack_fgrow1 (&table_obstack, "#define YYNTOKENS %d\n", ntokens);
382 obstack_fgrow1 (&table_obstack, "#define YYNNTS %d\n", nvars);
383 obstack_fgrow1 (&table_obstack, "#define YYNRULES %d\n", nrules);
384 obstack_fgrow1 (&table_obstack, "#define YYNSTATES %d\n", nstates);
385 obstack_fgrow1 (&table_obstack, "#define YYMAXUTOK %d\n\n",
386 max_user_token_number);
e372befa
RS
387 }
388
c3e23647 389 /* Output the table of symbol names. */
1e9798d5 390 if (!token_table_flag && !no_parser_flag)
ff4423cc 391 obstack_sgrow (&table_obstack,
573c1d9f 392 "\n#if YYDEBUG != 0 || defined YYERROR_VERBOSE\n\n");
ff4423cc 393 obstack_sgrow (&table_obstack, "\
896fe5c1 394/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */\n");
ff4423cc 395 obstack_sgrow (&table_obstack,
1e9798d5 396 "static const char *const yytname[] =\n{\n ");
c3e23647 397
1e9798d5
AD
398 j = 0;
399 for (i = 0; i < nsyms; i++)
ceed8467
AD
400 /* this used to be i<=nsyms, but that output a final "" symbol
401 almost by accident */
c3e23647 402 {
1e9798d5
AD
403 /* Width of the next token, including the two quotes, the coma
404 and the space. */
405 int strsize = 4;
6c89f1c1 406 char *p;
c3e23647 407
1e9798d5
AD
408 for (p = tags[i]; p && *p; p++)
409 if (*p == '"' || *p == '\\' || *p == '\n' || *p == '\t'
410 || *p == '\b')
411 strsize += 2;
412 else if (*p < 040 || *p >= 0177)
413 strsize += 4;
414 else
415 strsize++;
416
417 if (j + strsize > 75)
c3e23647 418 {
ff4423cc 419 obstack_sgrow (&table_obstack, "\n ");
1e9798d5 420 j = 2;
c3e23647
RS
421 }
422
896fe5c1 423 obstack_1grow (&table_obstack, '\"');
c3e23647
RS
424 for (p = tags[i]; p && *p; p++)
425 {
426 if (*p == '"' || *p == '\\')
573c1d9f 427 obstack_fgrow1 (&table_obstack, "\\%c", *p);
c3e23647 428 else if (*p == '\n')
ff4423cc 429 obstack_sgrow (&table_obstack, "\\n");
c3e23647 430 else if (*p == '\t')
ff4423cc 431 obstack_sgrow (&table_obstack, "\\t");
c3e23647 432 else if (*p == '\b')
ff4423cc 433 obstack_sgrow (&table_obstack, "\\b");
c3e23647 434 else if (*p < 040 || *p >= 0177)
573c1d9f 435 obstack_fgrow1 (&table_obstack, "\\%03o", *p);
c3e23647 436 else
573c1d9f 437 obstack_1grow (&table_obstack, *p);
c3e23647
RS
438 }
439
ff4423cc 440 obstack_sgrow (&table_obstack, "\", ");
1e9798d5 441 j += strsize;
c3e23647 442 }
9ee3c97b 443 /* add a NULL entry to list of tokens */
ff4423cc 444 obstack_sgrow (&table_obstack, "NULL\n};\n");
c3e23647 445
89cab50d 446 if (!token_table_flag && !no_parser_flag)
ff4423cc 447 obstack_sgrow (&table_obstack, "#endif\n\n");
e372befa 448
9ee3c97b 449 /* Output YYTOKNUM. */
89cab50d 450 if (token_table_flag)
e372befa 451 {
896fe5c1 452 output_short_table (&table_obstack,
1e9798d5
AD
453 "YYTOKNUM[YYLEX] -- Index in YYTNAME corresponding to YYLEX",
454 "yytoknum", user_toknums,
d019d655 455 0, 1, ntokens + 1);
e372befa
RS
456 }
457
9ee3c97b 458 /* Output YYR1. */
896fe5c1 459 output_short_table (&table_obstack,
1e9798d5
AD
460 "YYR1[YYN] -- Symbol number of symbol that rule YYN derives",
461 "yyr1", rlhs,
d019d655 462 0, 1, nrules + 1);
d7913476 463 XFREE (rlhs + 1);
d019d655 464
896fe5c1 465 obstack_1grow (&table_obstack, '\n');
9ee3c97b
AD
466
467 /* Output YYR2. */
1e9798d5 468 short_tab = XMALLOC (short, nrules + 1);
c3e23647 469 for (i = 1; i < nrules; i++)
1e9798d5
AD
470 short_tab[i] = rrhs[i + 1] - rrhs[i] - 1;
471 short_tab[nrules] = nitems - rrhs[nrules] - 1;
896fe5c1 472 output_short_table (&table_obstack,
1e9798d5
AD
473 "YYR2[YYN] -- Number of symbols composing right hand side of rule YYN",
474 "yyr2", short_tab,
475 0, 1, nrules + 1);
896fe5c1 476 obstack_1grow (&table_obstack, '\n');
c3e23647 477
1e9798d5 478 XFREE (short_tab);
c3e23647 479
d7913476 480 XFREE (rrhs + 1);
c3e23647
RS
481}
482
483
4a120d45 484static void
d2729d44 485output_defines (void)
c3e23647 486{
896fe5c1
AD
487 obstack_fgrow1 (&table_obstack, "\n\n#define\tYYFINAL\t\t%d\n", final_state);
488 obstack_fgrow1 (&table_obstack, "#define\tYYFLAG\t\t%d\n", MINSHORT);
489 obstack_fgrow1 (&table_obstack, "#define\tYYNTBASE\t%d\n", ntokens);
c3e23647
RS
490}
491
492
6c89f1c1
AD
493/*------------------------------------------------------------------.
494| Decide what to do for each type of token if seen as the lookahead |
495| token in specified state. The value returned is used as the |
496| default action (yydefact) for the state. In addition, actrow is |
497| filled with what to do for each kind of token, index by symbol |
498| number, with zero meaning do the default action. The value |
499| MINSHORT, a very negative number, means this situation is an |
500| error. The parser recognizes this value specially. |
501| |
502| This is where conflicts are resolved. The loop over lookahead |
503| rules considered lower-numbered rules last, and the last rule |
504| considered that likes a token gets to handle it. |
505`------------------------------------------------------------------*/
c3e23647 506
4a120d45 507static int
d2729d44 508action_row (int state)
c3e23647 509{
6c89f1c1
AD
510 int i;
511 int j;
512 int k;
513 int m = 0;
514 int n = 0;
515 int count;
516 int default_rule;
517 int nreds;
518 int max;
519 int rule;
520 int shift_state;
521 int symbol;
522 unsigned mask;
523 unsigned *wordp;
524 reductions *redp;
525 shifts *shiftp;
526 errs *errp;
ceed8467 527 int nodefault = 0; /* set nonzero to inhibit having any default reduction */
c3e23647
RS
528
529 for (i = 0; i < ntokens; i++)
530 actrow[i] = 0;
531
532 default_rule = 0;
533 nreds = 0;
534 redp = reduction_table[state];
535
536 if (redp)
537 {
538 nreds = redp->nreds;
539
540 if (nreds >= 1)
541 {
36281465
AD
542 /* loop over all the rules available here which require
543 lookahead */
c3e23647
RS
544 m = lookaheads[state];
545 n = lookaheads[state + 1];
546
547 for (i = n - 1; i >= m; i--)
548 {
ceed8467 549 rule = -LAruleno[i];
c3e23647
RS
550 wordp = LA + i * tokensetsize;
551 mask = 1;
552
36281465 553 /* and find each token which the rule finds acceptable
ceed8467 554 to come next */
c3e23647
RS
555 for (j = 0; j < ntokens; j++)
556 {
36281465
AD
557 /* and record this rule as the rule to use if that
558 token follows. */
c3e23647
RS
559 if (mask & *wordp)
560 actrow[j] = rule;
561
562 mask <<= 1;
563 if (mask == 0)
564 {
565 mask = 1;
566 wordp++;
567 }
568 }
569 }
570 }
571 }
572
573 shiftp = shift_table[state];
574
36281465
AD
575 /* Now see which tokens are allowed for shifts in this state. For
576 them, record the shift as the thing to do. So shift is preferred
577 to reduce. */
c3e23647
RS
578
579 if (shiftp)
580 {
581 k = shiftp->nshifts;
582
583 for (i = 0; i < k; i++)
584 {
585 shift_state = shiftp->shifts[i];
ceed8467
AD
586 if (!shift_state)
587 continue;
c3e23647
RS
588
589 symbol = accessing_symbol[shift_state];
590
ceed8467 591 if (ISVAR (symbol))
c3e23647
RS
592 break;
593
594 actrow[symbol] = shift_state;
595
36281465
AD
596 /* Do not use any default reduction if there is a shift for
597 error */
598 if (symbol == error_token_number)
599 nodefault = 1;
c3e23647
RS
600 }
601 }
602
603 errp = err_table[state];
604
36281465
AD
605 /* See which tokens are an explicit error in this state (due to
606 %nonassoc). For them, record MINSHORT as the action. */
c3e23647
RS
607
608 if (errp)
609 {
610 k = errp->nerrs;
611
612 for (i = 0; i < k; i++)
613 {
614 symbol = errp->errs[i];
615 actrow[symbol] = MINSHORT;
616 }
617 }
618
36281465
AD
619 /* Now find the most common reduction and make it the default action
620 for this state. */
c3e23647 621
ceed8467 622 if (nreds >= 1 && !nodefault)
c3e23647
RS
623 {
624 if (consistent[state])
625 default_rule = redp->rules[0];
626 else
627 {
628 max = 0;
629 for (i = m; i < n; i++)
630 {
631 count = 0;
ceed8467 632 rule = -LAruleno[i];
9ee3c97b 633
c3e23647
RS
634 for (j = 0; j < ntokens; j++)
635 {
636 if (actrow[j] == rule)
637 count++;
638 }
9ee3c97b 639
c3e23647
RS
640 if (count > max)
641 {
642 max = count;
643 default_rule = rule;
644 }
645 }
9ee3c97b 646
c3e23647
RS
647 /* actions which match the default are replaced with zero,
648 which means "use the default" */
9ee3c97b 649
c3e23647
RS
650 if (max > 0)
651 {
652 for (j = 0; j < ntokens; j++)
653 {
654 if (actrow[j] == default_rule)
655 actrow[j] = 0;
656 }
9ee3c97b 657
ceed8467 658 default_rule = -default_rule;
c3e23647
RS
659 }
660 }
661 }
662
663 /* If have no default rule, the default is an error.
664 So replace any action which says "error" with "use default". */
665
666 if (default_rule == 0)
667 for (j = 0; j < ntokens; j++)
668 {
669 if (actrow[j] == MINSHORT)
670 actrow[j] = 0;
671 }
672
36281465 673 return default_rule;
c3e23647
RS
674}
675
676
4a120d45 677static void
d2729d44 678save_row (int state)
c3e23647 679{
6c89f1c1
AD
680 int i;
681 int count;
682 short *sp;
683 short *sp1;
684 short *sp2;
c3e23647
RS
685
686 count = 0;
687 for (i = 0; i < ntokens; i++)
688 {
689 if (actrow[i] != 0)
690 count++;
691 }
692
693 if (count == 0)
694 return;
695
d7913476
AD
696 froms[state] = sp1 = sp = XCALLOC (short, count);
697 tos[state] = sp2 = XCALLOC (short, count);
c3e23647
RS
698
699 for (i = 0; i < ntokens; i++)
700 {
701 if (actrow[i] != 0)
702 {
703 *sp1++ = i;
704 *sp2++ = actrow[i];
705 }
706 }
707
708 tally[state] = count;
709 width[state] = sp1[-1] - sp[0] + 1;
710}
711
712
6c89f1c1
AD
713/*------------------------------------------------------------------.
714| Figure out the actions for the specified state, indexed by |
715| lookahead token type. |
716| |
f2acea59
AD
717| The YYDEFACT table is output now. The detailed info is saved for |
718| putting into YYTABLE later. |
6c89f1c1 719`------------------------------------------------------------------*/
c3e23647 720
4a120d45 721static void
6c89f1c1 722token_actions (void)
c3e23647 723{
6c89f1c1 724 int i;
d7913476 725 short *yydefact = XCALLOC (short, nstates);
c3e23647 726
d7913476 727 actrow = XCALLOC (short, ntokens);
f2acea59 728 for (i = 0; i < nstates; ++i)
c3e23647 729 {
f2acea59 730 yydefact[i] = action_row (i);
6c89f1c1 731 save_row (i);
c3e23647 732 }
d7913476 733 XFREE (actrow);
f2acea59 734
896fe5c1 735 output_short_table (&table_obstack,
43591cec
AD
736 "YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE\n\
737 doesn't specify something else to do. Zero means the default is an\n\
738 error",
739 "yydefact", yydefact,
f2acea59 740 yydefact[0], 1, nstates);
896fe5c1 741 obstack_1grow (&table_obstack, '\n');
d7913476 742 XFREE (yydefact);
c3e23647
RS
743}
744
745
6c89f1c1
AD
746static void
747free_shifts (void)
c3e23647 748{
6c89f1c1 749 shifts *sp, *sptmp; /* JF derefrenced freed ptr */
c3e23647 750
d7913476 751 XFREE (shift_table);
c3e23647 752
6c89f1c1
AD
753 for (sp = first_shift; sp; sp = sptmp)
754 {
755 sptmp = sp->next;
d7913476 756 XFREE (sp);
6c89f1c1
AD
757 }
758}
c3e23647 759
c3e23647 760
6c89f1c1
AD
761static void
762free_reductions (void)
763{
764 reductions *rp, *rptmp; /* JF fixed freed ptr */
c3e23647 765
d7913476 766 XFREE (reduction_table);
c3e23647 767
6c89f1c1 768 for (rp = first_reduction; rp; rp = rptmp)
c3e23647 769 {
6c89f1c1 770 rptmp = rp->next;
d7913476 771 XFREE (rp);
c3e23647 772 }
c3e23647
RS
773}
774
775
6c89f1c1 776
4a120d45 777static void
d2729d44 778save_column (int symbol, int default_state)
c3e23647 779{
6c89f1c1 780 int i;
6c89f1c1
AD
781 short *sp;
782 short *sp1;
783 short *sp2;
784 int count;
785 int symno;
c3e23647 786
43591cec
AD
787 short begin = goto_map[symbol];
788 short end = goto_map[symbol + 1];
c3e23647
RS
789
790 count = 0;
43591cec 791 for (i = begin; i < end; i++)
c3e23647
RS
792 {
793 if (to_state[i] != default_state)
794 count++;
795 }
796
797 if (count == 0)
798 return;
799
800 symno = symbol - ntokens + nstates;
801
d7913476
AD
802 froms[symno] = sp1 = sp = XCALLOC (short, count);
803 tos[symno] = sp2 = XCALLOC (short, count);
c3e23647 804
43591cec 805 for (i = begin; i < end; i++)
c3e23647
RS
806 {
807 if (to_state[i] != default_state)
808 {
809 *sp1++ = from_state[i];
810 *sp2++ = to_state[i];
811 }
812 }
813
814 tally[symno] = count;
815 width[symno] = sp1[-1] - sp[0] + 1;
816}
817
6c89f1c1
AD
818static int
819default_goto (int symbol)
820{
821 int i;
822 int m;
823 int n;
824 int default_state;
825 int max;
826
827 m = goto_map[symbol];
828 n = goto_map[symbol + 1];
829
830 if (m == n)
831 return -1;
832
833 for (i = 0; i < nstates; i++)
834 state_count[i] = 0;
835
836 for (i = m; i < n; i++)
837 state_count[to_state[i]]++;
838
839 max = 0;
840 default_state = -1;
841
842 for (i = 0; i < nstates; i++)
843 {
844 if (state_count[i] > max)
845 {
846 max = state_count[i];
847 default_state = i;
848 }
849 }
850
851 return default_state;
852}
853
854
855/*-------------------------------------------------------------------.
856| Figure out what to do after reducing with each rule, depending on |
857| the saved state from before the beginning of parsing the data that |
858| matched this rule. |
859| |
860| The YYDEFGOTO table is output now. The detailed info is saved for |
861| putting into YYTABLE later. |
862`-------------------------------------------------------------------*/
863
864static void
865goto_actions (void)
866{
43591cec 867 int i;
6c89f1c1 868
43591cec 869 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
d7913476 870 state_count = XCALLOC (short, nstates);
6c89f1c1 871
43591cec 872 for (i = ntokens; i < nsyms; ++i)
6c89f1c1 873 {
43591cec
AD
874 int default_state = default_goto (i);
875 save_column (i, default_state);
876 yydefgoto[i - ntokens] = default_state;
6c89f1c1
AD
877 }
878
896fe5c1 879 output_short_table (&table_obstack, NULL, "yydefgoto", yydefgoto,
43591cec
AD
880 yydefgoto[0], 1, nsyms - ntokens);
881
d7913476 882 XFREE (state_count);
43591cec 883 XFREE (yydefgoto);
6c89f1c1 884}
c3e23647
RS
885
886
9ee3c97b
AD
887/* The next few functions decide how to pack the actions and gotos
888 information into yytable. */
c3e23647 889
4a120d45 890static void
d2729d44 891sort_actions (void)
c3e23647 892{
6c89f1c1
AD
893 int i;
894 int j;
895 int k;
896 int t;
897 int w;
c3e23647 898
d7913476 899 order = XCALLOC (short, nvectors);
c3e23647
RS
900 nentries = 0;
901
902 for (i = 0; i < nvectors; i++)
903 {
904 if (tally[i] > 0)
905 {
906 t = tally[i];
907 w = width[i];
908 j = nentries - 1;
909
910 while (j >= 0 && (width[order[j]] < w))
911 j--;
912
913 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
914 j--;
915
916 for (k = nentries - 1; k > j; k--)
917 order[k + 1] = order[k];
918
919 order[j + 1] = i;
920 nentries++;
921 }
922 }
923}
924
925
4a120d45 926static int
d2729d44 927matching_state (int vector)
c3e23647 928{
6c89f1c1
AD
929 int i;
930 int j;
931 int k;
932 int t;
933 int w;
934 int match;
935 int prev;
c3e23647
RS
936
937 i = order[vector];
938 if (i >= nstates)
36281465 939 return -1;
c3e23647
RS
940
941 t = tally[i];
942 w = width[i];
943
944 for (prev = vector - 1; prev >= 0; prev--)
945 {
946 j = order[prev];
947 if (width[j] != w || tally[j] != t)
36281465 948 return -1;
c3e23647
RS
949
950 match = 1;
951 for (k = 0; match && k < t; k++)
952 {
953 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
954 match = 0;
955 }
956
957 if (match)
36281465 958 return j;
c3e23647
RS
959 }
960
36281465 961 return -1;
c3e23647
RS
962}
963
964
4a120d45 965static int
d2729d44 966pack_vector (int vector)
c3e23647 967{
6c89f1c1
AD
968 int i;
969 int j;
970 int k;
971 int t;
972 int loc = 0;
973 int ok;
974 short *from;
975 short *to;
c3e23647
RS
976
977 i = order[vector];
978 t = tally[i];
979
340ef489 980 assert (t);
c3e23647
RS
981
982 from = froms[i];
983 to = tos[i];
984
985 for (j = lowzero - from[0]; j < MAXTABLE; j++)
986 {
987 ok = 1;
988
989 for (k = 0; ok && k < t; k++)
990 {
991 loc = j + from[k];
992 if (loc > MAXTABLE)
a0f6b076 993 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
c3e23647
RS
994
995 if (table[loc] != 0)
996 ok = 0;
997 }
998
999 for (k = 0; ok && k < vector; k++)
1000 {
1001 if (pos[k] == j)
1002 ok = 0;
1003 }
1004
1005 if (ok)
1006 {
1007 for (k = 0; k < t; k++)
1008 {
1009 loc = j + from[k];
1010 table[loc] = to[k];
1011 check[loc] = from[k];
1012 }
1013
1014 while (table[lowzero] != 0)
1015 lowzero++;
1016
1017 if (loc > high)
1018 high = loc;
1019
36281465 1020 return j;
c3e23647
RS
1021 }
1022 }
1023
ceed8467
AD
1024 berror ("pack_vector");
1025 return 0; /* JF keep lint happy */
c3e23647
RS
1026}
1027
1028
6c89f1c1
AD
1029static void
1030pack_table (void)
1031{
1032 int i;
1033 int place;
1034 int state;
1035
d7913476
AD
1036 base = XCALLOC (short, nvectors);
1037 pos = XCALLOC (short, nentries);
1038 table = XCALLOC (short, MAXTABLE);
1039 check = XCALLOC (short, MAXTABLE);
6c89f1c1
AD
1040
1041 lowzero = 0;
1042 high = 0;
1043
1044 for (i = 0; i < nvectors; i++)
1045 base[i] = MINSHORT;
1046
1047 for (i = 0; i < MAXTABLE; i++)
1048 check[i] = -1;
1049
1050 for (i = 0; i < nentries; i++)
1051 {
1052 state = matching_state (i);
1053
1054 if (state < 0)
1055 place = pack_vector (i);
1056 else
1057 place = base[state];
1058
1059 pos[i] = place;
1060 base[order[i]] = place;
1061 }
1062
1063 for (i = 0; i < nvectors; i++)
1064 {
1065 if (froms[i])
d7913476 1066 XFREE (froms[i]);
6c89f1c1 1067 if (tos[i])
d7913476 1068 XFREE (tos[i]);
6c89f1c1
AD
1069 }
1070
d7913476
AD
1071 XFREE (froms);
1072 XFREE (tos);
1073 XFREE (pos);
6c89f1c1 1074}
c3e23647
RS
1075
1076/* the following functions output yytable, yycheck
1077 and the vectors whose elements index the portion starts */
1078
4a120d45 1079static void
d2729d44 1080output_base (void)
c3e23647 1081{
896fe5c1 1082 output_short_table (&table_obstack, NULL, "yypact", base,
d019d655 1083 base[0], 1, nstates);
c3e23647 1084
896fe5c1 1085 obstack_1grow (&table_obstack, '\n');
c3e23647 1086
896fe5c1 1087 output_short_table (&table_obstack, NULL, "yypgoto", base,
d019d655 1088 base[nstates], nstates + 1, nvectors);
c3e23647 1089
d7913476 1090 XFREE (base);
c3e23647
RS
1091}
1092
1093
4a120d45 1094static void
d2729d44 1095output_table (void)
c3e23647 1096{
896fe5c1
AD
1097 obstack_fgrow1 (&table_obstack, "\n\n#define\tYYLAST\t\t%d\n\n\n", high);
1098 output_short_table (&table_obstack, NULL, "yytable", table,
d019d655 1099 table[0], 1, high + 1);
d7913476 1100 XFREE (table);
c3e23647
RS
1101}
1102
1103
4a120d45 1104static void
d2729d44 1105output_check (void)
c3e23647 1106{
896fe5c1 1107 output_short_table (&table_obstack, NULL, "yycheck", check,
d019d655 1108 check[0], 1, high + 1);
d7913476 1109 XFREE (check);
c3e23647
RS
1110}
1111
6c89f1c1
AD
1112/* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
1113 and yycheck. */
1114
1115static void
1116output_actions (void)
1117{
1118 nvectors = nstates + nvars;
c3e23647 1119
d7913476
AD
1120 froms = XCALLOC (short *, nvectors);
1121 tos = XCALLOC (short *, nvectors);
1122 tally = XCALLOC (short, nvectors);
1123 width = XCALLOC (short, nvectors);
6c89f1c1
AD
1124
1125 token_actions ();
1126 free_shifts ();
1127 free_reductions ();
d7913476
AD
1128 XFREE (lookaheads);
1129 XFREE (LA);
1130 XFREE (LAruleno);
1131 XFREE (accessing_symbol);
6c89f1c1
AD
1132
1133 goto_actions ();
d7913476
AD
1134 XFREE (goto_map + ntokens);
1135 XFREE (from_state);
1136 XFREE (to_state);
6c89f1c1
AD
1137
1138 sort_actions ();
1139 pack_table ();
896fe5c1 1140 obstack_1grow (&table_obstack, '\n');
6c89f1c1
AD
1141 output_base ();
1142 output_table ();
896fe5c1 1143 obstack_1grow (&table_obstack, '\n');
6c89f1c1
AD
1144 output_check ();
1145}
c3e23647 1146
ff61dabd
AD
1147/*------------------------------------------.
1148| Copy the parser code into TABLE_OBSTACK. |
1149`------------------------------------------*/
c3e23647 1150
4a120d45 1151static void
d2729d44 1152output_parser (void)
c3e23647 1153{
6c89f1c1 1154 int c;
ff61dabd 1155 FILE *fskel;
ef7ddedd 1156 size_t line;
573c1d9f 1157 int actions_dumped = 0;
c3e23647
RS
1158
1159 if (pure_parser)
ff4423cc 1160 obstack_sgrow (&table_obstack, "#define YYPURE 1\n\n");
c3e23647 1161
ff61dabd 1162 /* Loop over lines in the standard parser file. */
cd5bd6ac
AD
1163 if (!skeleton)
1164 {
1165 if (semantic_parser)
1166 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
1167 else
1168 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
1169 }
ef7ddedd
AD
1170 fskel = xfopen (skeleton, "r");
1171
1172 /* Set LINE to 2, not 1: `#line LINENUM' -- Here LINENUM is a
1173 decimal integer constant. This specifies that the line number of
1174 the *following* line of input, in its original source file, was
1175 LINENUM. */
1176 line = 2;
c3e23647
RS
1177
1178 while (1)
1179 {
573c1d9f
AD
1180 enum line_type_e
1181 {
1182 regular_line,
1183 sync_line, /* #line. */
1184 actions_line /* %% actions. */
1185 };
1186 enum line_type_e line_type = regular_line;
c3e23647 1187
ff61dabd 1188 c = getc (fskel);
c3e23647 1189
573c1d9f 1190 /* Is this line special? */
ef7ddedd 1191 if (c == '#')
573c1d9f
AD
1192 {
1193 /* See if it's a `#line' line. */
1194 if ((c = getc (fskel)) == 'l')
1195 if ((c = getc (fskel)) == 'i')
1196 if ((c = getc (fskel)) == 'n')
1197 if ((c = getc (fskel)) == 'e')
1198 line_type = sync_line;
1199 else
ff4423cc 1200 obstack_sgrow (&table_obstack, "#lin");
ef7ddedd 1201 else
ff4423cc 1202 obstack_sgrow (&table_obstack, "#li");
c3e23647 1203 else
ff4423cc 1204 obstack_sgrow (&table_obstack, "#l");
ef7ddedd 1205 else
ff4423cc 1206 obstack_sgrow (&table_obstack, "#");
573c1d9f
AD
1207 }
1208 else if (c == '%')
1209 {
1210 /* See if it's a `%% actions' line. */
1211 if ((c = getc (fskel)) == '%')
1212 if ((c = getc (fskel)) == ' ')
1213 if ((c = getc (fskel)) == 'a')
1214 if ((c = getc (fskel)) == 'c')
1215 if ((c = getc (fskel)) == 't')
1216 if ((c = getc (fskel)) == 'i')
1217 if ((c = getc (fskel)) == 'o')
1218 if ((c = getc (fskel)) == 'n')
1219 if ((c = getc (fskel)) == 's')
1220 line_type = actions_line;
1221 else
ff4423cc 1222 obstack_sgrow (&table_obstack, "%% action");
573c1d9f 1223 else
ff4423cc 1224 obstack_sgrow (&table_obstack, "%% actio");
573c1d9f 1225 else
ff4423cc 1226 obstack_sgrow (&table_obstack, "%% acti");
573c1d9f 1227 else
ff4423cc 1228 obstack_sgrow (&table_obstack, "%% act");
573c1d9f 1229 else
ff4423cc 1230 obstack_sgrow (&table_obstack, "%% ac");
573c1d9f 1231 else
ff4423cc 1232 obstack_sgrow (&table_obstack, "%% a");
573c1d9f 1233 else
ff4423cc 1234 obstack_sgrow (&table_obstack, "%% ");
573c1d9f 1235 else
ff4423cc 1236 obstack_sgrow (&table_obstack, "%%");
573c1d9f 1237 else
ff4423cc 1238 obstack_sgrow (&table_obstack, "%");
573c1d9f 1239 }
ef7ddedd 1240
573c1d9f
AD
1241 switch (line_type)
1242 {
1243 case sync_line:
1244 if (!no_lines_flag)
1245 obstack_fgrow2 (&table_obstack, "#line %d %s\n",
1246 line, quotearg_style (c_quoting_style, skeleton));
ef7ddedd 1247
573c1d9f
AD
1248 /* Skip the end of line. */
1249 for (; c != '\n' && c != EOF; c = getc (fskel))
1250 /* nothing */;
1251 break;
c3e23647 1252
573c1d9f 1253 case actions_line:
ceed8467 1254 {
573c1d9f
AD
1255 size_t size = obstack_object_size (&action_obstack);
1256
1257 actions_dumped++;
1258 assert (actions_dumped == 1);
1259 obstack_grow (&table_obstack,
1260 obstack_finish (&action_obstack),
1261 size);
ceed8467 1262 }
573c1d9f
AD
1263
1264 /* Skip the end of line. */
1265 for (; c != '\n' && c != EOF; c = getc (fskel))
1266 /* nothing */;
1267 break;
1268
1269 case regular_line:
1270 for (; c != '\n' && c != EOF; c = getc (fskel))
1271 obstack_1grow (&table_obstack, c);
1272 }
1273
c3e23647
RS
1274 if (c == EOF)
1275 break;
896fe5c1 1276 obstack_1grow (&table_obstack, c);
ef7ddedd 1277 line++;
c3e23647 1278 }
573c1d9f 1279 assert (actions_dumped == 1);
ff61dabd 1280 xfclose (fskel);
c3e23647
RS
1281}
1282
4a120d45 1283static void
d2729d44 1284output_program (void)
c3e23647 1285{
6c89f1c1 1286 int c;
c3e23647 1287
89cab50d 1288 if (!no_lines_flag)
14d3eb9b
AD
1289 obstack_fgrow2 (&table_obstack, "#line %d %s\n",
1290 lineno, quotearg_style (c_quoting_style, infile));
c3e23647 1291
14d3eb9b
AD
1292 while ((c = getc (finput)) != EOF)
1293 obstack_1grow (&table_obstack, c);
c3e23647
RS
1294}
1295
1296
4a120d45 1297static void
d2729d44 1298free_itemsets (void)
c3e23647 1299{
6c89f1c1 1300 core *cp, *cptmp;
c3e23647 1301
d7913476 1302 XFREE (state_table);
c3e23647 1303
36281465
AD
1304 for (cp = first_state; cp; cp = cptmp)
1305 {
ceed8467 1306 cptmp = cp->next;
d7913476 1307 XFREE (cp);
36281465 1308 }
c3e23647
RS
1309}
1310
1311
6c89f1c1
AD
1312/*----------------------------------------------------------.
1313| Output the parsing tables and the parser code to ftable. |
1314`----------------------------------------------------------*/
c3e23647 1315
6c89f1c1
AD
1316void
1317output (void)
1318{
6c89f1c1 1319 /* output_token_defines(ftable); / * JF put out token defines FIRST */
dd60faec
AD
1320
1321 /* If using a simple parser the definition of YYSTYPE are put into
896fe5c1 1322 TABLE_OBSTACK. */
dd60faec 1323 if (!semantic_parser)
36281465 1324 {
dd60faec 1325 size_t size = obstack_object_size (&attrs_obstack);
896fe5c1 1326 obstack_grow (&table_obstack, obstack_finish (&attrs_obstack), size);
36281465 1327 }
896fe5c1 1328 reader_output_yylsp (&table_obstack);
89cab50d 1329 if (debug_flag)
ff4423cc 1330 obstack_sgrow (&table_obstack, "\
6c89f1c1 1331#ifndef YYDEBUG\n\
71da9eea 1332# define YYDEBUG 1\n\
6c89f1c1 1333#endif\n\
896fe5c1 1334\n");
c3e23647 1335
6c89f1c1 1336 if (semantic_parser)
14d3eb9b
AD
1337 obstack_fgrow1 (&table_obstack, "#include %s\n",
1338 quotearg_style (c_quoting_style, attrsfile));
c3e23647 1339
89cab50d 1340 if (!no_parser_flag)
ff4423cc 1341 obstack_sgrow (&table_obstack, "#include <stdio.h>\n\n");
c3e23647 1342
6c89f1c1 1343 /* Make "const" do nothing if not in ANSI C. */
ff4423cc 1344 obstack_sgrow (&table_obstack, "\
6c89f1c1
AD
1345#ifndef __cplusplus\n\
1346# ifndef __STDC__\n\
1347# define const\n\
1348# endif\n\
1349#endif\n\
896fe5c1 1350\n");
c3e23647 1351
6c89f1c1
AD
1352 free_itemsets ();
1353 output_defines ();
1354 output_token_translations ();
1355/* if (semantic_parser) */
1356 /* This is now unconditional because debugging printouts can use it. */
1357 output_gram ();
d7913476 1358 XFREE (ritem);
6c89f1c1
AD
1359 if (semantic_parser)
1360 output_stos ();
1361 output_rule_data ();
1362 output_actions ();
89cab50d 1363 if (!no_parser_flag)
6c89f1c1
AD
1364 output_parser ();
1365 output_program ();
c3e23647 1366}