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