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