Merge remote-tracking branch 'origin/maint'

* origin/maint: (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:
	data/lalr1.cc
	gnulib
	src/scan-gram.l
	submodules/autoconf
	tests/calc.at
This commit is contained in:
Akim Demaille
2012-11-06 18:23:47 +01:00
20 changed files with 369 additions and 231 deletions

19
NEWS
View File

@@ -291,6 +291,25 @@ GNU Bison NEWS
The reductions are now explicitly represented as transitions to other
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]
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
Magnus Fromreide magfr@lysator.liu.se
Marc Autret autret_m@epita.fr
Marc Mendiola mmendiol@usc.edu
Martin Jacobs martin.jacobs@arcor.de
Martin Mokrejs mmokrejs@natur.cuni.cz
Martin Nylin martin.nylin@linuxmail.org
@@ -89,6 +90,7 @@ Paul Hilfinger Hilfinger@CS.Berkeley.EDU
Per Allansson per@appgate.com
Peter Fales psfales@lucent.com
Peter Hamorsky hamo@upjs.sk
Peter Simons simons@cryp.to
Piotr Gackiewicz gacek@intertel.com.pl
Quentin Hocquet hocquet@gostai.com
Quoc Peyrot chojin@lrde.epita.fr

View File

@@ -598,3 +598,46 @@ m4_define([b4_yylloc_default_define],
while (0)
#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

@@ -232,11 +232,11 @@ b4_percent_code_get([[top]])[
#endif
/* Default (constant) value used for initialization for null
right-hand sides. Unlike the standard yacc.c template,
here we set the default value of $$ to a zeroed-out value.
Since the default value is undefined, this behavior is
technically correct. */
static YYSTYPE yyval_default;
right-hand sides. Unlike the standard yacc.c template, here we set
the default value of $$ to a zeroed-out value. Since the default
value is undefined, this behavior is technically correct. */
static YYSTYPE yyval_default;]b4_locations_if([[
static YYLTYPE yyloc_default][]b4_yyloc_default;])[
/* Copy the second part of user declarations. */
]b4_user_post_prologue
@@ -412,28 +412,10 @@ dnl We probably ought to introduce a type for confl.
#define YYTERROR 1
]b4_locations_if([[
#ifndef YYLLOC_DEFAULT
]b4_yylloc_default_define[
# define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
/* 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. */
# 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
]])[
]b4_yy_location_print_define[
/* YYLEX -- calling `yylex' with the right arguments. */
#define YYLEX ]b4_function_call([yylex], [int], b4_lex_param)[
@@ -2278,14 +2260,9 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY;
yylval = yyval_default;
]b4_locations_if([
#if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
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], [
yylval = yyval_default;]b4_locations_if([
yylloc = yyloc_default;])[
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */
b4_user_initial_action

View File

@@ -81,12 +81,17 @@ b4_locations_if([,
]b4_parse_param_use[]dnl
[ 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
# and declaration of yyerror.
m4_append([b4_post_prologue],
]m4_append([b4_post_prologue],
[b4_syncline([@oline@], [@ofile@])[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)

View File

@@ -663,11 +663,11 @@ m4_if(b4_prefix, [yy], [],
/// Whether yyla contains a lookahead.
bool yyempty = true;
/* State. */
// State.
int yyn;
int yylen = 0;
/* Error handling. */
// Error handling.
int yynerrs_ = 0;
int yyerrstatus_ = 0;

View File

@@ -73,7 +73,7 @@ m4_define([b4_position_define],
};
/// Add and assign a position.
inline const position&
inline position&
operator+= (position& res, const int width)
{
res.columns (width);
@@ -89,7 +89,7 @@ m4_define([b4_position_define],
}
/// Add and assign a position.
inline const position&
inline position&
operator-= (position& res, const int width)
{
return res += -width;

View File

@@ -173,10 +173,11 @@ m4_define([b4_declare_scanner_communication_variables], [[
int yychar;
]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. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
@@ -184,21 +185,22 @@ int yychar;
/* Default value used for initialization, for pacifying older GCCs
or non-GCC compilers. */
static YYSTYPE yyval_default;
# define YYLVAL_INITIALIZE() (yylval = yyval_default)
# define YY_INITIAL_VALUE(Value) = Value
#endif]])[
#ifndef YYLVAL_INITIALIZE
# define YYLVAL_INITIALIZE()
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
/* 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. */
YYLTYPE yylloc;]])b4_pure_if([], [[
YYLTYPE yylloc][]b4_yyloc_default[;
]])b4_pure_if([], [[
/* Number of syntax errors so far. */
int yynerrs;]])])
@@ -266,7 +268,7 @@ typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
[[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([,
[[[int pushed_char]], [[pushed_char]]],
[[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_pull_if([b4_function_declare([b4_prefix[pull_parse]], [[int]],
[[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
@@ -664,33 +666,15 @@ do \
} \
while (0)
/* Error token number */
#define YYTERROR 1
#define YYERRCODE 256
]b4_locations_if([[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K])
/* 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) \
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]])[
]])[
]b4_yy_location_print_define[
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
@@ -1323,7 +1307,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
yypstate *yyps_local;]b4_pure_if([[
int yychar;
YYSTYPE yylval;]b4_locations_if([[
YYLTYPE yylloc;]])])[
YYLTYPE yylloc][]b4_yyloc_default[;]])])[
if (yyps)
yyps_local = yyps;
else
@@ -1403,7 +1387,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
[[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
[[[int yypushed_char]], [[yypushed_char]]],
[[[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]))], [[
@@ -1449,9 +1433,9 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
goto yyread_pushed_token;
}]])[
yyss = yyssa;
yyvs = yyvsa;]b4_locations_if([[
yyls = yylsa;]])[
yyssp = yyss = yyssa;
yyvsp = yyvs = yyvsa;]b4_locations_if([[
yylsp = yyls = yylsa;]])[
yystacksize = YYINITDEPTH;]b4_lac_if([[
yyes = yyesa;
@@ -1465,31 +1449,17 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* 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],[
]m4_ifdef([b4_initial_action], [
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. */
b4_user_initial_action
b4_dollar_popdef[]dnl
m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval;
]])dnl
m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc;
]])])dnl
b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])[;
]])dnl
[ goto yysetstate;
/*------------------------------------------------------------.

2
gnulib

Submodule gnulib updated: 6061979365...daf7f8c022

View File

@@ -354,7 +354,8 @@ eqopt ([[:space:]]*=)?
}
. {
complain (loc, complaint, _("invalid character: %s"), quote (yytext));
complain (loc, complaint, _("invalid character: %s"),
quote_mem (yytext, yyleng));
}
<<EOF>> {
@@ -450,7 +451,7 @@ eqopt ([[:space:]]*=)?
}
. {
complain (loc, complaint, _("invalid character in bracketed name: %s"),
quote (yytext));
quote_mem (yytext, yyleng));
}
<<EOF>> {
BEGIN bracketed_id_context_state;

View File

@@ -69,6 +69,76 @@ AT_PARSER_CHECK([./input], 0,
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_COMPILE([[input]])
AT_FULL_COMPILE([input])
AT_PARSER_CHECK([[./input]], [[0]],
[[6
]])
@@ -557,7 +626,7 @@ AT_BISON_OPTION_POPDEFS
# AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
# ---------------------------------------------------------------------------
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
_AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
@@ -595,10 +664,6 @@ AT_DATA_GRAMMAR([[input.y]],
[[%define parse.error verbose
%debug
%locations
%initial-action {
@$.first_line = @$.last_line = 1;
@$.first_column = @$.last_column = 1;
}
%{
# include <stdio.h>
@@ -647,8 +712,8 @@ main (void)
]])
AT_BISON_CHECK([-o input.c input.y], [], [],
[[input.y:27.3-5: warning: useless %destructor for type <*> [-Wother]
input.y:27.3-5: warning: useless %printer for type <*> [-Wother]
[[input.y:23.3-5: warning: useless %destructor for type <*> [-Wother]
input.y:23.3-5: warning: useless %printer for type <*> [-Wother]
]])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], 1,
@@ -659,29 +724,29 @@ AT_PARSER_CHECK([./input], 1,
]],
[[Starting parse
Entering state 0
Reading a token: Next token is token 'a' (1.1-1.1: <> printer for 'a' @ 1)
Shifting 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: <> printer for 'a' @ 1)
Entering state 1
Reading a token: Next token is token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
Shifting 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: 'b'/'c' printer for 'b' @ 2)
Entering state 3
Reading a token: Next token is token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
Shifting 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: 'b'/'c' printer for 'c' @ 3)
Entering state 5
Reading a token: Next token is token 'd' (1.4-1.4: <> printer for 'd' @ 4)
Shifting 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: <> printer for 'd' @ 4)
Entering state 6
Reading a token: Now at end of input.
1.5-4: syntax error, unexpected $end, expecting 'e'
Error: popping token 'd' (1.4-1.4: <> printer for 'd' @ 4)
1.5: syntax error, unexpected $end, expecting 'e'
Error: popping token 'd' (1.4: <> printer for 'd' @ 4)
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
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
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
Cleanup: discarding lookahead token $end (1.5-1.5: )
Cleanup: discarding lookahead token $end (1.5: )
Stack now 0
]])
@@ -835,10 +900,6 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]],
[[%define parse.error verbose
%debug
%locations
%initial-action {
@$.first_line = @$.last_line = 1;
@$.first_column = @$.last_column = 1;
}
%{
# include <stdio.h>
@@ -899,11 +960,11 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
[m4_if([$1], [0],
[[input0.y:27.3-5: warning: useless %destructor for type <*> [-Wother]
input0.y:27.3-5: warning: useless %printer for type <*> [-Wother]
[[input0.y:23.3-5: warning: useless %destructor for type <*> [-Wother]
input0.y:23.3-5: warning: useless %printer for type <*> [-Wother]
]],
[[input1.y:27.3-4: warning: useless %destructor for type <> [-Wother]
input1.y:27.3-4: warning: useless %printer for type <> [-Wother]
[[input1.y:23.3-4: warning: useless %destructor for type <> [-Wother]
input1.y:23.3-4: warning: useless %printer for type <> [-Wother]
]])])
AT_COMPILE([input$1])
@@ -914,16 +975,16 @@ AT_PARSER_CHECK([./input$1], 0,
]],
[[Starting parse
Entering state 0
Reducing stack by rule 1 (line 46):
-> $$ = nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1)
Reducing stack by rule 1 (line 42):
-> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
Stack now 0
Entering state 1
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
Stack now 0 1 2
Cleanup: popping token END (1.1-1.1: <]]kind[[> for 'E' @ 1)
Cleanup: popping nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1)
Cleanup: popping token END (1.1: <]]kind[[> for 'E' @ 1)
Cleanup: popping nterm start (1.1: <]]kind[[> for 'S' @ 1)
]])
m4_popdef([kind])

View File

@@ -178,18 +178,7 @@ read_signed_integer (]AT_YYLEX_FORMALS[)
]AT_YYLEX_PROTOTYPE[
{
static int init = 1;
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. */
do
{
@@ -261,6 +250,8 @@ AT_SKEL_CC_IF(
{
semantic_value ival;
};
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
[[fprintf (yyoutput, "%d", $$)]])[; } <ival>;
%code provides
{
@@ -280,24 +271,16 @@ AT_SKEL_CC_IF(
FILE *input;
static int power (int base, int exponent);
]AT_SKEL_CC_IF(,
[static void yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
AT_PARAM_IF([semantic_value *result, int *count, ])
const char *s
);])[
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE_EXTERN[
}
]AT_SKEL_CC_IF([AT_LOCATION_IF([AT_LOCATION_TYPE_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 ();
}
])])])[
]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([[
%initial-action
{
@$.first.l = @$.first.c = 1;
@$.last = @$.first;
}]])])[
/* Bison Declarations */
%token CALC_EOF 0 "end of input"
@@ -365,27 +348,8 @@ power (int base, int exponent)
o << '-' << s.last.c - 1;
return o;
}
]])
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_YYERROR_DEFINE[
]AT_DEFINES_IF([],
[AT_CALC_LEX
AT_CALC_MAIN])])
@@ -552,7 +516,7 @@ _AT_CHECK_CALC([$1],
[842])
# 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])
_AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20],
[1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!'])
@@ -596,10 +560,10 @@ calc: error: 4444 != 1])
# The same, but this time exercising explicitly triggered syntax errors.
# 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
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.12: syntax error, unexpected number
calc: error: 2222 != 1])
@@ -656,7 +620,7 @@ AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %defi
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
# ----------------------- #
@@ -694,8 +658,8 @@ AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %defin
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
# ----------------------------- #
@@ -725,10 +689,10 @@ AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-pref
AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
@@ -760,5 +724,5 @@ AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %ve
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])

