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