Implement support for relative and absolute skeleton file names.

Discussed starting at
<http://lists.gnu.org/archive/html/bison-patches/2006-12/msg00071.html>.
* doc/bison.texinfo (Decl Summary): Document in %skeleton entry.
(Bison Options): Document in --skeleton entry.
* src/output.c (output_skeleton): Use strncpy rather than strcpy since
full_skeleton can't necessarily hold all of pkgdatadir.
If the specified skeleton file name contains a `/', don't prepend
pkgdatadir.
* src/parse-gram.y (prologue_declaration): If the specified skeleton
file name contains a `/', prepend the grammar file directory.
* tests/Makefile.am (TESTSUITE_AT): Add skeletons.at.
* skeletons.at: New file.
(relative skeleton file names): New test case.
(installed skeleton file names): New test case.
* tests/testsuite.at: Include skeletons.at.

* bootstrap: Update copyright to 2007.
This commit is contained in:
Joel E. Denny
2007-01-18 02:18:17 +00:00
parent 830c9b1847
commit a7867f53b3
9 changed files with 309 additions and 81 deletions

View File

@@ -1,3 +1,24 @@
2007-01-17 Joel E. Denny <jdenny@ces.clemson.edu>
Implement support for relative and absolute skeleton file names.
Discussed starting at
<http://lists.gnu.org/archive/html/bison-patches/2006-12/msg00071.html>.
* doc/bison.texinfo (Decl Summary): Document in %skeleton entry.
(Bison Options): Document in --skeleton entry.
* src/output.c (output_skeleton): Use strncpy rather than strcpy since
full_skeleton can't necessarily hold all of pkgdatadir.
If the specified skeleton file name contains a `/', don't prepend
pkgdatadir.
* src/parse-gram.y (prologue_declaration): If the specified skeleton
file name contains a `/', prepend the grammar file directory.
* tests/Makefile.am (TESTSUITE_AT): Add skeletons.at.
* skeletons.at: New file.
(relative skeleton file names): New test case.
(installed skeleton file names): New test case.
* tests/testsuite.at: Include skeletons.at.
* bootstrap: Update copyright to 2007.
2007-01-17 Paolo Bonzini <bonzini@gnu.org> 2007-01-17 Paolo Bonzini <bonzini@gnu.org>
* bootstrap: Remove occurrences of .#bootmp from the files. * bootstrap: Remove occurrences of .#bootmp from the files.

View File

@@ -2,7 +2,7 @@
# Bootstrap this package from CVS. # Bootstrap this package from CVS.
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@@ -4698,11 +4698,18 @@ Require a Version of Bison}.
@end deffn @end deffn
@deffn {Directive} %skeleton "@var{file}" @deffn {Directive} %skeleton "@var{file}"
Specify the skeleton to use. You probably don't need this option unless Specify the skeleton to use.
you are developing Bison; you should use @code{%language} if you want to
specify the skeleton for a different language, because it is clearer and You probably don't need this option unless you are developing Bison.
because it will always choose the correct skeleton for non-deterministic You should use @code{%language} if you want to specify the skeleton for a
or push parsers. different language, because it is clearer and because it will always choose the
correct skeleton for non-deterministic or push parsers.
If @var{file} does not contain a @code{/}, @var{file} is the name of a skeleton
file in the Bison installation directory.
If it does, @var{file} is an absolute file name or a file name relative to the
directory of the grammar file.
This is similar to how most shells resolve commands.
@end deffn @end deffn
@deffn {Directive} %token-table @deffn {Directive} %token-table
@@ -7319,14 +7326,20 @@ Pretend that @code{%no-parser} was specified. @xref{Decl Summary}.
@item -S @var{file} @item -S @var{file}
@itemx --skeleton=@var{file} @itemx --skeleton=@var{file}
Specify the skeleton to use, as if @code{%skeleton} was specified Specify the skeleton to use, similar to @code{%skeleton}
(@pxref{Decl Summary, , Bison Declaration Summary}). (@pxref{Decl Summary, , Bison Declaration Summary}).
You probably don't need this option unless you are developing Bison; You probably don't need this option unless you are developing Bison.
you should use @option{--language} if you want to specify the skeleton for a You should use @option{--language} if you want to specify the skeleton for a
different language, because it is clearer and because it will always different language, because it is clearer and because it will always
choose the correct skeleton for non-deterministic or push parsers. choose the correct skeleton for non-deterministic or push parsers.
If @var{file} does not contain a @code{/}, @var{file} is the name of a skeleton
file in the Bison installation directory.
If it does, @var{file} is an absolute file name or a file name relative to the
current working directory.
This is similar to how most shells resolve commands.
@item -k @item -k
@itemx --token-table @itemx --token-table
Pretend that @code{%token-table} was specified. @xref{Decl Summary}. Pretend that @code{%token-table} was specified. @xref{Decl Summary}.

