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