]> git.saurik.com Git - bison.git/blame - src/parse-gram.y
Update ChangeLog.
[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"
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 }
0ce61575
AD
228| "%debug"
229 {
230 muscle_percent_define_insert ("debug", @$, "");
231 }
16dc6a9e 232| "%define" variable content.opt
7eb8a0bc 233 {
9611cfa2 234 muscle_percent_define_insert ($2, @2, $3);
7eb8a0bc 235 }
2ce4ed68 236| "%defines" { defines_flag = true; }
02975b9a
JD
237| "%defines" STRING
238 {
239 defines_flag = true;
240 spec_defines_file = xstrdup ($2);
241 }
b3a2272a
AD
242| "%error-verbose"
243 {
244 muscle_percent_define_insert ("error_verbose", @$, "");
245 }
2ce4ed68
AD
246| "%expect" INT { expected_sr_conflicts = $2; }
247| "%expect-rr" INT { expected_rr_conflicts = $2; }
02975b9a
JD
248| "%file-prefix" STRING { spec_file_prefix = $2; }
249| "%file-prefix" "=" STRING { spec_file_prefix = $3; } /* deprecated */
cd3684cf 250| "%glr-parser"
c66dfadd
PE
251 {
252 nondeterministic_parser = true;
253 glr_parser = true;
254 }
e9071366 255| "%initial-action" "{...}"
c66dfadd 256 {
7c0c6181
JD
257 code_props action;
258 code_props_symbol_action_init (&action, $2, @2);
259 code_props_translate_code (&action);
260 gram_scanner_last_string_free ();
261 muscle_code_grow ("initial_action", action.code, @2);
262 code_scanner_last_string_free ();
c66dfadd 263 }
51365192 264| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
2ce4ed68
AD
265| "%lex-param" "{...}" { add_param ("lex_param", $2, @2); }
266| "%locations" { locations_flag = true; }
02975b9a
JD
267| "%name-prefix" STRING { spec_name_prefix = $2; }
268| "%name-prefix" "=" STRING { spec_name_prefix = $3; } /* deprecated */
2ce4ed68
AD
269| "%no-lines" { no_lines_flag = true; }
270| "%nondeterministic-parser" { nondeterministic_parser = true; }
02975b9a
JD
271| "%output" STRING { spec_outfile = $2; }
272| "%output" "=" STRING { spec_outfile = $3; } /* deprecated */
2ce4ed68 273| "%parse-param" "{...}" { add_param ("parse_param", $2, @2); }
d9df47b6
JD
274| "%pure-parser"
275 {
276 /* %pure-parser is deprecated in favor of `%define api.pure', so use
277 `%define api.pure' in a backward-compatible manner here. First, don't
278 complain if %pure-parser is specified multiple times. */
279 if (!muscle_find_const ("percent_define(api.pure)"))
280 muscle_percent_define_insert ("api.pure", @1, "");
281 /* In all cases, use api.pure now so that the backend doesn't complain if
282 the skeleton ignores api.pure, but do warn now if there's a previous
283 conflicting definition from an actual %define. */
284 if (!muscle_percent_define_flag_if ("api.pure"))
285 muscle_percent_define_insert ("api.pure", @1, "");
286 }
2ce4ed68 287| "%require" STRING { version_check (&@2, $2); }
a7867f53
JD
288| "%skeleton" STRING
289 {
290 char const *skeleton_user = $2;
291 if (strchr (skeleton_user, '/'))
292 {
293 size_t dir_length = strlen (current_file);
294 char *skeleton_build;
295 while (dir_length && current_file[dir_length - 1] != '/')
296 --dir_length;
297 while (dir_length && current_file[dir_length - 1] == '/')
298 --dir_length;
299 skeleton_build =
300 xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
301 if (dir_length > 0)
302 {
303 strncpy (skeleton_build, current_file, dir_length);
304 skeleton_build[dir_length++] = '/';
305 }
306 strcpy (skeleton_build + dir_length, skeleton_user);
307 skeleton_user = uniqstr_new (skeleton_build);
308 free (skeleton_build);
309 }
51365192 310 skeleton_arg (skeleton_user, grammar_prio, @1);
a7867f53 311 }
2ce4ed68 312| "%token-table" { token_table_flag = true; }
ef1b4273 313| "%verbose" { report_flag |= report_states; }
2ce4ed68 314| "%yacc" { yacc_flag = true; }
cd3684cf 315| /*FIXME: Err? What is this horror doing here? */ ";"
e9955c83
AD
316;
317
2c569025
AD
318grammar_declaration:
319 precedence_declaration
320| symbol_declaration
e9955c83
AD
321| "%start" symbol
322 {
8efe435c 323 grammar_start_symbol_set ($2, @2);
e9955c83 324 }
3be03b13 325| "%destructor" "{...}" generic_symlist
9280d3ef 326 {
3d2cbc26 327 symbol_list *list;
e9071366 328 for (list = $3; list; list = list->next)
7c0c6181 329 symbol_list_destructor_set (list, $2, @2);
e9071366 330 symbol_list_free ($3);
9280d3ef 331 }
3be03b13 332| "%printer" "{...}" generic_symlist
366eea36 333 {
3d2cbc26 334 symbol_list *list;
e9071366 335 for (list = $3; list; list = list->next)
7c0c6181 336 symbol_list_printer_set (list, $2, @2);
e9071366 337 symbol_list_free ($3);
366eea36 338 }
22fccf95 339| "%default-prec"
39a06c25 340 {
22fccf95
PE
341 default_prec = true;
342 }
343| "%no-default-prec"
344 {
345 default_prec = false;
39a06c25 346 }
8e0a5e9e
JD
347| "%code" braceless
348 {
9611cfa2
JD
349 /* Do not invoke muscle_percent_code_grow here since it invokes
350 muscle_user_name_list_grow. */
592d0b1e 351 muscle_code_grow ("percent_code()", $2, @2);
8e0a5e9e
JD
352 code_scanner_last_string_free ();
353 }
16dc6a9e 354| "%code" ID braceless
8e0a5e9e 355 {
9611cfa2 356 muscle_percent_code_grow ($2, @2, $3, @3);
8e0a5e9e 357 code_scanner_last_string_free ();
8e0a5e9e 358 }
2c569025
AD
359;
360
58d7a1a1 361
3c262606
AD
362/*---------.
363| %union. |
364`---------*/
58d7a1a1
AD
365
366%token PERCENT_UNION "%union";
367
368union_name:
369 /* Nothing. */ {}
370| ID { muscle_code_grow ("union_name", $1, @1); }
371;
372
373grammar_declaration:
7ecec4dd 374 "%union" union_name braceless
58d7a1a1 375 {
ddc8ede1 376 union_seen = true;
7ecec4dd
JD
377 muscle_code_grow ("stype", $3, @3);
378 code_scanner_last_string_free ();
58d7a1a1
AD
379 }
380;
381
382
383
384
2c569025
AD
385symbol_declaration:
386 "%nterm" { current_class = nterm_sym; } symbol_defs.1
e9955c83
AD
387 {
388 current_class = unknown_sym;
389 current_type = NULL;
390 }
2c569025 391| "%token" { current_class = token_sym; } symbol_defs.1
e9955c83 392 {
2c569025 393 current_class = unknown_sym;
e9955c83
AD
394 current_type = NULL;
395 }
cb823b6f 396| "%type" TAG symbols.1
e9955c83 397 {
3d2cbc26 398 symbol_list *list;
4f82b42a 399 tag_seen = true;
1e0bab92 400 for (list = $3; list; list = list->next)
3be03b13 401 symbol_type_set (list->content.sym, $2, @2);
dafdc66f 402 symbol_list_free ($3);
e9955c83
AD
403 }
404;
405
2c569025 406precedence_declaration:
cb823b6f 407 precedence_declarator tag.opt symbols.prec
1e0bab92 408 {
3d2cbc26 409 symbol_list *list;
1e0bab92
AD
410 ++current_prec;
411 for (list = $3; list; list = list->next)
412 {
3be03b13
JD
413 symbol_type_set (list->content.sym, current_type, @2);
414 symbol_precedence_set (list->content.sym, current_prec, $1, @1);
1e0bab92 415 }
dafdc66f 416 symbol_list_free ($3);
1e0bab92
AD
417 current_type = NULL;
418 }
e9955c83
AD
419;
420
2c569025 421precedence_declarator:
d78f0ac9
AD
422 "%left" { $$ = left_assoc; }
423| "%right" { $$ = right_assoc; }
424| "%nonassoc" { $$ = non_assoc; }
425| "%precedence" { $$ = precedence_assoc; }
e9955c83
AD
426;
427
cb823b6f 428tag.opt:
87fbb0bf 429 /* Nothing. */ { current_type = NULL; }
cb823b6f 430| TAG { current_type = $1; tag_seen = true; }
e9955c83
AD
431;
432
ab7f29f8
JD
433/* Just like symbols.1 but accept INT for the sake of POSIX. */
434symbols.prec:
435 symbol.prec
436 { $$ = symbol_list_sym_new ($1, @1); }
437| symbols.prec symbol.prec
438 { $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
439;
440
441symbol.prec:
442 symbol { $$ = $1; }
443 | symbol INT { $$ = $1; symbol_user_token_number_set ($1, $2, @2); }
444 ;
445
3be03b13 446/* One or more symbols to be %typed. */
1e0bab92 447symbols.1:
3be03b13
JD
448 symbol
449 { $$ = symbol_list_sym_new ($1, @1); }
450| symbols.1 symbol
451 { $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
452;
453
454generic_symlist:
455 generic_symlist_item { $$ = $1; }
456| generic_symlist generic_symlist_item { $$ = symbol_list_prepend ($1, $2); }
457;
458
459generic_symlist_item:
cb823b6f
AD
460 symbol { $$ = symbol_list_sym_new ($1, @1); }
461| TAG { $$ = symbol_list_type_new ($1, @1); }
462| "<*>" { $$ = symbol_list_default_tagged_new (@1); }
463| "<>" { $$ = symbol_list_default_tagless_new (@1); }
e9955c83
AD
464;
465
e9955c83
AD
466/* One token definition. */
467symbol_def:
cb823b6f 468 TAG
e9955c83
AD
469 {
470 current_type = $1;
ddc8ede1 471 tag_seen = true;
e9955c83 472 }
58d7a1a1 473| id
e9955c83 474 {
073f9288 475 symbol_class_set ($1, current_class, @1, true);
1a31ed21 476 symbol_type_set ($1, current_type, @1);
e9955c83 477 }
58d7a1a1 478| id INT
e9955c83 479 {
073f9288 480 symbol_class_set ($1, current_class, @1, true);
1a31ed21 481 symbol_type_set ($1, current_type, @1);
e776192e 482 symbol_user_token_number_set ($1, $2, @2);
e9955c83 483 }
58d7a1a1 484| id string_as_id
e9955c83 485 {
073f9288 486 symbol_class_set ($1, current_class, @1, true);
1a31ed21 487 symbol_type_set ($1, current_type, @1);
a5d50994 488 symbol_make_alias ($1, $2, @$);
e9955c83 489 }
58d7a1a1 490| id INT string_as_id
e9955c83 491 {
073f9288 492 symbol_class_set ($1, current_class, @1, true);
1a31ed21 493 symbol_type_set ($1, current_type, @1);
e776192e 494 symbol_user_token_number_set ($1, $2, @2);
a5d50994 495 symbol_make_alias ($1, $3, @$);
e9955c83
AD
496 }
497;
498
499/* One or more symbol definitions. */
500symbol_defs.1:
501 symbol_def
e9955c83 502| symbol_defs.1 symbol_def
e9955c83
AD
503;
504
2c569025
AD
505
506 /*------------------------------------------.
507 | The grammar section: between the two %%. |
508 `------------------------------------------*/
509
510grammar:
1921f1d7
AD
511 rules_or_grammar_declaration
512| grammar rules_or_grammar_declaration
513;
514
515/* As a Bison extension, one can use the grammar declarations in the
b7295522 516 body of the grammar. */
1921f1d7 517rules_or_grammar_declaration:
e9955c83 518 rules
8d0a98bb 519| grammar_declaration ";"
b275314e
AD
520| error ";"
521 {
522 yyerrok;
523 }
e9955c83
AD
524;
525
526rules:
58d7a1a1 527 id_colon { current_lhs = $1; current_lhs_location = @1; } rhses.1
e9955c83
AD
528;
529
530rhses.1:
8f3596a6
AD
531 rhs { grammar_current_rule_end (@1); }
532| rhses.1 "|" rhs { grammar_current_rule_end (@3); }
8d0a98bb 533| rhses.1 ";"
e9955c83
AD
534;
535
536rhs:
537 /* Nothing. */
8f3596a6 538 { grammar_current_rule_begin (current_lhs, current_lhs_location); }
e9955c83 539| rhs symbol
8efe435c 540 { grammar_current_rule_symbol_append ($2, @2); }
e9071366 541| rhs "{...}"
381ecb06 542 { grammar_current_rule_action_append ($2, @2); }
e9955c83 543| rhs "%prec" symbol
e776192e 544 { grammar_current_rule_prec_set ($3, @3); }
676385e2
PH
545| rhs "%dprec" INT
546 { grammar_current_rule_dprec_set ($3, @3); }
cb823b6f 547| rhs "%merge" TAG
676385e2 548 { grammar_current_rule_merge_set ($3, @3); }
e9955c83
AD
549;
550
58d7a1a1 551
3c262606
AD
552/*---------------------------.
553| variable and content.opt. |
554`---------------------------*/
16dc6a9e
JD
555
556variable:
557 ID
3c262606
AD
558| STRING { $$ = uniqstr_new ($1); } /* deprecated and not M4-friendly */
559;
2ce4ed68 560
592d0b1e 561/* Some content or empty by default. */
2ce4ed68
AD
562content.opt:
563 /* Nothing. */
564 {
592d0b1e 565 $$ = "";
2ce4ed68 566 }
6afc30cc 567| STRING
2ce4ed68
AD
568;
569
570
3c262606
AD
571/*------------.
572| braceless. |
573`------------*/
6afc30cc 574
2ce4ed68
AD
575braceless:
576 "{...}"
577 {
7c0c6181 578 code_props plain_code;
2ce4ed68 579 $1[strlen ($1) - 1] = '\n';
7c0c6181
JD
580 code_props_plain_init (&plain_code, $1+1, @1);
581 code_props_translate_code (&plain_code);
582 gram_scanner_last_string_free ();
583 $$ = plain_code.code;
2ce4ed68
AD
584 }
585;
586
587
3c262606
AD
588/*--------------.
589| Identifiers. |
590`--------------*/
58d7a1a1 591
33ad1a9c
PE
592/* Identifiers are returned as uniqstr values by the scanner.
593 Depending on their use, we may need to make them genuine symbols. */
58d7a1a1
AD
594
595id:
33ad1a9c 596 ID
203b9274 597 { $$ = symbol_from_uniqstr ($1, @1); }
33ad1a9c
PE
598| CHAR
599 {
600 $$ = symbol_get (char_name ($1), @1);
601 symbol_class_set ($$, token_sym, @1, false);
602 symbol_user_token_number_set ($$, $1, @1);
603 }
58d7a1a1
AD
604;
605
606id_colon:
203b9274 607 ID_COLON { $$ = symbol_from_uniqstr ($1, @1); }
58d7a1a1
AD
608;
609
610
e9955c83 611symbol:
58d7a1a1
AD
612 id
613| string_as_id
e9955c83
AD
614;
615
ca407bdf 616/* A string used as an ID: quote it. */
e9955c83
AD
617string_as_id:
618 STRING
619 {
ca407bdf 620 $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
db89d400 621 symbol_class_set ($$, token_sym, @1, false);
e9955c83
AD
622 }
623;
624
e9955c83
AD
625epilogue.opt:
626 /* Nothing. */
e9955c83
AD
627| "%%" EPILOGUE
628 {
7c0c6181
JD
629 code_props plain_code;
630 code_props_plain_init (&plain_code, $2, @2);
631 code_props_translate_code (&plain_code);
e9071366 632 gram_scanner_last_string_free ();
7c0c6181
JD
633 muscle_code_grow ("epilogue", plain_code.code, @2);
634 code_scanner_last_string_free ();
e9955c83
AD
635 }
636;
637
e9955c83 638%%
b7295522
PE
639
640
641/* Return the location of the left-hand side of a rule whose
642 right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
643 the right-hand side, and return an empty location equal to the end
644 boundary of RHS[0] if the right-hand side is empty. */
645
646static YYLTYPE
647lloc_default (YYLTYPE const *rhs, int n)
648{
649 int i;
a737b216 650 YYLTYPE loc;
62cb8a99
PE
651
652 /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
653 The bug is fixed in 7.4.2m, but play it safe for now. */
654 loc.start = rhs[n].end;
655 loc.end = rhs[n].end;
b7295522 656
5320ca4d
PE
657 /* Ignore empty nonterminals the start of the the right-hand side.
658 Do not bother to ignore them at the end of the right-hand side,
659 since empty nonterminals have the same end as their predecessors. */
b7295522
PE
660 for (i = 1; i <= n; i++)
661 if (! equal_boundaries (rhs[i].start, rhs[i].end))
662 {
a737b216 663 loc.start = rhs[i].start;
b7295522
PE
664 break;
665 }
666
a737b216 667 return loc;
b7295522
PE
668}
669
670
671/* Add a lex-param or a parse-param (depending on TYPE) with
672 declaration DECL and location LOC. */
673
1773ceee 674static void
e9ce5688 675add_param (char const *type, char *decl, location loc)
1773ceee 676{
ead9e56e 677 static char const alphanum[26 + 26 + 1 + 10] =
1773ceee
PE
678 "abcdefghijklmnopqrstuvwxyz"
679 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ead9e56e
PE
680 "_"
681 "0123456789";
1773ceee 682 char const *name_start = NULL;
e9ce5688 683 char *p;
1773ceee 684
e503aa60
AD
685 /* Stop on last actual character. */
686 for (p = decl; p[1]; p++)
ead9e56e
PE
687 if ((p == decl
688 || ! memchr (alphanum, p[-1], sizeof alphanum))
689 && memchr (alphanum, p[0], sizeof alphanum - 10))
1773ceee
PE
690 name_start = p;
691
ead9e56e
PE
692 /* Strip the surrounding '{' and '}', and any blanks just inside
693 the braces. */
694 while (*--p == ' ' || *p == '\t')
695 continue;
e503aa60 696 p[1] = '\0';
ead9e56e
PE
697 while (*++decl == ' ' || *decl == '\t')
698 continue;
e9ce5688 699
1773ceee
PE
700 if (! name_start)
701 complain_at (loc, _("missing identifier in parameter declaration"));
702 else
703 {
704 char *name;
705 size_t name_len;
706
707 for (name_len = 1;
ead9e56e 708 memchr (alphanum, name_start[name_len], sizeof alphanum);
1773ceee
PE
709 name_len++)
710 continue;
711
712 name = xmalloc (name_len + 1);
713 memcpy (name, name_start, name_len);
714 name[name_len] = '\0';
715 muscle_pair_list_grow (type, decl, name);
716 free (name);
717 }
718
e9071366 719 gram_scanner_last_string_free ();
1773ceee
PE
720}
721
2ce4ed68 722
b50d2359
AD
723static void
724version_check (location const *loc, char const *version)
725{
726 if (strverscmp (version, PACKAGE_VERSION) > 0)
9b8a5ce0
AD
727 {
728 complain_at (*loc, "require bison %s, but have %s",
729 version, PACKAGE_VERSION);
730 exit (63);
731 }
b50d2359
AD
732}
733
1fec91df 734static void
3d2cbc26 735gram_error (location const *loc, char const *msg)
e9955c83 736{
ad8a3efc 737 complain_at (*loc, "%s", msg);
e9955c83 738}
e9ce5688
PE
739
740char const *
741token_name (int type)
742{
fc01665e 743 return yytname[YYTRANSLATE (type)];
e9ce5688 744}
33ad1a9c
PE
745
746static char const *
747char_name (char c)
748{
749 if (c == '\'')
750 return "'\\''";
751 else
752 {
753 char buf[4];
754 buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
755 return quotearg_style (escape_quoting_style, buf);
756 }
757}