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