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