]> git.saurik.com Git - bison.git/blame - src/parse-gram.y
tests: enhance AT_SYNCLINES_COMPILE.
[bison.git] / src / parse-gram.y
CommitLineData
12ffdd28 1%{/* Bison Grammar Parser -*- C -*-
a737b216 2
e141f4d4 3 Copyright (C) 2002-2010 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"
00f5d575 28#include "muscle-tab.h"
872b52bc 29#include "named-ref.h"
ca407bdf 30#include "quotearg.h"
e9955c83 31#include "reader.h"
3d2cbc26 32#include "symlist.h"
e9071366
AD
33#include "scan-gram.h"
34#include "scan-code.h"
e9955c83 35
b7295522
PE
36#define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N)
37static YYLTYPE lloc_default (YYLTYPE const *, int);
4cdb01db 38
b233d555 39#define YY_LOCATION_PRINT(File, Loc) \
f0064700 40 location_print (File, Loc)
b233d555 41
b50d2359
AD
42static void version_check (location const *loc, char const *version);
43
6e649e65 44/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
ad8a3efc 45 FIXME: depends on the undocumented availability of YYLLOC. */
e9955c83
AD
46#undef yyerror
47#define yyerror(Msg) \
f0064700 48 gram_error (&yylloc, Msg)
3d2cbc26 49static void gram_error (location const *, char const *);
e9955c83 50
33ad1a9c 51static char const *char_name (char);
e9955c83
AD
52%}
53
a7706735
AD
54%code
55{
eaca4c11 56 static int current_prec = 0;
a7706735
AD
57 static location current_lhs_location;
58 static named_ref *current_lhs_named_ref;
eaca4c11
AD
59 static symbol *current_lhs;
60 static symbol_class current_class = unknown_sym;
61 static uniqstr current_type = NULL;
a7706735
AD
62
63 #define YYTYPE_INT16 int_fast16_t
64 #define YYTYPE_INT8 int_fast8_t
65 #define YYTYPE_UINT16 uint_fast16_t
66 #define YYTYPE_UINT8 uint_fast8_t
67}
68
12ffdd28 69%debug
82b248ad 70%verbose
12ffdd28
PE
71%defines
72%locations
73%pure-parser
31b850d2 74%define parse.error "verbose"
12ffdd28 75%name-prefix="gram_"
219741d8 76%expect 0
12ffdd28 77
cd3684cf
AD
78%initial-action
79{
80 /* Bison's grammar can initial empty locations, hence a default
81 location is needed. */
4a678af8
JD
82 boundary_set (&@$.start, current_file, 1, 1);
83 boundary_set (&@$.end, current_file, 1, 1);
cd3684cf 84}
e9955c83 85
e9955c83
AD
86%union
87{
a7706735
AD
88 assoc assoc;
89 char *code;
90 char const *chars;
91 int integer;
92 named_ref *named_ref;
3d2cbc26
PE
93 symbol *symbol;
94 symbol_list *list;
3d2cbc26 95 uniqstr uniqstr;
58d7a1a1 96 unsigned char character;
e9955c83
AD
97};
98
f9a85a15 99/* Define the tokens together with their human representation. */
3d38c03a
AD
100%token GRAM_EOF 0 "end of file"
101%token STRING "string"
3d38c03a 102%token INT "integer"
e9955c83 103
9280d3ef
AD
104%token PERCENT_TOKEN "%token"
105%token PERCENT_NTERM "%nterm"
366eea36 106
9280d3ef 107%token PERCENT_TYPE "%type"
e9071366
AD
108%token PERCENT_DESTRUCTOR "%destructor"
109%token PERCENT_PRINTER "%printer"
366eea36 110
9280d3ef
AD
111%token PERCENT_LEFT "%left"
112%token PERCENT_RIGHT "%right"
113%token PERCENT_NONASSOC "%nonassoc"
d78f0ac9 114%token PERCENT_PRECEDENCE "%precedence"
04e60654 115
3d38c03a
AD
116%token PERCENT_PREC "%prec"
117%token PERCENT_DPREC "%dprec"
118%token PERCENT_MERGE "%merge"
e9955c83 119
e9955c83 120
ae7453f2
AD
121/*----------------------.
122| Global Declarations. |
123`----------------------*/
124
125%token
136a0f76 126 PERCENT_CODE "%code"
39a06c25 127 PERCENT_DEFAULT_PREC "%default-prec"
cd3684cf
AD
128 PERCENT_DEFINE "%define"
129 PERCENT_DEFINES "%defines"
31b850d2 130 PERCENT_ERROR_VERBOSE "%error-verbose"
cd3684cf 131 PERCENT_EXPECT "%expect"
a7706735 132 PERCENT_EXPECT_RR "%expect-rr"
ba061fa6 133 PERCENT_FLAG "%<flag>"
cd3684cf
AD
134 PERCENT_FILE_PREFIX "%file-prefix"
135 PERCENT_GLR_PARSER "%glr-parser"
e9071366 136 PERCENT_INITIAL_ACTION "%initial-action"
0e021770 137 PERCENT_LANGUAGE "%language"
cd3684cf 138 PERCENT_NAME_PREFIX "%name-prefix"
22fccf95 139 PERCENT_NO_DEFAULT_PREC "%no-default-prec"
cd3684cf
AD
140 PERCENT_NO_LINES "%no-lines"
141 PERCENT_NONDETERMINISTIC_PARSER
a7706735 142 "%nondeterministic-parser"
cd3684cf 143 PERCENT_OUTPUT "%output"
a7706735 144 PERCENT_REQUIRE "%require"
cd3684cf
AD
145 PERCENT_SKELETON "%skeleton"
146 PERCENT_START "%start"
147 PERCENT_TOKEN_TABLE "%token-table"
148 PERCENT_VERBOSE "%verbose"
149 PERCENT_YACC "%yacc"
ae7453f2 150;
e9955c83 151
58d7a1a1 152%token BRACED_CODE "{...}"
b143f404 153%token BRACKETED_ID "[identifier]"
58d7a1a1
AD
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 "<>"
58d7a1a1
AD
166
167%type <character> CHAR
33ad1a9c 168%printer { fputs (char_name ($$), stderr); } CHAR
3d38c03a 169
2ce4ed68 170/* braceless is not to be used for rule or symbol actions, as it
7c0c6181 171 calls code_props_plain_init. */
6afc30cc 172%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
eb095650 173%type <code> "{...}"
33ad1a9c 174%printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
eb095650 175 STRING
2ce4ed68 176%printer { fprintf (stderr, "{\n%s\n}", $$); }
6afc30cc 177 braceless content.opt "{...}" "%{...%}" EPILOGUE
58d7a1a1 178
b143f404
JD
179%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG variable
180%printer { fputs ($$, stderr); } <uniqstr>
181%printer { fprintf (stderr, "[%s]", $$); } BRACKETED_ID
58d7a1a1 182%printer { fprintf (stderr, "%s:", $$); } ID_COLON
ba061fa6
AD
183%printer { fprintf (stderr, "%%%s", $$); } PERCENT_FLAG
184%printer { fprintf (stderr, "<%s>", $$); } TAG
58d7a1a1 185
e9955c83 186%type <integer> INT
b143f404 187%printer { fprintf (stderr, "%d", $$); } <integer>
58d7a1a1 188
b143f404
JD
189%type <symbol> id id_colon string_as_id symbol symbol.prec
190%printer { fprintf (stderr, "%s", $$->tag); } <symbol>
58d7a1a1
AD
191%printer { fprintf (stderr, "%s:", $$->tag); } id_colon
192
2c569025 193%type <assoc> precedence_declarator
ab7f29f8 194%type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item
b143f404 195%type <named_ref> named_ref.opt
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}