glr.cc, yacc.c: initialize yylloc properly

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.
This commit is contained in:
Akim Demaille
2012-11-06 15:34:51 +01:00
parent 3237f57096
commit a1d1ab50a0
6 changed files with 99 additions and 22 deletions

View File

@@ -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
])
]])

View File

@@ -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

View File

@@ -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([@oline@], [@ofile@])[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)

View File

@@ -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;
/*------------------------------------------------------------.