[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/8] glr.cc, yacc.c: initialize yylloc properly
From: |
Akim Demaille |
Subject: |
[PATCH 3/8] glr.cc, yacc.c: initialize yylloc properly |
Date: |
Tue, 6 Nov 2012 17:47:12 +0100 |
There are several issues to address here. One is that yylloc should
be initialized when possible. Another is that the push parser needs
to update yypushed_loc when the user modified it. And if the parser
starts by a reduction of an empty, it uses the first location on the
stack, which, therefore, must also be initialized to this initial
location.
This is getting complex, especially since because initializing a
global (impure interface) is different from initializing a local
variable. To simplify, the local yylloc is not initialized during its
definition.
* data/c.m4 (b4_yyloc_default_define): Replace by...
(b4_yyloc_default): this.
Adjust dependencies.
* data/glr.cc: Initialize yylloc.
* data/yacc.c (b4_declare_scanner_communication_variables):
Initialize yylloc during its definition.
Don't define yyloc_default.
(yypush_parse): The location formal is not const, as we might
initialize it.
(yyparse): Define yyloc_default.
Use it before running the user initial action.
Possibly update the first location on the stack, and the pushed
location after the user initial action.
* tests/actions.at (Initial locations): Check that the initial
location is correct.
---
NEWS | 3 +++
data/c.m4 | 14 +++++-------
data/glr.c | 4 ++--
data/glr.cc | 9 ++++++--
data/yacc.c | 21 +++++++++--------
tests/actions.at | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 99 insertions(+), 22 deletions(-)
diff --git a/NEWS b/NEWS
index 37b8e2c..3d21470 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,9 @@ GNU Bison NEWS
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.
diff --git a/data/c.m4 b/data/c.m4
index a1013cc..8bd96b8 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -673,12 +673,11 @@ m4_define([b4_yy_location_print_define],
#endif]])
])
-# b4_yyloc_default_define
-# -----------------------
-# Define yyloc_default, which can be used to initialize location
-# variables.
-m4_define([b4_yyloc_default_define],
-[[static YYLTYPE yyloc_default
+# 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]),
@@ -686,5 +685,4 @@ m4_define([b4_yyloc_default_define],
m4_defn([b4_location_initial_line]),
m4_defn([b4_location_initial_column]))[ }
# endif
- ;]dnl
-])
+]])
diff --git a/data/glr.c b/data/glr.c
index a2992e0..9bd9522 100644
--- a/data/glr.c
+++ b/data/glr.c
@@ -226,8 +226,8 @@ b4_percent_code_get([[top]])[
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([
-b4_yyloc_default_define])[
+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
diff --git a/data/glr.cc b/data/glr.cc
index 826bc80..104bf78 100644
--- a/data/glr.cc
+++ b/data/glr.cc
@@ -87,12 +87,17 @@ m4_define([b4_yy_symbol_print_generate],
]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([[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(address@hidden@], address@hidden@])[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
diff --git a/data/yacc.c b/data/yacc.c
index e82264f..b9a4fb1 100644
--- a/data/yacc.c
+++ b/data/yacc.c
@@ -181,8 +181,7 @@ int yychar;
#else
/* Default value used for initialization, for pacifying older GCCs
or non-GCC compilers. */
-static YYSTYPE yyval_default;]b4_locations_if([
-b4_yyloc_default_define])[
+static YYSTYPE yyval_default;
# define YY_INITIAL_VALUE(Value) = Value
#endif]])[
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
@@ -197,7 +196,8 @@ b4_yyloc_default_define])[
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
/* Location data for the lookahead symbol. */
-YYLTYPE yylloc YY_INITIAL_VALUE(yyloc_default);]])b4_pure_if([], [[
+YYLTYPE yylloc][]b4_yyloc_default[;
+]])b4_pure_if([], [[
/* Number of syntax errors so far. */
int yynerrs;]])])
@@ -265,7 +265,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_c_function_decl([b4_prefix[pull_parse]], [[int]],
[[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
@@ -1409,7 +1409,7 @@ b4_c_function_def([[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
@@ -1489,7 +1489,7 @@ b4_c_function_def([[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]))], [[
@@ -1556,16 +1556,17 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
-]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;
/*------------------------------------------------------------.
diff --git a/tests/actions.at b/tests/actions.at
index fc70f48..0e02239 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -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])
--
1.8.0
- [PATCH 0/8] {branch-2.6} more fixes for -Wuninitialized warnings, Akim Demaille, 2012/11/06
- [PATCH 3/8] glr.cc, yacc.c: initialize yylloc properly,
Akim Demaille <=
- [PATCH 4/8] yacc.c: also disable -Wuninitialized., Akim Demaille, 2012/11/06
- [PATCH 6/8] lalr1.cc: always initialize yylval., Akim Demaille, 2012/11/06
- [PATCH 2/8] yacc.c, glr.c: a better YY_LOCATION_PRINT, Akim Demaille, 2012/11/06
- [PATCH 8/8] tests: calc: modernize the use of locations, Akim Demaille, 2012/11/06
- [PATCH 1/8] yacc.c: simplify initialization, Akim Demaille, 2012/11/06
- [PATCH 5/8] tests: check that C and C++ objects can be linked together., Akim Demaille, 2012/11/06
- [PATCH 7/8] tests: remove useless location initializations, Akim Demaille, 2012/11/06