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