View File

@@ -376,7 +376,7 @@ m4_define([_AT_GLR_STDERR],
]])
m4_define([_AT_GLR_STDERR_WITH_LOC],
[[17.5-4: syntax error
[[17.5: syntax error
]])
m4_define([_AT_VERBOSE_GLR_STDERR],
@@ -384,7 +384,7 @@ m4_define([_AT_VERBOSE_GLR_STDERR],
]])
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

@@ -1545,13 +1545,6 @@ AT_DATA_GRAMMAR([glr-regr17.y],
]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

View File

@@ -241,9 +241,6 @@ AT_TEST([x7], [%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_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
# multiple inclusions. While at it, check they are sane for C++.
for h in *.h *.hh
@@ -257,6 +254,12 @@ EOF
AT_COMPILE_CXX([$h.o])
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])
AT_CLEANUP

View File

@@ -20,6 +20,67 @@ AT_BANNER([[Input Processing.]])
# 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. ##
## ------------ ##

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_pushdef([AT_SKEL_JAVA_IF],
[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],
[AT_SKEL_JAVA_IF([java],
[AT_SKEL_CC_IF([c++],
@@ -140,6 +141,13 @@ m4_pushdef([AT_LOCATION_TYPE_IF],
[m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])])
m4_pushdef([AT_PARAM_IF],
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
# Comma-terminated list of formals parse-parameters.
# E.g., %parse-param { int x } %parse-param {int y} -> "int x, int y, ".
# FIXME: Support grouped parse-param.
m4_pushdef([AT_PARSE_PARAMS])
m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
[m4_append([AT_PARSE_PARAMS], [\1, ])])
m4_pushdef([AT_PURE_IF],
[m4_bmatch([$3], [%define *api\.pure\|%pure-parser],
[m4_bmatch([$3], [%define *api\.pure *"?false"?], [$2], [$1])],
@@ -250,6 +258,7 @@ m4_popdef([AT_GLR_OR_PARAM_IF])
m4_popdef([AT_PURE_AND_LOC_IF])
m4_popdef([AT_LOCATION_TYPE_IF])
m4_popdef([AT_LOCATION_IF])
m4_popdef([AT_PARSE_PARAMS])
m4_popdef([AT_PARAM_IF])
m4_popdef([AT_LEXPARAM_IF])
m4_popdef([AT_YACC_IF])
@@ -359,7 +368,7 @@ static
# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
m4_define([AT_YYERROR_FORMALS],
[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],
@@ -383,16 +392,11 @@ m4_define([AT_YYERROR_DEFINE],
/* A C error reporting function. */
static
]AT_YYERROR_PROTOTYPE[
{
]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);
{]m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]),
[[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\), *], [
YYUSE(\1);])dnl
AT_YYERROR_SEES_LOC_IF([[
YY_LOCATION_PRINT (stderr, ]AT_LOC[);
fprintf (stderr, ": ");]])[
fprintf (stderr, "%s\n", msg);
}]],
@@ -660,6 +664,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. ##
## ---------------------------- ##

View File

@@ -443,14 +443,19 @@ AT_SETUP([Stray symbols in brackets])
AT_DATA_GRAMMAR([test.y],
[[
%%
start: foo[ /* aaa */ *&-.+ ] bar
start: foo[ /* aaa */ *&-.+\000\001\002\377 ] bar
{ 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, [],
[[test.y:11.23: 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.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

View File

@@ -1590,14 +1590,14 @@ AT_CLEANUP
m4_pushdef([AT_TEST],
[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
## yyerror.
AT_DATA_GRAMMAR([input.y],
[[%defines
%locations
%skeleton $1
%skeleton "$1"
%union { int ival; }
%parse-param { int x }
// Spaces, tabs, and new lines.
@@ -1611,26 +1611,18 @@ AT_DATA_GRAMMAR([input.y],
#include <stdio.h>
#include <stdlib.h>
]AT_SKEL_CC_IF([], [[
static
void
yyerror (int x, int y, const char *msg)
{
fprintf (stderr, "x: %d, y: %d, %s\n", x, y, msg);
}]])[
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
%}
%%
exp: 'a' { fprintf (stdout, "x: %d, y: %d\n", x, y); };
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["a"])[
]AT_SKEL_CC_IF(
[AT_YYERROR_DEFINE
int
[int
yyparse (int x, int y)
{
yy::parser parser(x, y);
@@ -1654,9 +1646,9 @@ AT_CLEANUP
])
## FIXME: test Java, and iterate over skeletons.
AT_TEST("yacc.c")
AT_TEST("glr.c")
AT_TEST("lalr1.cc")
AT_TEST("glr.cc")
AT_TEST([yacc.c])
AT_TEST([glr.c])
AT_TEST([lalr1.cc])
AT_TEST([glr.cc])
m4_popdef([AT_TEST])