Merge branch 'branch-2.6' into maint

* origin/branch-2.6: (24 commits)
  tests: calc: modernize the use of locations
  tests: remove useless location initializations
  lalr1.cc: always initialize yylval.
  tests: check that C and C++ objects can be linked together.
  yacc.c: also disable -Wuninitialized.
  glr.cc, yacc.c: initialize yylloc properly
  yacc.c, glr.c: a better YY_LOCATION_PRINT
  yacc.c: simplify initialization
  doc: formatting changes
  c++: fix position operator signatures
  tests: remove useless location initialization.
  tests: fix locations in C
  tests: handle %parse-param in the generated yyerror
  tests: simplifications
  grammars: fix display of nul character in error message
  tests: sort
  tests: cosmetic changes
  comment changes
  autoconf: update
  gnulib: update
  ...

Conflicts:
	NEWS
	gnulib
	tests/named-refs.at
	tests/regression.at
This commit is contained in:
Akim Demaille
2012-11-06 18:00:33 +01:00
20 changed files with 360 additions and 234 deletions

19
NEWS
View File

@@ -51,6 +51,25 @@ GNU Bison NEWS
The reductions are now explicitly represented as transitions to other The reductions are now explicitly represented as transitions to other
diamond shaped nodes. diamond shaped nodes.
* Noteworthy changes in release ?.? (????-??-??) [?]
We consider compiler warnings about Bison generated parsers to be bugs.
Rather than working around them in your own project, please consider
reporting them to us.
** Bug fixes
Warnings about uninitialized yylval and/or yylloc for push parsers with a
pure interface have been fixed for GCC 4.0 up to 4.8, and Clang 2.9 to
3.2.
Other issues in the test suite have been addressed.
Nul characters are correctly displayed in error messages.
When possible, yylloc is correctly initialized before calling yylex. It
is no longer necessary to initialize it in the %initial-action.
* Noteworthy changes in release 2.6.4 (2012-10-23) [stable] * Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
Bison 2.6.3's --version was incorrect. This release fixes this issue. Bison 2.6.3's --version was incorrect. This release fixes this issue.

2
THANKS
View File

@@ -64,6 +64,7 @@ Laurent Mascherpa laurent.mascherpa@epita.fr
Lie Yan lie.yan@kaust.edu.sa Lie Yan lie.yan@kaust.edu.sa
Magnus Fromreide magfr@lysator.liu.se Magnus Fromreide magfr@lysator.liu.se
Marc Autret autret_m@epita.fr Marc Autret autret_m@epita.fr
Marc Mendiola mmendiol@usc.edu
Martin Jacobs martin.jacobs@arcor.de Martin Jacobs martin.jacobs@arcor.de
Martin Mokrejs mmokrejs@natur.cuni.cz Martin Mokrejs mmokrejs@natur.cuni.cz
Martin Nylin martin.nylin@linuxmail.org Martin Nylin martin.nylin@linuxmail.org
@@ -88,6 +89,7 @@ Paul Hilfinger Hilfinger@CS.Berkeley.EDU
Per Allansson per@appgate.com Per Allansson per@appgate.com
Peter Fales psfales@lucent.com Peter Fales psfales@lucent.com
Peter Hamorsky hamo@upjs.sk Peter Hamorsky hamo@upjs.sk
Peter Simons simons@cryp.to
Piotr Gackiewicz gacek@intertel.com.pl Piotr Gackiewicz gacek@intertel.com.pl
Quoc Peyrot chojin@lrde.epita.fr Quoc Peyrot chojin@lrde.epita.fr
R Blake blakers@mac.com R Blake blakers@mac.com

View File

