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