+2006-12-25 Joel E. Denny <jdenny@ces.clemson.edu>
+
+ Enable push parsers to operate in impure mode. Thus, %push-parser no
+ longer implies %pure-parser. The point of this change is to move
+ towards being able to test the push parser code by running the entire
+ test suite as if %push-parser had been declared.
+ * data/push.c (yypush_parse): For impure mode, remove the
+ yypushed_char, yypushed_val, and yypushed_loc arguments.
+ Instead, declare these as local variables initialized to the global
+ yychar, yylval, and yylloc.
+ For the first yypush_parse invocation only, restore the initial values
+ of these global variables when it's time to read a token since they
+ have been overwritten.
+ * src/parse-gram.y (prologue_declaration): Don't set pure_parser for
+ %push-parser.
+ * tests/calc.at (Simple LALR(1) Calculator): Always declare
+ %pure-parser along with %push-parser since this test case was designed
+ for pure push parsers.
+ * tests/local.at (AT_PURE_OR_PUSH_IF): Remove unused.
+ (AT_YACC_OR_PUSH_IF): New.
+ (AT_YYERROR_SEES_LOC_IF): Fix enough that the test suite passes, but
+ add a note that it's still wrong for some cases (as it has been for a
+ while).
+ (AT_PURE_LEX_IF): Use AT_PURE_IF instead of AT_PURE_OR_PUSH_IF since
+ %push-parser no longer implies %pure-parser.
+
2006-12-20 Joel E. Denny <jdenny@ces.clemson.edu>
Remove some unnecessary differences between the pull parser code and
b4_c_function_decl([[yypstate_delete]], [[void]],
[[[yypstate *yyps]], [[yyps]]])
b4_c_function_decl([[yypush_parse]], [[int]],
- [[[yypstate *yyps]], [[yyps]]],
+ [[[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 const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param]))[
#endif
]])
`-------------------------*/
]b4_push_if([
-b4_c_function_def([[yypush_parse]], [[int]], [[[yypstate *yyps]], [[yyps]]],
+b4_c_function_def([[yypush_parse]], [[int]],
+ [[[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 const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param]))], [
#ifdef YYPARSE_PARAM
b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
#endif])[
{
]b4_pure_if([b4_declare_scanner_communication_variables])
- b4_push_if([], [b4_declare_parser_state_variables])[
+ b4_push_if([b4_pure_if([], [[ int yypushed_char = yychar;
+ YYSTYPE yypushed_val = yylval;
+ ]b4_locations_if([[YYLTYPE yypushed_loc = yylloc;
+]])])],
+ [b4_declare_parser_state_variables])[
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
goto yypushreturn;
}
yyps->yynew = 0;
-
+]b4_pure_if([], [[
+ /* Restoring the pushed token is only necessary for the first
+ yypush_parse invocation since subsequent invocations don't overwrite
+ it before jumping to yyread_pushed_token. */
+ yychar = yypushed_char;
+ yylval = yypushed_val;
+ ]b4_locations_if([[yylloc = yypushed_loc;
+]])])[
yyread_pushed_token:
]])[ YYDPRINTF ((stderr, "Reading a token: "));
-]b4_push_if([[ yychar = yypushed_char;
+]b4_push_if([b4_pure_if([[ yychar = yypushed_char;
if (yypushed_val)
yylval = *yypushed_val;
]b4_locations_if([[ if (yypushed_loc)
- yylloc = *yypushed_loc;]])],
+ yylloc = *yypushed_loc;
+]])])],
[[ yychar = YYLEX;
]])[ }
b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
[[b4_prefix[pstate *yyps]], [[yyps]]])
b4_c_function_decl([b4_prefix[push_parse]], [[int]],
- [[b4_prefix[pstate *yyps]], [[yyps]]],
+ [[b4_prefix[pstate *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 const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param]))[
#endif
]])
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
-/* Line 191 of yacc.c */
+/* Line 198 of yacc.c */
#line 97 "parse-gram.y"
symbol *symbol;
unsigned char character;
}
-/* Line 191 of yacc.c */
+/* Line 198 of yacc.c */
#line 326 "parse-gram.c"
YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
/* User initialization code. */
-/* Line 1076 of yacc.c */
+/* Line 1082 of yacc.c */
#line 89 "parse-gram.y"
{
/* Bison's grammar can initial empty locations, hence a default
boundary_set (&yylloc.end, current_file, 1, 1);
}
-/* Line 1076 of yacc.c */
+/* Line 1082 of yacc.c */
#line 1712 "parse-gram.c"
yylsp[0] = yylloc;
goto yysetstate;
/* Line 1269 of yacc.c */
#line 260 "parse-gram.y"
- { push_parser = true; pure_parser = true; }
+ { push_parser = true; }
break;
case 30:
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
-/* Line 1487 of yacc.c */
+/* Line 1535 of yacc.c */
#line 97 "parse-gram.y"
symbol *symbol;
unsigned char character;
}
-/* Line 1487 of yacc.c */
+/* Line 1535 of yacc.c */
#line 186 "parse-gram.h"
YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
| "%output" "=" STRING { spec_outfile = $3; } /* deprecated */
| "%parse-param" "{...}" { add_param ("parse_param", $2, @2); }
| "%pure-parser" { pure_parser = true; }
-| "%push-parser" { push_parser = true; pure_parser = true; }
+| "%push-parser" { push_parser = true; }
| "%require" STRING { version_check (&@2, $2); }
| "%skeleton" STRING { skeleton_arg ($2, 1, &@1); }
| "%token-table" { token_table_flag = true; }
AT_CHECK_CALC_LALR([%error-verbose])
AT_CHECK_CALC_LALR([%pure-parser %locations])
-AT_CHECK_CALC_LALR([%push-parser %locations %skeleton "push.c"])
+AT_CHECK_CALC_LALR([%push-parser %pure-parser %locations %skeleton "push.c"])
AT_CHECK_CALC_LALR([%error-verbose %locations])
AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
-AT_CHECK_CALC_LALR([%push-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %skeleton "push.c"])
+AT_CHECK_CALC_LALR([%push-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %skeleton "push.c"])
AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
[m4_bmatch([$3], [%pure-parser], [$1], [$2])])
m4_pushdef([AT_PUSH_IF],
[m4_bmatch([$3], [%push-parser], [$1], [$2])])
-m4_pushdef([AT_PURE_OR_PUSH_IF],
-[m4_bmatch([$3], [%pure-parser\|%push-parser], [$1], [$2])])
+m4_pushdef([AT_YACC_OR_PUSH_IF],
+[AT_YACC_IF([$1], [AT_PUSH_IF([$1], [$2])])])
m4_pushdef([AT_PURE_AND_LOC_IF],
[m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations],
[$1], [$2])])
[AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
[$2])])
# yyerror always sees the locations (when activated), except if
-# push or (yacc & pure & !param).
+# (yacc & pure & !param). FIXME: This is wrong. See the manual.
m4_pushdef([AT_YYERROR_SEES_LOC_IF],
-[AT_PUSH_IF([$2],[AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
- [$1])],
- [$1])],
- [$2])])])
+[AT_LOCATION_IF([AT_YACC_OR_PUSH_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
+ [$1])],
+ [$1])],
+ [$2])])
# The interface is pure: either because %pure-parser, or because we
# are using the C++ parsers.
m4_pushdef([AT_PURE_LEX_IF],
-[AT_PURE_OR_PUSH_IF([$1],
+[AT_PURE_IF([$1],
[AT_SKEL_CC_IF([$1], [$2])])])
AT_PURE_LEX_IF(