@@ -643,3 +643,46 @@ m4_define([b4_yylloc_default_define],
while (YYID (0)) while (YYID (0))
#endif #endif
]]) ]])
# b4_yy_location_print_define
# ---------------------------
# Define YY_LOCATION_PRINT.
m4_define([b4_yy_location_print_define],
[b4_locations_if([[
/* YY_LOCATION_PRINT -- Print the location on the stream.
This macro was not mandated originally: define only if we know
we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
do { \
fprintf (File, "%d.%d", (Loc).first_line, (Loc).first_column); \
if ((Loc).first_line < (Loc).last_line) \
fprintf (File, "-%d.%d", (Loc).last_line, (Loc).last_column - 1); \
else if ((Loc).first_column < (Loc).last_column - 1) \
fprintf (File, "-%d", (Loc).last_column - 1); \
} while (0)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
#endif]],
[[/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif]])
])
# b4_yyloc_default
# ----------------
# Expand to a possible default value for yylloc.
m4_define([b4_yyloc_default],
[[
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
= { ]m4_join([, ],
m4_defn([b4_location_initial_line]),
m4_defn([b4_location_initial_column]),
m4_defn([b4_location_initial_line]),
m4_defn([b4_location_initial_column]))[ }
# endif
]])

View File

@@ -223,11 +223,11 @@ b4_percent_code_get([[top]])[
#endif #endif
/* Default (constant) value used for initialization for null /* Default (constant) value used for initialization for null
right-hand sides. Unlike the standard yacc.c template, right-hand sides. Unlike the standard yacc.c template, here we set
here we set the default value of $$ to a zeroed-out value. the default value of $$ to a zeroed-out value. Since the default
Since the default value is undefined, this behavior is value is undefined, this behavior is technically correct. */
technically correct. */ static YYSTYPE yyval_default;]b4_locations_if([[
static YYSTYPE yyval_default; static YYLTYPE yyloc_default][]b4_yyloc_default;])[
/* Copy the second part of user declarations. */ /* Copy the second part of user declarations. */
]b4_user_post_prologue ]b4_user_post_prologue
@@ -475,28 +475,10 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] =
#define YYTERROR 1 #define YYTERROR 1
]b4_locations_if([[ ]b4_locations_if([[
#ifndef YYLLOC_DEFAULT
]b4_yylloc_default_define[ ]b4_yylloc_default_define[
# define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc) # define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
]])[
/* YY_LOCATION_PRINT -- Print the location on the stream. ]b4_yy_location_print_define[
This macro was not mandated originally: define only if we know
we won't break user code: when these are the locations we know. */
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
(Loc).first_line, (Loc).first_column, \
(Loc).last_line, (Loc).last_column)
#endif
]],[
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) ((void) 0)
#endif
])[
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
/* YYLEX -- calling `yylex' with the right arguments. */ /* YYLEX -- calling `yylex' with the right arguments. */
#define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[ #define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
@@ -2295,14 +2277,9 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
YYDPRINTF ((stderr, "Starting parse\n")); YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; yychar = YYEMPTY;
yylval = yyval_default; yylval = yyval_default;]b4_locations_if([
]b4_locations_if([ yylloc = yyloc_default;])[
#if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL ]m4_ifdef([b4_initial_action], [
yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[;
yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
#endif
])
m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */ /* User initialization code. */
b4_user_initial_action b4_user_initial_action

View File

@@ -87,12 +87,17 @@ m4_define([b4_yy_symbol_print_generate],
]b4_parse_param_use[]dnl ]b4_parse_param_use[]dnl
[ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[); [ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
} }
]]) ]])[
# Hijack the initial action to initialize the locations.
]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
[m4_define([b4_initial_action],
[yylloc.initialize ();]m4_ifdef([b4_initial_action], [
m4_defn([b4_initial_action])]))])])[
# Hijack the post prologue to insert early definition of YYLLOC_DEFAULT # Hijack the post prologue to insert early definition of YYLLOC_DEFAULT
# and declaration of yyerror. # and declaration of yyerror.
m4_append([b4_post_prologue], ]m4_append([b4_post_prologue],
[b4_syncline([@oline@], [@ofile@])[ [b4_syncline([@oline@], [@ofile@])[
]b4_yylloc_default_define[ ]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc) #define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)

View File

@@ -512,17 +512,18 @@ do { \
int yychar = yyempty_; int yychar = yyempty_;
int yytoken = 0; int yytoken = 0;
/* State. */ // State.
int yyn; int yyn;
int yylen = 0; int yylen = 0;
int yystate = 0; int yystate = 0;
/* Error handling. */ // Error handling.
int yynerrs_ = 0; int yynerrs_ = 0;
int yyerrstatus_ = 0; int yyerrstatus_ = 0;
/// Semantic value of the lookahead. /// Semantic value of the lookahead.
semantic_type yylval; static semantic_type yyval_default;
semantic_type yylval = yyval_default;
/// Location of the lookahead. /// Location of the lookahead.
location_type yylloc; location_type yylloc;
/// The locations where the error started and ended. /// The locations where the error started and ended.

View File

@@ -87,7 +87,7 @@ b4_copyright([Positions for Bison parsers in C++],
}; };
/// Add and assign a position. /// Add and assign a position.
inline const position& inline position&
operator+= (position& res, const int width) operator+= (position& res, const int width)
{ {
res.columns (width); res.columns (width);
@@ -103,7 +103,7 @@ b4_copyright([Positions for Bison parsers in C++],
} }
/// Add and assign a position. /// Add and assign a position.
inline const position& inline position&
operator-= (position& res, const int width) operator-= (position& res, const int width)
{ {
return res += -width; return res += -width;

View File

@@ -171,10 +171,11 @@ m4_define([b4_declare_scanner_communication_variables], [[
int yychar; int yychar;
]b4_pure_if([[ ]b4_pure_if([[
#if defined __GNUC__ && (4 < __GNUC__ + (6 <= __GNUC_MINOR__)) #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */ /* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ # define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop") _Pragma ("GCC diagnostic pop")
@@ -182,21 +183,22 @@ int yychar;
/* Default value used for initialization, for pacifying older GCCs /* Default value used for initialization, for pacifying older GCCs
or non-GCC compilers. */ or non-GCC compilers. */
static YYSTYPE yyval_default; static YYSTYPE yyval_default;
# define YYLVAL_INITIALIZE() (yylval = yyval_default) # define YY_INITIAL_VALUE(Value) = Value
#endif]])[ #endif]])[
#ifndef YYLVAL_INITIALIZE
# define YYLVAL_INITIALIZE()
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END # define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif #endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
/* The semantic value of the lookahead symbol. */ /* The semantic value of the lookahead symbol. */
YYSTYPE yylval;]b4_locations_if([[ YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
/* Location data for the lookahead symbol. */ /* Location data for the lookahead symbol. */
YYLTYPE yylloc;]])b4_pure_if([], [[ YYLTYPE yylloc][]b4_yyloc_default[;
]])b4_pure_if([], [[
/* Number of syntax errors so far. */ /* Number of syntax errors so far. */
int yynerrs;]])]) int yynerrs;]])])
@@ -264,7 +266,7 @@ typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
[[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([, [[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([,
[[[int pushed_char]], [[pushed_char]]], [[[int pushed_char]], [[pushed_char]]],
[[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([, [[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([,
[[b4_api_PREFIX[LTYPE const *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [, [[b4_api_PREFIX[LTYPE *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param])) b4_parse_param]))
b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]], b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]],
[[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [, [[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
@@ -765,33 +767,15 @@ do \
} \ } \
while (YYID (0)) while (YYID (0))
/* Error token number */
#define YYTERROR 1 #define YYTERROR 1
#define YYERRCODE 256 #define YYERRCODE 256
]b4_locations_if([[ ]b4_locations_if([[
]b4_yylloc_default_define[ ]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K]) #define YYRHSLOC(Rhs, K) ((Rhs)[K])
]])[
/* YY_LOCATION_PRINT -- Print the location on the stream. ]b4_yy_location_print_define[
This macro was not mandated originally: define only if we know
we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
(Loc).first_line, (Loc).first_column, \
(Loc).last_line, (Loc).last_column)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
#endif]],
[[/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif]])[
/* YYLEX -- calling `yylex' with the right arguments. */ /* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM #ifdef YYLEX_PARAM
@@ -1426,7 +1410,7 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
yypstate *yyps_local;]b4_pure_if([[ yypstate *yyps_local;]b4_pure_if([[
int yychar; int yychar;
YYSTYPE yylval;]b4_locations_if([[ YYSTYPE yylval;]b4_locations_if([[
YYLTYPE yylloc;]])])[ YYLTYPE yylloc][]b4_yyloc_default[;]])])[
if (yyps) if (yyps)
yyps_local = yyps; yyps_local = yyps;
else else
@@ -1506,7 +1490,7 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
[[[yypstate *yyps]], [[yyps]]]b4_pure_if([, [[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
[[[int yypushed_char]], [[yypushed_char]]], [[[int yypushed_char]], [[yypushed_char]]],
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([, [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
[[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [, [[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param]))], [[ b4_parse_param]))], [[
@@ -1557,9 +1541,9 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
goto yyread_pushed_token; goto yyread_pushed_token;
}]])[ }]])[
yyss = yyssa; yyssp = yyss = yyssa;
yyvs = yyvsa;]b4_locations_if([[ yyvsp = yyvs = yyvsa;]b4_locations_if([[
yyls = yylsa;]])[ yylsp = yyls = yylsa;]])[
yystacksize = YYINITDEPTH;]b4_lac_if([[ yystacksize = YYINITDEPTH;]b4_lac_if([[
yyes = yyesa; yyes = yyesa;
@@ -1573,31 +1557,17 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
yyerrstatus = 0; yyerrstatus = 0;
yynerrs = 0; yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */ yychar = YYEMPTY; /* Cause a token to be read. */
]m4_ifdef([b4_initial_action], [
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
yyssp = yyss;
yyvsp = yyvs;]b4_locations_if([[
yylsp = yyls;]])[
YYLVAL_INITIALIZE ();]b4_locations_if([[
#if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
/* Initialize the default location before parsing starts. */
yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[;
yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
#endif]])
m4_ifdef([b4_initial_action],[
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [],
[m4_define([b4_at_dollar_used])yylloc])dnl [m4_define([b4_at_dollar_used])dnl
b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
/* User initialization code. */ /* User initialization code. */
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef[]dnl b4_dollar_popdef[]dnl
m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval; m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval;
]])dnl
m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc;
]])])dnl ]])])dnl
b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])[;
]])dnl
[ goto yysetstate; [ goto yysetstate;
/*------------------------------------------------------------. /*------------------------------------------------------------.

2
gnulib

Submodule gnulib updated: 0e6a848c8c...daf7f8c022

View File

@@ -291,7 +291,7 @@ splice (\\[ \f\t\v]*\n)*
} }
. { . {
complain_at (*loc, _("invalid character: %s"), quote (yytext)); complain_at (*loc, _("invalid character: %s"), quote_mem (yytext, yyleng));
} }
<<EOF>> { <<EOF>> {
@@ -375,7 +375,7 @@ splice (\\[ \f\t\v]*\n)*
} }
. { . {
complain_at (*loc, _("invalid character in bracketed name: %s"), complain_at (*loc, _("invalid character in bracketed name: %s"),
quote (yytext)); quote_mem (yytext, yyleng));
} }
<<EOF>> { <<EOF>> {
BEGIN bracketed_id_context_state; BEGIN bracketed_id_context_state;

View File

@@ -69,6 +69,76 @@ AT_PARSER_CHECK([./input], 0,
AT_CLEANUP AT_CLEANUP
## ------------------ ##
## Initial location. ##
## ------------------ ##
# AT_TEST(SKELETON-NAME, DIRECTIVES)
# ----------------------------------
# Check the the initial location is correct.
m4_pushdef([AT_TEST],
[AT_SETUP([Initial location: $1 $2])
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2 %parse-param { int x }])
AT_DATA_GRAMMAR([[input.y]],
[[%defines /* FIXME: Required by lalr1.cc in Bison 2.6. */
%locations
%debug
%skeleton "$1"
$2
%parse-param { int x } // Useless, but used to force yyerror purity.
%code
{
# include <stdio.h>
# include <stdlib.h> // getenv
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%%
exp: { ]AT_SKEL_CC_IF([[std::cerr << @$ << std::endl]],
[[YY_LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_PROTOTYPE[
{]AT_PURE_IF([
YYUSE(lvalp);
YYUSE(llocp);], [AT_SKEL_CC_IF([
YYUSE(lvalp);
YYUSE(llocp);])])[
return 'x';
}
int
main (void)
{]AT_SKEL_CC_IF([[
yy::parser p (0);
p.set_debug_level (!!getenv("YYDEBUG"));
return p.parse ();]], [[
yydebug = !!getenv("YYDEBUG");
return !!yyparse (0);]])[
}
]])
AT_FULL_COMPILE([input])
AT_PARSER_CHECK([./input], 1, [],
[[1.1
1.1: syntax error
]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
## FIXME: test Java, and iterate over skeletons.
AT_TEST([yacc.c])
AT_TEST([yacc.c], [%define api.pure])
AT_TEST([yacc.c], [%define api.push-pull both])
AT_TEST([yacc.c], [%define api.push-pull both %define api.pure])
AT_TEST([glr.c])
AT_TEST([lalr1.cc])
AT_TEST([glr.cc])
m4_popdef([AT_TEST])
@@ -159,8 +229,7 @@ main (void)
} }
]]) ]])
AT_BISON_CHECK([[-o input.c input.y]]) AT_FULL_COMPILE([input])
AT_COMPILE([[input]])
AT_PARSER_CHECK([[./input]], [[0]], AT_PARSER_CHECK([[./input]], [[0]],
[[6 [[6
]]) ]])
@@ -305,7 +374,7 @@ line:
$$ = -1; $$ = -1;
V(line, $$, @$, ": "); V(line, $$, @$, ": ");
V('(', $1, @1, " "); V('(', $1, @1, " ");
fprintf (stderr, "error (@%d-%d) ", RANGE(@2)); fprintf (stderr, "error (@%d-%d) ", RANGE (@2));
V(')', $3, @3, "\n"); V(')', $3, @3, "\n");
} }
; ;
@@ -557,7 +626,7 @@ AT_BISON_OPTION_POPDEFS
# AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG]) # AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
m4_define([AT_CHECK_PRINTER_AND_DESTRUCTOR], m4_define([AT_CHECK_PRINTER_AND_DESTRUCTOR],
[AT_SETUP([Printers and Destructors $2: $1]) [AT_SETUP([Printers and Destructors$2]m4_ifval([$1], [[: $1]]))
$3 $3
_AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4], _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
@@ -572,13 +641,13 @@ AT_CLEANUP
AT_CHECK_PRINTER_AND_DESTRUCTOR([]) AT_CHECK_PRINTER_AND_DESTRUCTOR([])
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union]) AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"]) AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union]) AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser]) AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union]) AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
@@ -595,10 +664,6 @@ AT_DATA_GRAMMAR([[input.y]],
[[%error-verbose [[%error-verbose
%debug %debug
%locations %locations
%initial-action {
@$.first_line = @$.last_line = 1;
@$.first_column = @$.last_column = 1;
}
%{ %{
# include <stdio.h> # include <stdio.h>
@@ -656,29 +721,29 @@ AT_PARSER_CHECK([./input], 1,
]], ]],
[[Starting parse [[Starting parse
Entering state 0 Entering state 0
Reading a token: Next token is token 'a' (1.1-1.1: <> printer for 'a' @ 1) Reading a token: Next token is token 'a' (1.1: <> printer for 'a' @ 1)
Shifting token 'a' (1.1-1.1: <> printer for 'a' @ 1) Shifting token 'a' (1.1: <> printer for 'a' @ 1)
Entering state 1 Entering state 1
Reading a token: Next token is token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2) Reading a token: Next token is token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
Shifting token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2) Shifting token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
Entering state 3 Entering state 3
Reading a token: Next token is token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3) Reading a token: Next token is token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
Shifting token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3) Shifting token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
Entering state 5 Entering state 5
Reading a token: Next token is token 'd' (1.4-1.4: <> printer for 'd' @ 4) Reading a token: Next token is token 'd' (1.4: <> printer for 'd' @ 4)
Shifting token 'd' (1.4-1.4: <> printer for 'd' @ 4) Shifting token 'd' (1.4: <> printer for 'd' @ 4)
Entering state 6 Entering state 6
Reading a token: Now at end of input. Reading a token: Now at end of input.
1.5-4: syntax error, unexpected $end, expecting 'e' 1.5: syntax error, unexpected $end, expecting 'e'
Error: popping token 'd' (1.4-1.4: <> printer for 'd' @ 4) Error: popping token 'd' (1.4: <> printer for 'd' @ 4)
Stack now 0 1 3 5 Stack now 0 1 3 5
Error: popping token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3) Error: popping token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
Stack now 0 1 3 Stack now 0 1 3
Error: popping token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2) Error: popping token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
Stack now 0 1 Stack now 0 1
Error: popping token 'a' (1.1-1.1: <> printer for 'a' @ 1) Error: popping token 'a' (1.1: <> printer for 'a' @ 1)
Stack now 0 Stack now 0
Cleanup: discarding lookahead token $end (1.5-1.5: ) Cleanup: discarding lookahead token $end (1.5: )
Stack now 0 Stack now 0
]]) ]])
@@ -829,10 +894,6 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]],
[[%error-verbose [[%error-verbose
%debug %debug
%locations %locations
%initial-action {
@$.first_line = @$.last_line = 1;
@$.first_column = @$.last_column = 1;
}
%{ %{
# include <stdio.h> # include <stdio.h>
@@ -899,16 +960,16 @@ AT_PARSER_CHECK([./input$1], 0,
]], ]],
[[Starting parse [[Starting parse
Entering state 0 Entering state 0
Reducing stack by rule 1 (line 46): Reducing stack by rule 1 (line 42):
-> $$ = nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1) -> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
Stack now 0 Stack now 0
Entering state 1 Entering state 1
Reading a token: Now at end of input. Reading a token: Now at end of input.
Shifting token END (1.1-1.1: <]]kind[[> for 'E' @ 1) Shifting token END (1.1: <]]kind[[> for 'E' @ 1)
Entering state 2 Entering state 2
Stack now 0 1 2 Stack now 0 1 2
Cleanup: popping token END (1.1-1.1: <]]kind[[> for 'E' @ 1) Cleanup: popping token END (1.1: <]]kind[[> for 'E' @ 1)
Cleanup: popping nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1) Cleanup: popping nterm start (1.1: <]]kind[[> for 'S' @ 1)
]]) ]])
m4_popdef([kind]) m4_popdef([kind])
@@ -1237,7 +1298,7 @@ AT_CHECK_ACTION_LOCATIONS([[%printer]])
# Check that we can used qualified $$ (v.g., $<type>$) not only in # Check that we can used qualified $$ (v.g., $<type>$) not only in
# rule actions, but also where $$ is valid: %printer and %destructor. # rule actions, but also where $$ is valid: %printer and %destructor.
# #
# FIXME: Not actually checking %desctructor, but it's the same code as # FIXME: Not actually checking %destructor, but it's the same code as
# %printer... # %printer...
# #
# To do that, use a semantic value that has two fields (sem_type), # To do that, use a semantic value that has two fields (sem_type),
@@ -1295,17 +1356,6 @@ AT_DATA_GRAMMAR([[input.y]],
%printer { report (yyo, $<ival>$, $$ ); } <fval>; %printer { report (yyo, $<ival>$, $$ ); } <fval>;
%printer { report (yyo, $<ival>$, $<fval>$); } <>; %printer { report (yyo, $<ival>$, $<fval>$); } <>;
]AT_SKEL_CC_IF([[
/* The lalr1.cc skeleton, for backward compatibility, defines
a constructor for position that initializes the filename. The
glr.cc skeleton does not (and in fact cannot: location/position
are stored in a union, from which objects with constructors are
excluded in C++). */
%initial-action {
@$.initialize ();
}
]])[
%initial-action %initial-action
{ {
$<ival>$ = 42; $<ival>$ = 42;

View File

@@ -178,18 +178,7 @@ read_signed_integer (]AT_YYLEX_FORMALS[)
]AT_YYLEX_PROTOTYPE[ ]AT_YYLEX_PROTOTYPE[
{ {
static int init = 1;
int c; int c;
if (init)
{
init = 0;
]AT_LOCATION_IF([
AT_LOC_LAST_COLUMN = 1;
AT_LOC_LAST_LINE = 1;
])[
}
/* Skip current token, then white spaces. */ /* Skip current token, then white spaces. */
do do
{ {
@@ -261,6 +250,8 @@ AT_SKEL_CC_IF(
{ {
semantic_value ival; semantic_value ival;
}; };
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
[[fprintf (yyoutput, "%d", $$)]])[; } <ival>;
%code provides %code provides
{ {
@@ -280,24 +271,16 @@ AT_SKEL_CC_IF(
FILE *input; FILE *input;
static int power (int base, int exponent); static int power (int base, int exponent);
]AT_SKEL_CC_IF(, ]AT_YYERROR_DECLARE[
[static void yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
AT_PARAM_IF([semantic_value *result, int *count, ])
const char *s
);])[
]AT_YYLEX_DECLARE_EXTERN[ ]AT_YYLEX_DECLARE_EXTERN[
} }
]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([], [[ ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([[
/* The lalr1.cc skeleton, for backward compatibility, defines %initial-action
a constructor for position that initializes the filename. The {
glr.cc skeleton does not (and in fact cannot: location/position @$.first.l = @$.first.c = 1;
are stored in a union, from which objects with constructors are @$.last = @$.first;
excluded in C++). */ }]])])[
%initial-action {
@$.initialize ();
}
]])])[
/* Bison Declarations */ /* Bison Declarations */
%token CALC_EOF 0 "end of input" %token CALC_EOF 0 "end of input"
@@ -365,27 +348,8 @@ power (int base, int exponent)
o << '-' << s.last.c - 1; o << '-' << s.last.c - 1;
return o; return o;
} }
]]) ]])])[
AT_YYERROR_DEFINE], ]AT_YYERROR_DEFINE[
[/* A C error reporting function. */
static void
yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
AT_PARAM_IF([semantic_value *result, int *count, ])
const char *s)
{
AT_PARAM_IF([(void) result; (void) count;])
AT_YYERROR_SEES_LOC_IF([
fprintf (stderr, "%d.%d",
AT_LOC_FIRST_LINE, AT_LOC_FIRST_COLUMN);
if (AT_LOC_FIRST_LINE != AT_LOC_LAST_LINE)
fprintf (stderr, "-%d.%d",
AT_LOC_LAST_LINE, AT_LOC_LAST_COLUMN - 1);
else if (AT_LOC_FIRST_COLUMN != AT_LOC_LAST_COLUMN - 1)
fprintf (stderr, "-%d",
AT_LOC_LAST_COLUMN - 1);
fprintf (stderr, ": ");])
fprintf (stderr, "%s\n", s);
}])[
]AT_DEFINES_IF([], ]AT_DEFINES_IF([],
[AT_CALC_LEX [AT_CALC_LEX
AT_CALC_MAIN])]) AT_CALC_MAIN])])
@@ -550,7 +514,7 @@ _AT_CHECK_CALC([$1],
[842]) [842])
# Some syntax errors. # Some syntax errors.
_AT_CHECK_CALC_ERROR([$1], [1], [0 0], [15], _AT_CHECK_CALC_ERROR([$1], [1], [1 2], [15],
[1.3: syntax error, unexpected number]) [1.3: syntax error, unexpected number])
_AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20], _AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20],
[1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!']) [1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!'])
@@ -594,10 +558,10 @@ calc: error: 4444 != 1])
# The same, but this time exercising explicitly triggered syntax errors. # The same, but this time exercising explicitly triggered syntax errors.
# POSIX says the lookahead causing the error should not be discarded. # POSIX says the lookahead causing the error should not be discarded.
_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (0 0) = 1], [102], _AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1], [102],
[1.10: syntax error, unexpected number [1.10: syntax error, unexpected number
calc: error: 2222 != 1]) calc: error: 2222 != 1])
_AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (0 0) = 1], [113], _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1], [113],
[1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!' [1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
1.12: syntax error, unexpected number 1.12: syntax error, unexpected number
calc: error: 2222 != 1]) calc: error: 2222 != 1])