View File

@@ -492,13 +492,16 @@ output_skeleton (void)
full_skeleton = xmalloc (pkgdatadirlen + 1 full_skeleton = xmalloc (pkgdatadirlen + 1
+ (skeleton_size < sizeof m4sugar + (skeleton_size < sizeof m4sugar
? sizeof m4sugar : skeleton_size)); ? sizeof m4sugar : skeleton_size));
strcpy (full_skeleton, pkgdatadir); strncpy (full_skeleton, pkgdatadir, pkgdatadirlen);
full_skeleton[pkgdatadirlen] = '/'; full_skeleton[pkgdatadirlen] = '/';
strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar); strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
full_m4sugar = xstrdup (full_skeleton); full_m4sugar = xstrdup (full_skeleton);
strcpy (full_skeleton + pkgdatadirlen + 1, m4bison); strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
full_m4bison = xstrdup (full_skeleton); full_m4bison = xstrdup (full_skeleton);
strcpy (full_skeleton + pkgdatadirlen + 1, skeleton); if (strchr (skeleton, '/'))
strcpy (full_skeleton, skeleton);
else
strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
xfclose (xfopen (full_m4sugar, "r")); xfclose (xfopen (full_m4sugar, "r"));
/* Create an m4 subprocess connected to us via two pipes. */ /* Create an m4 subprocess connected to us via two pipes. */

View File

