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

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