View File

@@ -376,7 +376,7 @@ m4_define([_AT_GLR_STDERR],
]]) ]])
m4_define([_AT_GLR_STDERR_WITH_LOC], m4_define([_AT_GLR_STDERR_WITH_LOC],
[[17.5-4: syntax error [[17.5: syntax error
]]) ]])
m4_define([_AT_VERBOSE_GLR_STDERR], m4_define([_AT_VERBOSE_GLR_STDERR],
@@ -384,7 +384,7 @@ m4_define([_AT_VERBOSE_GLR_STDERR],
]]) ]])
m4_define([_AT_VERBOSE_GLR_STDERR_WITH_LOC], m4_define([_AT_VERBOSE_GLR_STDERR_WITH_LOC],
[[17.5-4: syntax error, unexpected ID, expecting '=' or '+' or ')' [[17.5: syntax error, unexpected ID, expecting '=' or '+' or ')'
]]) ]])
## ---------------------------------------------------- ## ## ---------------------------------------------------- ##

View File

@@ -1543,13 +1543,6 @@ AT_DATA_GRAMMAR([glr-regr17.y],
]AT_YYLEX_DECLARE[ ]AT_YYLEX_DECLARE[
%} %}
%initial-action {
@$.first_line = 1;
@$.first_column = 1;
@$.last_line = 1;
@$.last_column = 1;
}
%% %%
/* Tests the case of an empty RHS that has inherited the location of the /* Tests the case of an empty RHS that has inherited the location of the

View File

@@ -240,9 +240,6 @@ AT_TEST([x7], [%define api.push-pull both])
AT_TEST([x8], [%define api.pure %define api.push-pull both]) AT_TEST([x8], [%define api.pure %define api.push-pull both])
#AT_TEST([x5], [%locations %language "c++" %glr-parser]) #AT_TEST([x5], [%locations %language "c++" %glr-parser])
AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
AT_CHECK([./parser], [0], [[expout]])
# Check that the headers are self-contained, and protected against # Check that the headers are self-contained, and protected against
# multiple inclusions. While at it, check they are sane for C++. # multiple inclusions. While at it, check they are sane for C++.
for h in *.h *.hh for h in *.h *.hh
@@ -256,6 +253,12 @@ EOF
AT_COMPILE_CXX([$h.o]) AT_COMPILE_CXX([$h.o])
done done
# Do this late, so that other checks have been performed.
AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
AT_CHECK([./parser], [0], [[expout]])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
AT_CLEANUP AT_CLEANUP

View File

@@ -20,6 +20,67 @@ AT_BANNER([[Input Processing.]])
# Mostly test that we are robust to mistakes. # Mostly test that we are robust to mistakes.
## ---------------- ##
## Invalid inputs. ##
## ---------------- ##
AT_SETUP([Invalid inputs])
AT_DATA([input.y],
[[\000\001\002\377?
%%
?
default: 'a' }
%&
%a-does-not-exist
%-
%{
]])
AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y || exit 77]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:1.1: error: invalid character: '\0'
input.y:1.1: error: invalid character: '\001'
input.y:1.1: error: invalid character: '\002'
input.y:1.1: error: invalid character: '\377'
input.y:1.2: error: invalid character: '?'
input.y:3.1: error: invalid character: '?'
input.y:4.14: error: invalid character: '}'
input.y:5.1: error: invalid character: '%'
input.y:5.2: error: invalid character: '&'
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
input.y:7.1: error: invalid character: '%'
input.y:7.2: error: invalid character: '-'
input.y:8.1-9.0: error: missing '%}' at end of file
input.y:8.1-9.0: error: syntax error, unexpected %{...%}
]])
AT_CLEANUP
AT_SETUP([Invalid inputs with {}])
# We used to SEGV here. See
# http://lists.gnu.org/archive/html/bug-bison/2005-07/msg00053.html
AT_DATA([input.y],
[[
%destructor
%initial-action
%lex-param
%parse-param
%printer
%union
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:3.1-15: error: syntax error, unexpected %initial-action, expecting {...}
]])
AT_CLEANUP
## ------------ ## ## ------------ ##
## Invalid $n. ## ## Invalid $n. ##
## ------------ ## ## ------------ ##

View File

@@ -119,6 +119,7 @@ m4_pushdef([AT_SKEL_CC_IF],
[m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])]) [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
m4_pushdef([AT_SKEL_JAVA_IF], m4_pushdef([AT_SKEL_JAVA_IF],
[m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])]) [m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])])
# The target language: "c", "c++", or "java".
m4_pushdef([AT_LANG], m4_pushdef([AT_LANG],
[AT_SKEL_JAVA_IF([java], [AT_SKEL_JAVA_IF([java],
[AT_SKEL_CC_IF([c++], [AT_SKEL_CC_IF([c++],
@@ -140,6 +141,12 @@ m4_pushdef([AT_LOCATION_TYPE_IF],
[m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])]) [m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])])
m4_pushdef([AT_PARAM_IF], m4_pushdef([AT_PARAM_IF],
[m4_bmatch([$3], [%parse-param], [$1], [$2])]) [m4_bmatch([$3], [%parse-param], [$1], [$2])])
# Comma-terminated list of formals parse-parameters.
# E.g., %parse-param { int x } {int y} -> "int x, int y, ".
m4_pushdef([AT_PARSE_PARAMS])
m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
[m4_append([AT_PARSE_PARAMS], [\1, ])])
m4_pushdef([AT_PURE_IF], m4_pushdef([AT_PURE_IF],
[m4_bmatch([$3], [%define *api\.pure\|%pure-parser], [m4_bmatch([$3], [%define *api\.pure\|%pure-parser],
[m4_bmatch([$3], [%define *api\.pure *"?false"?], [$2], [$1])], [m4_bmatch([$3], [%define *api\.pure *"?false"?], [$2], [$1])],
@@ -241,6 +248,7 @@ m4_popdef([AT_GLR_OR_PARAM_IF])
m4_popdef([AT_PURE_AND_LOC_IF]) m4_popdef([AT_PURE_AND_LOC_IF])
m4_popdef([AT_LOCATION_TYPE_IF]) m4_popdef([AT_LOCATION_TYPE_IF])
m4_popdef([AT_LOCATION_IF]) m4_popdef([AT_LOCATION_IF])
m4_popdef([AT_PARSE_PARAMS])
m4_popdef([AT_PARAM_IF]) m4_popdef([AT_PARAM_IF])
m4_popdef([AT_LEXPARAM_IF]) m4_popdef([AT_LEXPARAM_IF])
m4_popdef([AT_YACC_IF]) m4_popdef([AT_YACC_IF])
@@ -350,7 +358,7 @@ static
# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair. # Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
m4_define([AT_YYERROR_FORMALS], m4_define([AT_YYERROR_FORMALS],
[m4_case(AT_LANG, [m4_case(AT_LANG,
[c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])[const char *msg]])[]dnl [c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])AT_PARSE_PARAMS [const char *msg]])[]dnl
]) ])
m4_define([AT_YYERROR_PROTOTYPE], m4_define([AT_YYERROR_PROTOTYPE],
@@ -374,16 +382,11 @@ m4_define([AT_YYERROR_DEFINE],
/* A C error reporting function. */ /* A C error reporting function. */
static static
]AT_YYERROR_PROTOTYPE[ ]AT_YYERROR_PROTOTYPE[
{ {]m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]),
]AT_YYERROR_SEES_LOC_IF([[ [[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\), *], [
fprintf (stderr, "%d.%d", YYUSE(\1);])dnl
]AT_LOC_FIRST_LINE[, ]AT_LOC_FIRST_COLUMN[); AT_YYERROR_SEES_LOC_IF([[
if (]AT_LOC_FIRST_LINE[ != ]AT_LOC_LAST_LINE[) YY_LOCATION_PRINT (stderr, ]AT_LOC[);
fprintf (stderr, "-%d.%d",
]AT_LOC_LAST_LINE[, ]AT_LOC_LAST_COLUMN[ - 1);
else if (]AT_LOC_FIRST_COLUMN[ != ]AT_LOC_LAST_COLUMN[ - 1)
fprintf (stderr, "-%d",
]AT_LOC_LAST_COLUMN[ - 1);
fprintf (stderr, ": ");]])[ fprintf (stderr, ": ");]])[
fprintf (stderr, "%s\n", msg); fprintf (stderr, "%s\n", msg);
}]], }]],
@@ -680,6 +683,44 @@ m4_define([AT_FULL_COMPILE],
]) ])
# AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
# --------------------------------
# Check that we can link together C and C++ objects.
m4_define([AT_SKIP_IF_CANNOT_LINK_C_AND_CXX],
[AT_DATA([c-and-cxx.h],
[[#ifdef __cplusplus
extern "C"
{
#endif
int fortytwo (void);
#ifdef __cplusplus
}
#endif
]])
AT_DATA([c-only.c],
[[#include "c-and-cxx.h"
int
main (void)
{
return fortytwo () == 42 ? 0 : 1;
}
]])
AT_DATA([cxx-only.cc],
[[#include "c-and-cxx.h"
int fortytwo ()
{
return 42;
}
]])
AT_COMPILE([c-only.o], [c-only.c])
AT_COMPILE_CXX([cxx-only.o], [cxx-only.cc])
AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS c-only.o cxx-only.o -o c-and-cxx ||
exit 77], [ignore], [ignore])
AT_CHECK([./c-and-cxx])
])
## ---------------------------- ## ## ---------------------------- ##
## Running a generated parser. ## ## Running a generated parser. ##
## ---------------------------- ## ## ---------------------------- ##