@@ -678,14 +678,14 @@ static const yytype_uint16 yyrline[] =
0, 210, 210, 218, 220, 224, 225, 235, 236, 250, 0, 210, 210, 218, 220, 224, 225, 235, 236, 250,
251, 256, 257, 258, 259, 260, 261, 266, 275, 276, 251, 256, 257, 258, 259, 260, 261, 266, 275, 276,
277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
287, 288, 289, 290, 291, 292, 293, 297, 298, 299, 287, 288, 289, 313, 314, 315, 316, 320, 321, 322,
303, 310, 317, 321, 325, 330, 353, 354, 358, 370, 326, 333, 340, 344, 348, 353, 376, 377, 381, 393,
370, 375, 375, 380, 391, 406, 407, 408, 412, 413, 393, 398, 398, 403, 414, 429, 430, 431, 435, 436,
418, 420, 425, 426, 430, 431, 432, 433, 438, 443, 441, 443, 448, 449, 453, 454, 455, 456, 461, 466,
448, 454, 460, 471, 472, 481, 482, 488, 489, 490, 471, 477, 483, 494, 495, 504, 505, 511, 512, 513,
497, 497, 501, 502, 503, 508, 509, 511, 513, 515, 520, 520, 524, 525, 526, 531, 532, 534, 536, 538,
517, 527, 528, 534, 538, 547, 567, 569, 578, 583, 540, 550, 551, 557, 561, 570, 590, 592, 601, 606,
584, 589, 596, 598 607, 612, 619, 621
}; };
#endif #endif
@@ -2105,35 +2105,57 @@ yyreduce:
case 32: case 32:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 289 "parse-gram.y" #line 290 "parse-gram.y"
{ skeleton_arg ((yyvsp[(2) - (2)].chars), 1, &(yylsp[(1) - (2)])); } {
char const *skeleton_user = (yyvsp[(2) - (2)].chars);
if (strchr (skeleton_user, '/'))
{
size_t dir_length = strlen (current_file);
char *skeleton_build;
while (dir_length && current_file[dir_length - 1] != '/')
--dir_length;
while (dir_length && current_file[dir_length - 1] == '/')
--dir_length;
skeleton_build =
xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
if (dir_length > 0)
{
strncpy (skeleton_build, current_file, dir_length);
skeleton_build[dir_length++] = '/';
}
strcpy (skeleton_build + dir_length, skeleton_user);
skeleton_user = uniqstr_new (skeleton_build);
free (skeleton_build);
}
skeleton_arg (skeleton_user, 1, &(yylsp[(1) - (2)]));
}
break; break;
case 33: case 33:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 290 "parse-gram.y" #line 313 "parse-gram.y"
{ token_table_flag = true; } { token_table_flag = true; }
break; break;
case 34: case 34:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 291 "parse-gram.y" #line 314 "parse-gram.y"
{ report_flag = report_states; } { report_flag = report_states; }
break; break;
case 35: case 35:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 292 "parse-gram.y" #line 315 "parse-gram.y"
{ yacc_flag = true; } { yacc_flag = true; }
break; break;
case 39: case 39:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 300 "parse-gram.y" #line 323 "parse-gram.y"
{ {
grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]));
} }
@@ -2142,7 +2164,7 @@ yyreduce:
case 40: case 40:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 304 "parse-gram.y" #line 327 "parse-gram.y"
{ {
symbol_list *list; symbol_list *list;
for (list = (yyvsp[(3) - (3)].list); list; list = list->next) for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
@@ -2154,7 +2176,7 @@ yyreduce:
case 41: case 41:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 311 "parse-gram.y" #line 334 "parse-gram.y"
{ {
symbol_list *list; symbol_list *list;
for (list = (yyvsp[(3) - (3)].list); list; list = list->next) for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
@@ -2166,7 +2188,7 @@ yyreduce:
case 42: case 42:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 318 "parse-gram.y" #line 341 "parse-gram.y"
{ {
default_prec = true; default_prec = true;
} }
@@ -2175,7 +2197,7 @@ yyreduce:
case 43: case 43:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 322 "parse-gram.y" #line 345 "parse-gram.y"
{ {
default_prec = false; default_prec = false;
} }
@@ -2184,7 +2206,7 @@ yyreduce:
case 44: case 44:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 326 "parse-gram.y" #line 349 "parse-gram.y"
{ {
muscle_code_grow ("percent_code_unqualified", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); muscle_code_grow ("percent_code_unqualified", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
code_scanner_last_string_free (); code_scanner_last_string_free ();
@@ -2194,7 +2216,7 @@ yyreduce:
case 45: case 45:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 331 "parse-gram.y" #line 354 "parse-gram.y"
{ {
char const name_prefix[] = "percent_code("; char const name_prefix[] = "percent_code(";
size_t length = strlen ((yyvsp[(2) - (3)].uniqstr)); size_t length = strlen ((yyvsp[(2) - (3)].uniqstr));
@@ -2212,21 +2234,21 @@ yyreduce:
case 46: case 46:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 353 "parse-gram.y" #line 376 "parse-gram.y"
{} {}
break; break;
case 47: case 47:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 354 "parse-gram.y" #line 377 "parse-gram.y"
{ muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } { muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break; break;
case 48: case 48:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 359 "parse-gram.y" #line 382 "parse-gram.y"
{ {
union_seen = true; union_seen = true;
muscle_code_grow ("stype", (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); muscle_code_grow ("stype", (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)]));
@@ -2237,14 +2259,14 @@ yyreduce:
case 49: case 49:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 370 "parse-gram.y" #line 393 "parse-gram.y"
{ current_class = nterm_sym; } { current_class = nterm_sym; }
break; break;
case 50: case 50:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 371 "parse-gram.y" #line 394 "parse-gram.y"
{ {
current_class = unknown_sym; current_class = unknown_sym;
current_type = NULL; current_type = NULL;
@@ -2254,14 +2276,14 @@ yyreduce:
case 51: case 51:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 375 "parse-gram.y" #line 398 "parse-gram.y"
{ current_class = token_sym; } { current_class = token_sym; }
break; break;
case 52: case 52:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 376 "parse-gram.y" #line 399 "parse-gram.y"
{ {
current_class = unknown_sym; current_class = unknown_sym;
current_type = NULL; current_type = NULL;
@@ -2271,7 +2293,7 @@ yyreduce:
case 53: case 53:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 381 "parse-gram.y" #line 404 "parse-gram.y"
{ {
symbol_list *list; symbol_list *list;
tag_seen = true; tag_seen = true;
@@ -2284,7 +2306,7 @@ yyreduce:
case 54: case 54:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 392 "parse-gram.y" #line 415 "parse-gram.y"
{ {
symbol_list *list; symbol_list *list;
++current_prec; ++current_prec;
@@ -2301,98 +2323,98 @@ yyreduce:
case 55: case 55:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 406 "parse-gram.y" #line 429 "parse-gram.y"
{ (yyval.assoc) = left_assoc; } { (yyval.assoc) = left_assoc; }
break; break;
case 56: case 56:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 407 "parse-gram.y" #line 430 "parse-gram.y"
{ (yyval.assoc) = right_assoc; } { (yyval.assoc) = right_assoc; }
break; break;
case 57: case 57:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 408 "parse-gram.y" #line 431 "parse-gram.y"
{ (yyval.assoc) = non_assoc; } { (yyval.assoc) = non_assoc; }
break; break;
case 58: case 58:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 412 "parse-gram.y" #line 435 "parse-gram.y"
{ current_type = NULL; } { current_type = NULL; }
break; break;
case 59: case 59:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 413 "parse-gram.y" #line 436 "parse-gram.y"
{ current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; } { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; }
break; break;
case 60: case 60:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 419 "parse-gram.y" #line 442 "parse-gram.y"
{ (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
break; break;
case 61: case 61:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 421 "parse-gram.y" #line 444 "parse-gram.y"
{ (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); } { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); }
break; break;
case 62: case 62:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 425 "parse-gram.y" #line 448 "parse-gram.y"
{ (yyval.list) = (yyvsp[(1) - (1)].list); } { (yyval.list) = (yyvsp[(1) - (1)].list); }
break; break;
case 63: case 63:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 426 "parse-gram.y" #line 449 "parse-gram.y"
{ (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); } { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); }
break; break;
case 64: case 64:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 430 "parse-gram.y" #line 453 "parse-gram.y"
{ (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
break; break;
case 65: case 65:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 431 "parse-gram.y" #line 454 "parse-gram.y"
{ (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } { (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break; break;
case 66: case 66:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 432 "parse-gram.y" #line 455 "parse-gram.y"
{ (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); } { (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); }
break; break;
case 67: case 67:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 433 "parse-gram.y" #line 456 "parse-gram.y"
{ (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); } { (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); }
break; break;
case 68: case 68:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 439 "parse-gram.y" #line 462 "parse-gram.y"
{ {
current_type = (yyvsp[(1) - (1)].uniqstr); current_type = (yyvsp[(1) - (1)].uniqstr);
tag_seen = true; tag_seen = true;
@@ -2402,7 +2424,7 @@ yyreduce:
case 69: case 69:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 444 "parse-gram.y" #line 467 "parse-gram.y"
{ {
symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true); symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true);
symbol_type_set ((yyvsp[(1) - (1)].symbol), current_type, (yylsp[(1) - (1)])); symbol_type_set ((yyvsp[(1) - (1)].symbol), current_type, (yylsp[(1) - (1)]));
@@ -2412,7 +2434,7 @@ yyreduce:
case 70: case 70:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 449 "parse-gram.y" #line 472 "parse-gram.y"
{ {
symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true);
symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)])); symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)]));
@@ -2423,7 +2445,7 @@ yyreduce:
case 71: case 71:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 455 "parse-gram.y" #line 478 "parse-gram.y"
{ {
symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true);
symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)])); symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)]));
@@ -2434,7 +2456,7 @@ yyreduce:
case 72: case 72:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 461 "parse-gram.y" #line 484 "parse-gram.y"
{ {
symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true); symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true);
symbol_type_set ((yyvsp[(1) - (3)].symbol), current_type, (yylsp[(1) - (3)])); symbol_type_set ((yyvsp[(1) - (3)].symbol), current_type, (yylsp[(1) - (3)]));
@@ -2446,7 +2468,7 @@ yyreduce:
case 79: case 79:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 491 "parse-gram.y" #line 514 "parse-gram.y"
{ {
yyerrok; yyerrok;
} }
@@ -2455,77 +2477,77 @@ yyreduce:
case 80: case 80:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 497 "parse-gram.y" #line 520 "parse-gram.y"
{ current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); } { current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); }
break; break;
case 82: case 82:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 501 "parse-gram.y" #line 524 "parse-gram.y"
{ grammar_current_rule_end ((yylsp[(1) - (1)])); } { grammar_current_rule_end ((yylsp[(1) - (1)])); }
break; break;
case 83: case 83:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 502 "parse-gram.y" #line 525 "parse-gram.y"
{ grammar_current_rule_end ((yylsp[(3) - (3)])); } { grammar_current_rule_end ((yylsp[(3) - (3)])); }
break; break;
case 85: case 85:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 508 "parse-gram.y" #line 531 "parse-gram.y"
{ grammar_current_rule_begin (current_lhs, current_lhs_location); } { grammar_current_rule_begin (current_lhs, current_lhs_location); }
break; break;
case 86: case 86:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 510 "parse-gram.y" #line 533 "parse-gram.y"
{ grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); } { grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); }
break; break;
case 87: case 87:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 512 "parse-gram.y" #line 535 "parse-gram.y"
{ grammar_current_rule_action_append ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } { grammar_current_rule_action_append ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); }
break; break;
case 88: case 88:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 514 "parse-gram.y" #line 537 "parse-gram.y"
{ grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); } { grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); }
break; break;
case 89: case 89:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 516 "parse-gram.y" #line 539 "parse-gram.y"
{ grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); } { grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); }
break; break;
case 90: case 90:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 518 "parse-gram.y" #line 541 "parse-gram.y"
{ grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); } { grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); }
break; break;
case 92: case 92:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 528 "parse-gram.y" #line 551 "parse-gram.y"
{ (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); } { (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); }
break; break;
case 93: case 93:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 534 "parse-gram.y" #line 557 "parse-gram.y"
{ {
static char one[] = "1"; static char one[] = "1";
(yyval.chars) = one; (yyval.chars) = one;
@@ -2535,7 +2557,7 @@ yyreduce:
case 95: case 95:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 548 "parse-gram.y" #line 571 "parse-gram.y"
{ {
code_props plain_code; code_props plain_code;
(yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n'; (yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n';
@@ -2549,14 +2571,14 @@ yyreduce:
case 96: case 96:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 568 "parse-gram.y" #line 591 "parse-gram.y"
{ (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break; break;
case 97: case 97:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 570 "parse-gram.y" #line 593 "parse-gram.y"
{ {
(yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)])); (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)]));
symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
@@ -2567,14 +2589,14 @@ yyreduce:
case 98: case 98:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 578 "parse-gram.y" #line 601 "parse-gram.y"
{ (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break; break;
case 101: case 101:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 590 "parse-gram.y" #line 613 "parse-gram.y"
{ {
(yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)])); (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)]));
symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
@@ -2584,7 +2606,7 @@ yyreduce:
case 103: case 103:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 599 "parse-gram.y" #line 622 "parse-gram.y"
{ {
code_props plain_code; code_props plain_code;
code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
@@ -2598,7 +2620,7 @@ yyreduce:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 2602 "parse-gram.c" #line 2624 "parse-gram.c"
default: break; default: break;
} }
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2817,7 +2839,7 @@ yyreturn:
/* Line 1537 of yacc.c */ /* Line 1537 of yacc.c */
#line 609 "parse-gram.y" #line 632 "parse-gram.y"

View File

@@ -286,7 +286,30 @@ prologue_declaration:
| "%push-parser" { push_parser = true; pull_parser = false; } | "%push-parser" { push_parser = true; pull_parser = false; }
| "%push-pull-parser" { push_parser = true; pull_parser = true; } | "%push-pull-parser" { push_parser = true; pull_parser = true; }
| "%require" STRING { version_check (&@2, $2); } | "%require" STRING { version_check (&@2, $2); }
| "%skeleton" STRING { skeleton_arg ($2, 1, &@1); } | "%skeleton" STRING
{
char const *skeleton_user = $2;
if (strchr (skeleton_user, '/'))
{
size_t dir_length = strlen (current_file);
char *skeleton_build;
while (dir_length && current_file[dir_length - 1] != '/')
--dir_length;
while (dir_length && current_file[dir_length - 1] == '/')
--dir_length;
skeleton_build =
xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
if (dir_length > 0)
{
strncpy (skeleton_build, current_file, dir_length);
skeleton_build[dir_length++] = '/';
}
strcpy (skeleton_build + dir_length, skeleton_user);
skeleton_user = uniqstr_new (skeleton_build);
free (skeleton_build);
}
skeleton_arg (skeleton_user, 1, &@1);
}
| "%token-table" { token_table_flag = true; } | "%token-table" { token_table_flag = true; }
| "%verbose" { report_flag = report_states; } | "%verbose" { report_flag = report_states; }
| "%yacc" { yacc_flag = true; } | "%yacc" { yacc_flag = true; }

View File

@@ -47,7 +47,7 @@ TESTSUITE_AT = \
local.at \ local.at \
testsuite.at \ testsuite.at \
input.at \ input.at \
output.at sets.at reduce.at \ output.at sets.at reduce.at skeletons.at \
synclines.at headers.at actions.at conflicts.at \ synclines.at headers.at actions.at conflicts.at \
calc.at \ calc.at \
torture.at existing.at regression.at \ torture.at existing.at regression.at \

143
tests/skeletons.at Normal file
View File

@@ -0,0 +1,143 @@
# Checking skeleton support. -*- Autotest -*-
# Copyright (C) 2007 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
AT_BANNER([[Skeletons Support.]])
## ------------------------------ ##
## relative skeleton file names. ##
## ------------------------------ ##
AT_SETUP([[relative skeleton file names]])
AT_CHECK([[mkdir tmp]])
AT_DATA([[tmp/skel.c]],
[[m4@&t@_divert_push(0)d@&t@nl
@output(b4_parser_file_name@)d@&t@nl
b4_percent_define_get([[test]])
m4@&t@_divert_pop(0)
]])
AT_DATA([[skel.c]],
[[m4@&t@_divert_push(0)d@&t@nl
@output(b4_parser_file_name@)d@&t@nl
b4_percent_define_get([[test]]) -- Local
m4@&t@_divert_pop(0)
]])
AT_DATA([[tmp/input-gram.y]],
[[%skeleton "./skel.c"
%define test "Hello World"
%%
start: ;
]])
AT_DATA([[input-gram.y]],
[[%skeleton "./skel.c"
%define test "Hello World"
%%
start: ;
]])
AT_DATA([[tmp/input-cmd-line.y]],
[[%define test "Hello World"
%%
start: ;
]])
AT_CHECK([[bison tmp/input-gram.y]])
AT_CHECK([[cat input-gram.tab.c]], [[0]],
[[Hello World
]])
AT_CHECK([[bison input-gram.y]])
AT_CHECK([[cat input-gram.tab.c]], [[0]],
[[Hello World -- Local
]])
AT_CHECK([[bison --skeleton=tmp/skel.c tmp/input-cmd-line.y]])
AT_CHECK([[cat input-cmd-line.tab.c]], [[0]],
[[Hello World
]])
AT_CLEANUP
## ------------------------------ ##
## installed skeleton file name. ##
## ------------------------------ ##
AT_SETUP([[installed skeleton file name]])
m4_pushdef([AT_GRAM],
[[%{
#include <stdio.h>
void yyerror (char const *msg);
int yylex (void);
%}
%error-verbose
%token 'a'
%%
start: ;
%%
void
yyerror (char const *msg)
{
fprintf (stderr, "%s\n", msg);
}
int
yylex (void)
{
return 'a';
}
int
main (void)
{
return yyparse ();
}
]])
AT_DATA([[input-cmd-line.y]],
[AT_GRAM])
AT_DATA([[input-gram.y]],
[[%skeleton "yacc.c"]
AT_GRAM])
AT_CHECK([[bison --skeleton=yacc.c -o input-cmd-line.c input-cmd-line.y]])
AT_COMPILE([[input-cmd-line]])
AT_PARSER_CHECK([[./input-cmd-line]], [[1]], [],
[[syntax error, unexpected 'a', expecting $end
]])
AT_CHECK([[bison -o input-gram.c input-gram.y]])
AT_COMPILE([[input-gram]])
AT_PARSER_CHECK([[./input-gram]], [[1]], [],
[[syntax error, unexpected 'a', expecting $end
]])
m4_popdef([AT_GRAM])
AT_CLEANUP

View File

@@ -1,6 +1,6 @@
# Test suite for GNU Bison. -*- Autotest -*- # Test suite for GNU Bison. -*- Autotest -*-
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 Free Software # Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007 Free Software
# Foundation, Inc. # Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,9 @@ m4_include([input.at])
# Testing output file names. # Testing output file names.
m4_include([output.at]) m4_include([output.at])
# Testing skeleton support.
m4_include([skeletons.at])
# Testing the part of the engine that computes FOLLOW etc. # Testing the part of the engine that computes FOLLOW etc.
m4_include([sets.at]) m4_include([sets.at])