]> git.saurik.com Git - bison.git/blame - src/parse-gram.y
(xsl:template name="escape"): Write xsl:param "required" attribute as comment.
[bison.git] / src / parse-gram.y
CommitLineData
12ffdd28 1%{/* Bison Grammar Parser -*- C -*-
a737b216 2
7c0c6181
JD
3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation,
4 Inc.
e9955c83
AD
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
f16b0819 8 This program is free software: you can redistribute it and/or modify
e9955c83 9 it under the terms of the GNU General Public License as published by
f16b0819 10 the Free Software Foundation, either version 3 of the License, or
e9955c83
AD
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
e9955c83 20
2cec9080 21#include <config.h>
e9955c83 22#include "system.h"
3d2cbc26 23
cb48f191
PE
24#include <strverscmp.h>
25
b275314e 26#include "complain.h"
3d2cbc26 27#include "conflicts.h"
e9955c83
AD
28#include "files.h"
29#include "getargs.h"
e9955c83 30#include "gram.h"
3d2cbc26 31#include "muscle_tab.h"
ca407bdf 32#include "quotearg.h"
e9955c83 33#include "reader.h"
3d2cbc26 34#include "symlist.h"
e9071366
AD
35#include "scan-gram.h"
36#include "scan-code.h"
e9955c83 37
b7295522
PE
38#define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N)
39static YYLTYPE lloc_default (YYLTYPE const *, int);
4cdb01db 40
b233d555 41#define YY_LOCATION_PRINT(File, Loc) \
f0064700 42 location_print (File, Loc)
b233d555 43
b50d2359
AD
44static void version_check (location const *loc, char const *version);
45
6e649e65 46/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
ad8a3efc 47 FIXME: depends on the undocumented availability of YYLLOC. */
e9955c83
AD
48#undef yyerror
49#define yyerror(Msg) \
f0064700 50 gram_error (&yylloc, Msg)
3d2cbc26 51static void gram_error (location const *, char const *);
e9955c83 52
33ad1a9c
PE
53static char const *char_name (char);
54
2ce4ed68
AD
55/** Add a lex-param or a parse-param.
56 *
57 * \param type \a lex_param or \a parse_param
58 * \param decl the formal argument
59 * \param loc the location in the source.
60 */
61static void add_param (char const *type, char *decl, location loc);
62
1773ceee 63
04098407 64static symbol_class current_class = unknown_sym;
ddc8ede1 65static uniqstr current_type = NULL;
877519f8
PE
66static symbol *current_lhs;
67static location current_lhs_location;
04098407 68static int current_prec = 0;
d42cf844 69
cb48f191
PE
70#define YYTYPE_INT16 int_fast16_t
71#define YYTYPE_INT8 int_fast8_t
72#define YYTYPE_UINT16 uint_fast16_t
73#define YYTYPE_UINT8 uint_fast8_t
e9955c83
AD
74%}
75
12ffdd28 76%debug
82b248ad 77%verbose
12ffdd28
PE
78%defines
79%locations
80%pure-parser
81%error-verbose
12ffdd28 82%name-prefix="gram_"
219741d8 83%expect 0
12ffdd28 84
cd3684cf
AD
85%initial-action
86{
87 /* Bison's grammar can initial empty locations, hence a default
88 location is needed. */
4a678af8
JD
89 boundary_set (&@$.start, current_file, 1, 1);
90 boundary_set (&@$.end, current_file, 1, 1);
cd3684cf 91}
e9955c83 92
e9955c83
AD
93%union
94{
3d2cbc26
PE
95 symbol *symbol;
96 symbol_list *list;
e9955c83 97 int integer;
eb095650
PE
98 char const *chars;
99 char *code;
3d2cbc26
PE
100 assoc assoc;
101 uniqstr uniqstr;
58d7a1a1 102 unsigned char character;
e9955c83
AD
103};
104
f9a85a15 105/* Define the tokens together with their human representation. */
3d38c03a
AD
106%token GRAM_EOF 0 "end of file"
107%token STRING "string"
3d38c03a 108%token INT "integer"
e9955c83 109
9280d3ef
AD
110%token PERCENT_TOKEN "%token"
111%token PERCENT_NTERM "%nterm"
366eea36 112
9280d3ef 113%token PERCENT_TYPE "%type"
e9071366
AD
114%token PERCENT_DESTRUCTOR "%destructor"
115%token PERCENT_PRINTER "%printer"
366eea36 116
9280d3ef
AD
117%token PERCENT_LEFT "%left"
118%token PERCENT_RIGHT "%right"
119%token PERCENT_NONASSOC "%nonassoc"
04e60654 120
3d38c03a
AD
121%token PERCENT_PREC "%prec"
122%token PERCENT_DPREC "%dprec"
123%token PERCENT_MERGE "%merge"
e9955c83 124
e9955c83 125
ae7453f2
AD
126/*----------------------.
127| Global Declarations. |
128`----------------------*/
129
130%token
136a0f76 131 PERCENT_CODE "%code"
cd3684cf 132 PERCENT_DEBUG "%debug"
39a06c25 133 PERCENT_DEFAULT_PREC "%default-prec"
cd3684cf
AD
134 PERCENT_DEFINE "%define"
135 PERCENT_DEFINES "%defines"
136 PERCENT_ERROR_VERBOSE "%error-verbose"
137 PERCENT_EXPECT "%expect"
d6328241 138 PERCENT_EXPECT_RR "%expect-rr"
cd3684cf
AD
139 PERCENT_FILE_PREFIX "%file-prefix"
140 PERCENT_GLR_PARSER "%glr-parser"
e9071366 141 PERCENT_INITIAL_ACTION "%initial-action"
0e021770 142 PERCENT_LANGUAGE "%language"
e9071366 143 PERCENT_LEX_PARAM "%lex-param"
cd3684cf
AD
144 PERCENT_LOCATIONS "%locations"
145 PERCENT_NAME_PREFIX "%name-prefix"
22fccf95 146 PERCENT_NO_DEFAULT_PREC "%no-default-prec"
cd3684cf
AD
147 PERCENT_NO_LINES "%no-lines"
148 PERCENT_NONDETERMINISTIC_PARSER
f0064700 149 "%nondeterministic-parser"
cd3684cf 150 PERCENT_OUTPUT "%output"
e9071366 151 PERCENT_PARSE_PARAM "%parse-param"
cd3684cf 152 PERCENT_PURE_PARSER "%pure-parser"
f0064700 153 PERCENT_REQUIRE "%require"
cd3684cf
AD
154 PERCENT_SKELETON "%skeleton"
155 PERCENT_START "%start"
156 PERCENT_TOKEN_TABLE "%token-table"
157 PERCENT_VERBOSE "%verbose"
158 PERCENT_YACC "%yacc"
ae7453f2 159;
e9955c83 160
58d7a1a1
AD
161%token BRACED_CODE "{...}"
162%token CHAR "char"
163%token EPILOGUE "epilogue"
3d38c03a 164%token EQUAL "="
3d38c03a 165%token ID "identifier"
b7295522 166%token ID_COLON "identifier:"
e9955c83 167%token PERCENT_PERCENT "%%"
58d7a1a1 168%token PIPE "|"
3d38c03a 169%token PROLOGUE "%{...%}"
58d7a1a1
AD
170%token SEMICOLON ";"
171%token TYPE "type"
12e35840 172%token TYPE_TAG_ANY "<*>"
3ebecc24 173%token TYPE_TAG_NONE "<>"
58d7a1a1
AD
174
175%type <character> CHAR
33ad1a9c 176%printer { fputs (char_name ($$), stderr); } CHAR
3d38c03a 177
2ce4ed68 178/* braceless is not to be used for rule or symbol actions, as it
7c0c6181 179 calls code_props_plain_init. */
6afc30cc 180%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
eb095650 181%type <code> "{...}"
33ad1a9c 182%printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
eb095650 183 STRING
2ce4ed68 184%printer { fprintf (stderr, "{\n%s\n}", $$); }
6afc30cc 185 braceless content.opt "{...}" "%{...%}" EPILOGUE
58d7a1a1 186
16dc6a9e 187%type <uniqstr> TYPE ID ID_COLON variable
82b248ad 188%printer { fprintf (stderr, "<%s>", $$); } TYPE
16dc6a9e 189%printer { fputs ($$, stderr); } ID variable
58d7a1a1
AD
190%printer { fprintf (stderr, "%s:", $$); } ID_COLON
191
e9955c83 192%type <integer> INT
82b248ad 193%printer { fprintf (stderr, "%d", $$); } INT
58d7a1a1
AD
194
195%type <symbol> id id_colon symbol string_as_id
196%printer { fprintf (stderr, "%s", $$->tag); } id symbol string_as_id
197%printer { fprintf (stderr, "%s:", $$->tag); } id_colon
198
2c569025 199%type <assoc> precedence_declarator
3be03b13 200%type <list> symbols.1 generic_symlist generic_symlist_item
e9955c83 201%%
2c569025 202
8efe435c 203input:
2ce4ed68 204 prologue_declarations "%%" grammar epilogue.opt
e9955c83
AD
205;
206
2c569025
AD
207
208 /*------------------------------------.
209 | Declarations: before the first %%. |
210 `------------------------------------*/
211
2ce4ed68 212prologue_declarations:
e9955c83 213 /* Nothing */
2ce4ed68 214| prologue_declarations prologue_declaration
e9955c83
AD
215;
216
2ce4ed68 217prologue_declaration:
2c569025 218 grammar_declaration
7c0c6181
JD
219| "%{...%}"
220 {
221 code_props plain_code;
222 code_props_plain_init (&plain_code, $1, @1);
223 code_props_translate_code (&plain_code);
224 gram_scanner_last_string_free ();
7ecec4dd
JD
225 muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
226 plain_code.code, @1);
7c0c6181
JD
227 code_scanner_last_string_free ();
228 }
2ce4ed68 229| "%debug" { debug_flag = true; }
16dc6a9e 230| "%define" variable content.opt
7eb8a0bc 231 {
9611cfa2 232 muscle_percent_define_insert ($2, @2, $3);
7eb8a0bc 233 }
2ce4ed68 234| "%defines" { defines_flag = true; }
02975b9a
JD
235| "%defines" STRING
236 {
237 defines_flag = true;
238 spec_defines_file = xstrdup ($2);
239 }
2ce4ed68
AD
240| "%error-verbose" { error_verbose = true; }
241| "%expect" INT { expected_sr_conflicts = $2; }
242| "%expect-rr" INT { expected_rr_conflicts = $2; }
02975b9a
JD
243| "%file-prefix" STRING { spec_file_prefix = $2; }
244| "%file-prefix" "=" STRING { spec_file_prefix = $3; } /* deprecated */
cd3684cf 245| "%glr-parser"
c66dfadd
PE
246 {
247 nondeterministic_parser = true;
248 glr_parser = true;
249 }
e9071366 250| "%initial-action" "{...}"
c66dfadd 251 {
7c0c6181
JD
252 code_props action;
253 code_props_symbol_action_init (&action, $2, @2);
254 code_props_translate_code (&action);
255 gram_scanner_last_string_free ();
256 muscle_code_grow ("initial_action", action.code, @2);
257 code_scanner_last_string_free ();
c66dfadd 258 }
0e021770 259| "%language" STRING { language_argmatch ($2, 1, &@1); }
2ce4ed68
AD
260| "%lex-param" "{...}" { add_param ("lex_param", $2, @2); }
261| "%locations" { locations_flag = true; }
02975b9a
JD
262| "%name-prefix" STRING { spec_name_prefix = $2; }
263| "%name-prefix" "=" STRING { spec_name_prefix = $3; } /* deprecated */
2ce4ed68
AD
264| "%no-lines" { no_lines_flag = true; }
265| "%nondeterministic-parser" { nondeterministic_parser = true; }
02975b9a
JD
266| "%output" STRING { spec_outfile = $2; }
267| "%output" "=" STRING { spec_outfile = $3; } /* deprecated */
2ce4ed68
AD
268| "%parse-param" "{...}" { add_param ("parse_param", $2, @2); }
269| "%pure-parser" { pure_parser = true; }
270| "%require" STRING { version_check (&@2, $2); }
a7867f53
JD
271| "%skeleton" STRING
272 {
273 char const *skeleton_user = $2;
274 if (strchr (skeleton_user, '/'))
275 {
276 size_t dir_length = strlen (current_file);
277 char *skeleton_build;
278 while (dir_length && current_file[dir_length - 1] != '/')
279 --dir_length;
280 while (dir_length && current_file[dir_length - 1] == '/')
281 --dir_length;
282 skeleton_build =
283 xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
284 if (dir_length > 0)
285 {
286 strncpy (skeleton_build, current_file, dir_length);
287 skeleton_build[dir_length++] = '/';
288 }
289 strcpy (skeleton_build + dir_length, skeleton_user);
290 skeleton_user = uniqstr_new (skeleton_build);
291 free (skeleton_build);
292 }
293 skeleton_arg (skeleton_user, 1, &@1);
294 }
2ce4ed68
AD
295| "%token-table" { token_table_flag = true; }
296| "%verbose" { report_flag = report_states; }
297| "%yacc" { yacc_flag = true; }
cd3684cf 298| /*FIXME: Err? What is this horror doing here? */ ";"
e9955c83
AD
299;
300
2c569025
AD
301grammar_declaration:
302 precedence_declaration
303| symbol_declaration
e9955c83
AD
304| "%start" symbol
305 {
8efe435c 306 grammar_start_symbol_set ($2, @2);
e9955c83 307 }
3be03b13 308| "%destructor" "{...}" generic_symlist
9280d3ef 309 {
3d2cbc26 310 symbol_list *list;
e9071366 311 for (list = $3; list; list = list->next)
7c0c6181 312 symbol_list_destructor_set (list, $2, @2);
e9071366 313 symbol_list_free ($3);
9280d3ef 314 }
3be03b13 315| "%printer" "{...}" generic_symlist
366eea36 316 {
3d2cbc26 317 symbol_list *list;
e9071366 318 for (list = $3; list; list = list->next)
7c0c6181 319 symbol_list_printer_set (list, $2, @2);
e9071366 320 symbol_list_free ($3);
366eea36 321 }
22fccf95 322| "%default-prec"
39a06c25 323 {
22fccf95
PE
324 default_prec = true;
325 }
326| "%no-default-prec"
327 {
328 default_prec = false;
39a06c25 329 }
8e0a5e9e
JD
330| "%code" braceless
331 {
9611cfa2
JD
332 /* Do not invoke muscle_percent_code_grow here since it invokes
333 muscle_user_name_list_grow. */
592d0b1e 334 muscle_code_grow ("percent_code()", $2, @2);
8e0a5e9e
JD
335 code_scanner_last_string_free ();
336 }
16dc6a9e 337| "%code" ID braceless
8e0a5e9e 338 {
9611cfa2 339 muscle_percent_code_grow ($2, @2, $3, @3);
8e0a5e9e 340 code_scanner_last_string_free ();
8e0a5e9e 341 }
2c569025
AD
342;
343
58d7a1a1
AD
344
345/*----------*
346 | %union. |
347 *----------*/
348
349%token PERCENT_UNION "%union";
350
351union_name:
352 /* Nothing. */ {}
353| ID { muscle_code_grow ("union_name", $1, @1); }
354;
355
356grammar_declaration:
7ecec4dd 357 "%union" union_name braceless
58d7a1a1 358 {
ddc8ede1 359 union_seen = true;
7ecec4dd
JD
360 muscle_code_grow ("stype", $3, @3);
361 code_scanner_last_string_free ();
58d7a1a1
AD
362 }
363;
364
365
366
367
2c569025
AD
368symbol_declaration:
369 "%nterm" { current_class = nterm_sym; } symbol_defs.1
e9955c83
AD
370 {
371 current_class = unknown_sym;
372 current_type = NULL;
373 }
2c569025 374| "%token" { current_class = token_sym; } symbol_defs.1
e9955c83 375 {
2c569025 376 current_class = unknown_sym;
e9955c83
AD
377 current_type = NULL;
378 }
1e0bab92 379| "%type" TYPE symbols.1
e9955c83 380 {
3d2cbc26 381 symbol_list *list;
4f82b42a 382 tag_seen = true;
1e0bab92 383 for (list = $3; list; list = list->next)
3be03b13 384 symbol_type_set (list->content.sym, $2, @2);
dafdc66f 385 symbol_list_free ($3);
e9955c83
AD
386 }
387;
388
2c569025 389precedence_declaration:
1e0bab92
AD
390 precedence_declarator type.opt symbols.1
391 {
3d2cbc26 392 symbol_list *list;
1e0bab92
AD
393 ++current_prec;
394 for (list = $3; list; list = list->next)
395 {
3be03b13
JD
396 symbol_type_set (list->content.sym, current_type, @2);
397 symbol_precedence_set (list->content.sym, current_prec, $1, @1);
1e0bab92 398 }
dafdc66f 399 symbol_list_free ($3);
1e0bab92
AD
400 current_type = NULL;
401 }
e9955c83
AD
402;
403
2c569025 404precedence_declarator:
e9955c83
AD
405 "%left" { $$ = left_assoc; }
406| "%right" { $$ = right_assoc; }
407| "%nonassoc" { $$ = non_assoc; }
408;
409
410type.opt:
87fbb0bf 411 /* Nothing. */ { current_type = NULL; }
ddc8ede1 412| TYPE { current_type = $1; tag_seen = true; }
e9955c83
AD
413;
414
3be03b13 415/* One or more symbols to be %typed. */
1e0bab92 416symbols.1:
3be03b13
JD
417 symbol
418 { $$ = symbol_list_sym_new ($1, @1); }
419| symbols.1 symbol
420 { $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
421;
422
423generic_symlist:
424 generic_symlist_item { $$ = $1; }
425| generic_symlist generic_symlist_item { $$ = symbol_list_prepend ($1, $2); }
426;
427
428generic_symlist_item:
429 symbol { $$ = symbol_list_sym_new ($1, @1); }
430| TYPE { $$ = symbol_list_type_new ($1, @1); }
12e35840 431| "<*>" { $$ = symbol_list_default_tagged_new (@1); }
3ebecc24 432| "<>" { $$ = symbol_list_default_tagless_new (@1); }
e9955c83
AD
433;
434
e9955c83
AD
435/* One token definition. */
436symbol_def:
437 TYPE
438 {
439 current_type = $1;
ddc8ede1 440 tag_seen = true;
e9955c83 441 }
58d7a1a1 442| id
e9955c83 443 {
073f9288 444 symbol_class_set ($1, current_class, @1, true);
1a31ed21 445 symbol_type_set ($1, current_type, @1);
e9955c83 446 }
58d7a1a1 447| id INT
e9955c83 448 {
073f9288 449 symbol_class_set ($1, current_class, @1, true);
1a31ed21 450 symbol_type_set ($1, current_type, @1);
e776192e 451 symbol_user_token_number_set ($1, $2, @2);
e9955c83 452 }
58d7a1a1 453| id string_as_id
e9955c83 454 {
073f9288 455 symbol_class_set ($1, current_class, @1, true);
1a31ed21 456 symbol_type_set ($1, current_type, @1);
a5d50994 457 symbol_make_alias ($1, $2, @$);
e9955c83 458 }
58d7a1a1 459| id INT string_as_id
e9955c83 460 {
073f9288 461 symbol_class_set ($1, current_class, @1, true);
1a31ed21 462 symbol_type_set ($1, current_type, @1);
e776192e 463 symbol_user_token_number_set ($1, $2, @2);
a5d50994 464 symbol_make_alias ($1, $3, @$);
e9955c83
AD
465 }
466;
467
468/* One or more symbol definitions. */
469symbol_defs.1:
470 symbol_def
e9955c83 471| symbol_defs.1 symbol_def
e9955c83
AD
472;
473
2c569025
AD
474
475 /*------------------------------------------.
476 | The grammar section: between the two %%. |
477 `------------------------------------------*/
478
479grammar:
1921f1d7
AD
480 rules_or_grammar_declaration
481| grammar rules_or_grammar_declaration
482;
483
484/* As a Bison extension, one can use the grammar declarations in the
b7295522 485 body of the grammar. */
1921f1d7 486rules_or_grammar_declaration:
e9955c83 487 rules
8d0a98bb 488| grammar_declaration ";"
b275314e
AD
489| error ";"
490 {
491 yyerrok;
492 }
e9955c83
AD
493;
494
495rules:
58d7a1a1 496 id_colon { current_lhs = $1; current_lhs_location = @1; } rhses.1
e9955c83
AD
497;
498
499rhses.1:
8f3596a6
AD
500 rhs { grammar_current_rule_end (@1); }
501| rhses.1 "|" rhs { grammar_current_rule_end (@3); }
8d0a98bb 502| rhses.1 ";"
e9955c83
AD
503;
504
505rhs:
506 /* Nothing. */
8f3596a6 507 { grammar_current_rule_begin (current_lhs, current_lhs_location); }
e9955c83 508| rhs symbol
8efe435c 509 { grammar_current_rule_symbol_append ($2, @2); }
e9071366 510| rhs "{...}"
381ecb06 511 { grammar_current_rule_action_append ($2, @2); }
e9955c83 512| rhs "%prec" symbol
e776192e 513 { grammar_current_rule_prec_set ($3, @3); }
676385e2
PH
514| rhs "%dprec" INT
515 { grammar_current_rule_dprec_set ($3, @3); }
516| rhs "%merge" TYPE
517 { grammar_current_rule_merge_set ($3, @3); }
e9955c83
AD
518;
519
58d7a1a1 520
16dc6a9e
JD
521/*----------------------------*
522 | variable and content.opt. |
523 *---------------------------*/
524
525variable:
526 ID
527 | STRING { $$ = uniqstr_new ($1); } /* deprecated and not M4-friendly */
528 ;
2ce4ed68 529
592d0b1e 530/* Some content or empty by default. */
2ce4ed68
AD
531content.opt:
532 /* Nothing. */
533 {
592d0b1e 534 $$ = "";
2ce4ed68 535 }
6afc30cc 536| STRING
2ce4ed68
AD
537;
538
539
6afc30cc
JD
540/*-------------*
541 | braceless. |
542 *-------------*/
543
2ce4ed68
AD
544braceless:
545 "{...}"
546 {
7c0c6181 547 code_props plain_code;
2ce4ed68 548 $1[strlen ($1) - 1] = '\n';
7c0c6181
JD
549 code_props_plain_init (&plain_code, $1+1, @1);
550 code_props_translate_code (&plain_code);
551 gram_scanner_last_string_free ();
552 $$ = plain_code.code;
2ce4ed68
AD
553 }
554;
555
556
58d7a1a1
AD
557/*---------------*
558 | Identifiers. |
559 *---------------*/
560
33ad1a9c
PE
561/* Identifiers are returned as uniqstr values by the scanner.
562 Depending on their use, we may need to make them genuine symbols. */
58d7a1a1
AD
563
564id:
33ad1a9c 565 ID
203b9274 566 { $$ = symbol_from_uniqstr ($1, @1); }
33ad1a9c
PE
567| CHAR
568 {
569 $$ = symbol_get (char_name ($1), @1);
570 symbol_class_set ($$, token_sym, @1, false);
571 symbol_user_token_number_set ($$, $1, @1);
572 }
58d7a1a1
AD
573;
574
575id_colon:
203b9274 576 ID_COLON { $$ = symbol_from_uniqstr ($1, @1); }
58d7a1a1
AD
577;
578
579
e9955c83 580symbol:
58d7a1a1
AD
581 id
582| string_as_id
e9955c83
AD
583;
584
ca407bdf 585/* A string used as an ID: quote it. */
e9955c83
AD
586string_as_id:
587 STRING
588 {
ca407bdf 589 $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
db89d400 590 symbol_class_set ($$, token_sym, @1, false);
e9955c83
AD
591 }
592;
593
e9955c83
AD
594epilogue.opt:
595 /* Nothing. */
e9955c83
AD
596| "%%" EPILOGUE
597 {
7c0c6181
JD
598 code_props plain_code;
599 code_props_plain_init (&plain_code, $2, @2);
600 code_props_translate_code (&plain_code);
e9071366 601 gram_scanner_last_string_free ();
7c0c6181
JD
602 muscle_code_grow ("epilogue", plain_code.code, @2);
603 code_scanner_last_string_free ();
e9955c83
AD
604 }
605;
606
e9955c83 607%%
b7295522
PE
608
609
610/* Return the location of the left-hand side of a rule whose
611 right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
612 the right-hand side, and return an empty location equal to the end
613 boundary of RHS[0] if the right-hand side is empty. */
614
615static YYLTYPE
616lloc_default (YYLTYPE const *rhs, int n)
617{
618 int i;
a737b216 619 YYLTYPE loc;
62cb8a99
PE
620
621 /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
622 The bug is fixed in 7.4.2m, but play it safe for now. */
623 loc.start = rhs[n].end;
624 loc.end = rhs[n].end;
b7295522 625
5320ca4d
PE
626 /* Ignore empty nonterminals the start of the the right-hand side.
627 Do not bother to ignore them at the end of the right-hand side,
628 since empty nonterminals have the same end as their predecessors. */
b7295522
PE
629 for (i = 1; i <= n; i++)
630 if (! equal_boundaries (rhs[i].start, rhs[i].end))
631 {
a737b216 632 loc.start = rhs[i].start;
b7295522
PE
633 break;
634 }
635
a737b216 636 return loc;
b7295522
PE
637}
638
639
640/* Add a lex-param or a parse-param (depending on TYPE) with
641 declaration DECL and location LOC. */
642
1773ceee 643static void
e9ce5688 644add_param (char const *type, char *decl, location loc)
1773ceee 645{
ead9e56e 646 static char const alphanum[26 + 26 + 1 + 10] =
1773ceee
PE
647 "abcdefghijklmnopqrstuvwxyz"
648 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ead9e56e
PE
649 "_"
650 "0123456789";
1773ceee 651 char const *name_start = NULL;
e9ce5688 652 char *p;
1773ceee 653
e503aa60
AD
654 /* Stop on last actual character. */
655 for (p = decl; p[1]; p++)
ead9e56e
PE
656 if ((p == decl
657 || ! memchr (alphanum, p[-1], sizeof alphanum))
658 && memchr (alphanum, p[0], sizeof alphanum - 10))
1773ceee
PE
659 name_start = p;
660
ead9e56e
PE
661 /* Strip the surrounding '{' and '}', and any blanks just inside
662 the braces. */
663 while (*--p == ' ' || *p == '\t')
664 continue;
e503aa60 665 p[1] = '\0';
ead9e56e
PE
666 while (*++decl == ' ' || *decl == '\t')
667 continue;
e9ce5688 668
1773ceee
PE
669 if (! name_start)
670 complain_at (loc, _("missing identifier in parameter declaration"));
671 else
672 {
673 char *name;
674 size_t name_len;
675
676 for (name_len = 1;
ead9e56e 677 memchr (alphanum, name_start[name_len], sizeof alphanum);
1773ceee
PE
678 name_len++)
679 continue;
680
681 name = xmalloc (name_len + 1);
682 memcpy (name, name_start, name_len);
683 name[name_len] = '\0';
684 muscle_pair_list_grow (type, decl, name);
685 free (name);
686 }
687
e9071366 688 gram_scanner_last_string_free ();
1773ceee
PE
689}
690
2ce4ed68 691
b50d2359
AD
692static void
693version_check (location const *loc, char const *version)
694{
695 if (strverscmp (version, PACKAGE_VERSION) > 0)
9b8a5ce0
AD
696 {
697 complain_at (*loc, "require bison %s, but have %s",
698 version, PACKAGE_VERSION);
699 exit (63);
700 }
b50d2359
AD
701}
702
1fec91df 703static void
3d2cbc26 704gram_error (location const *loc, char const *msg)
e9955c83 705{
ad8a3efc 706 complain_at (*loc, "%s", msg);
e9955c83 707}
e9ce5688
PE
708
709char const *
710token_name (int type)
711{
fc01665e 712 return yytname[YYTRANSLATE (type)];
e9ce5688 713}
33ad1a9c
PE
714
715static char const *
716char_name (char c)
717{
718 if (c == '\'')
719 return "'\\''";
720 else
721 {
722 char buf[4];
723 buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
724 return quotearg_style (escape_quoting_style, buf);
725 }
726}