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