View File

@@ -443,14 +443,19 @@ AT_SETUP([Stray symbols in brackets])
AT_DATA_GRAMMAR([test.y], AT_DATA_GRAMMAR([test.y],
[[ [[
%% %%
start: foo[ /* aaa */ *&-.+ ] bar start: foo[ /* aaa */ *&-.+\000\001\002\377 ] bar
{ s = $foo; } { s = $foo; }
]]) ]])
AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' test.y || exit 77]])
AT_BISON_CHECK([-o test.c test.y], 1, [], AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:11.23: error: invalid character in bracketed name: '*' [[test.y:11.23: error: invalid character in bracketed name: '*'
test.y:11.24: error: invalid character in bracketed name: '&' test.y:11.24: error: invalid character in bracketed name: '&'
test.y:11.25: error: invalid character in bracketed name: '-' test.y:11.25: error: invalid character in bracketed name: '-'
test.y:11.27: error: invalid character in bracketed name: '+' test.y:11.27: error: invalid character in bracketed name: '+'
test.y:11.28: error: invalid character in bracketed name: '\0'
test.y:11.28: error: invalid character in bracketed name: '\001'
test.y:11.28: error: invalid character in bracketed name: '\002'
test.y:11.28: error: invalid character in bracketed name: '\377'
]]) ]])
AT_CLEANUP AT_CLEANUP

View File

@@ -1597,14 +1597,14 @@ AT_CLEANUP
m4_pushdef([AT_TEST], m4_pushdef([AT_TEST],
[AT_SETUP([[Lex and parse params: $1]]) [AT_SETUP([[Lex and parse params: $1]])
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton $1]) AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" %parse-param { int x } %parse-param { int y }])
## FIXME: Improve parsing of parse-param and use the generated ## FIXME: Improve parsing of parse-param and use the generated
## yyerror. ## yyerror.
AT_DATA_GRAMMAR([input.y], AT_DATA_GRAMMAR([input.y],
[[%defines [[%defines
%locations %locations
%skeleton $1 %skeleton "$1"
%union { int ival; } %union { int ival; }
%parse-param { int x } %parse-param { int x }
// Spaces, tabs, and new lines. // Spaces, tabs, and new lines.
@@ -1618,26 +1618,18 @@ AT_DATA_GRAMMAR([input.y],
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
]AT_SKEL_CC_IF([], [[ ]AT_YYERROR_DECLARE[
static
void
yyerror (int x, int y, const char *msg)
{
fprintf (stderr, "x: %d, y: %d, %s\n", x, y, msg);
}]])[
]AT_YYLEX_DECLARE[ ]AT_YYLEX_DECLARE[
%} %}
%% %%
exp: 'a' { fprintf (stdout, "x: %d, y: %d\n", x, y); }; exp: 'a' { fprintf (stdout, "x: %d, y: %d\n", x, y); };
%% %%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["a"])[ ]AT_YYLEX_DEFINE(["a"])[
]AT_SKEL_CC_IF( ]AT_SKEL_CC_IF(
[AT_YYERROR_DEFINE [int
int
yyparse (int x, int y) yyparse (int x, int y)
{ {
yy::parser parser(x, y); yy::parser parser(x, y);
@@ -1661,9 +1653,9 @@ AT_CLEANUP
]) ])
## FIXME: test Java, and iterate over skeletons. ## FIXME: test Java, and iterate over skeletons.
AT_TEST("yacc.c") AT_TEST([yacc.c])
AT_TEST("glr.c") AT_TEST([glr.c])
AT_TEST("lalr1.cc") AT_TEST([lalr1.cc])
AT_TEST("glr.cc") AT_TEST([glr.cc])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])