From 451364edb17dae7d19301a494f8be7dad67287d2 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 20 Sep 2004 15:25:25 +0000 Subject: [PATCH] Let the initial-action act on the look-ahead, and use it for the "initial push" (corresponding to an hypothetical beginning-of-file). And let lalr1.cc honor %initial-action. * doc/bison.texinfo (Initial Action Decl): Clarify, and add an example. * data/lalr1.cc (Parser::initlocation_): Remove, bad experiment. (Parser::Parser): Remove the ctor that used to initialize it. (Parser::parse): Like in the other skeletons, issue the "starting parse" message before any action. Honor %initial-action. Initialize the stacks with the lookahead. * data/yacc.c: Let $$ and @$ in %initial-action designate the look-ahead. Push them in the stacks. * tests/actions.at, tests/calc.at: Adjust the C++ ctor invocations. --- ChangeLog | 19 +++++++++++++++++++ data/lalr1.cc | 49 +++++++++++++++++++++++++------------------------ data/yacc.c | 13 ++++++++----- doc/bison.texinfo | 51 ++++++++++++++++++++++++++++++--------------------- tests/actions.at | 2 +- tests/calc.at | 2 +- 6 files changed, 84 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56392bc..85539ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2004-09-20 Akim Demaille + Let the initial-action act on the look-ahead, and use it for the + "initial push" (corresponding to an hypothetical beginning-of-file). + And let lalr1.cc honor %initial-action. + + * doc/bison.texinfo (Initial Action Decl): Clarify, and add an + example. + * data/lalr1.cc (Parser::initlocation_): Remove, bad experiment. + (Parser::Parser): Remove the ctor that used to initialize it. + (Parser::parse): Like in the other skeletons, issue the "starting + parse" message before any action. + Honor %initial-action. + Initialize the stacks with the lookahead. + * data/yacc.c: Let $$ and @$ in %initial-action designate the + look-ahead. + Push them in the stacks. + * tests/actions.at, tests/calc.at: Adjust the C++ ctor invocations. + +2004-09-20 Akim Demaille + * doc/bison.texinfo (Initial Action Decl): New. 2004-09-20 Akim Demaille diff --git a/data/lalr1.cc b/data/lalr1.cc index ef5aad8..8ff462a 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -218,17 +218,9 @@ namespace yy typedef Stack< SemanticType > SemanticStack; typedef Stack< LocationType > LocationStack; -#if YYLSP_NEEDED - ]b4_parser_class_name[ (bool debug, - LocationType initlocation][]b4_param[]b4_parse_param_decl[) : - ]b4_constructor[][debug_ (debug), - cdebug_ (std::cerr), - initlocation_ (initlocation)]b4_parse_param_cons[ -#else ]b4_parser_class_name[ (bool debug][]b4_param[]b4_parse_param_decl[) : ]b4_constructor[][debug_ (debug), cdebug_ (std::cerr)]b4_parse_param_cons[ -#endif { } @@ -325,18 +317,17 @@ namespace yy /* Message. */ std::string message; - /* Semantic value and location of look-ahead token. */ + /// Semantic value of the look-ahead. SemanticType value; + /// Location of the look-ahead. LocationType location; /// The locations where the error started and ended. Location error_range_[2]; - /* @@$ and $$. */ + /// $$. SemanticType yyval; + /// @@$. LocationType yyloc; - - /* Initial location. */ - LocationType initlocation_; ]b4_parse_param_vars[ }; } @@ -446,24 +437,34 @@ yy::]b4_parser_class_name[::pop (unsigned int n) int yy::]b4_parser_class_name[::parse () { + YYCDEBUG << "Starting parse" << std::endl; + nerrs_ = 0; errstatus_ = 0; - /* Initialize the stacks. The initial state will be pushed in + /* Start. */ + state_ = 0; + looka_ = empty_; + +]m4_ifdef([b4_initial_action], [ +m4_pushdef([b4_at_dollar], [location])dnl +m4_pushdef([b4_dollar_dollar], [value])dnl + /* User initialization code. */ + b4_initial_action +m4_popdef([b4_dollar_dollar])dnl +m4_popdef([b4_at_dollar])dnl +/* Line __line__ of yacc.c. */ +b4_syncline([@oline@], [@ofile@])])dnl + +[ /* Initialize the stacks. The initial state will be pushed in yynewstate, since the latter expects the semantical and the location values to have been already stored, initialize these stacks with a primary value. */ state_stack_ = StateStack (0); - semantic_stack_ = SemanticStack (1); - location_stack_ = LocationStack (1); - - /* Start. */ - state_ = 0; - looka_ = empty_; -#if YYLSP_NEEDED - location = initlocation_; -#endif - YYCDEBUG << "Starting parse" << std::endl; + semantic_stack_ = SemanticStack (0); + location_stack_ = LocationStack (0); + semantic_stack_.push (value); + location_stack_.push (location); /* New state. */ yynewstate: diff --git a/data/yacc.c b/data/yacc.c index f1040eb..dcc060e 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -821,20 +821,23 @@ b4_c_function_def([yyparse], [int], b4_parse_param) ]b4_location_if([[ yylsp = yyls; #if YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ - yyls[0].first_line = yyls[0].last_line = 1; - yyls[0].first_column = yyls[0].last_column = 0; + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 0; #endif ]]) m4_ifdef([b4_initial_action], [ -m4_pushdef([b4_at_dollar], [(*yylsp)])dnl -m4_pushdef([b4_dollar_dollar], [(*yyvsp)])dnl +m4_pushdef([b4_at_dollar], [(yylloc)])dnl +m4_pushdef([b4_dollar_dollar], [(yylval)])dnl /* User initialization code. */ b4_initial_action m4_popdef([b4_dollar_dollar])dnl m4_popdef([b4_at_dollar])dnl /* Line __line__ of yacc.c. */ b4_syncline([@oline@], [@ofile@])])dnl - +[ + yyvsp[0] = yylval; +]b4_location_if([[ yylsp[0] = yylloc; +]]) [ goto yysetstate; /*------------------------------------------------------------. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index e270692..6917a69 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -3742,10 +3742,21 @@ code. @deffn {Directive} %initial-action @{ @var{code} @} @findex %initial-action Declare that the @var{code} must be invoked before parsing each time -@code{yyparse} is called. The @var{code} may use @code{@@$} to -designate the initial location, and the @code{%parse-param}. +@code{yyparse} is called. The @var{code} may use @code{$$} and +@code{@@$} --- initial value and location of the look-ahead --- and the +@code{%parse-param}. @end deffn +For instance, if your locations use a file name, you may use + +@example +%parse-param @{ const char *filename @}; +%initial-action +@{ + @@$.begin.filename = @@$.end.filename = filename; +@}; +@end example + @node Destructor Decl @subsection Freeing Discarded Symbols @@ -3822,7 +3833,7 @@ stacked symbols popped during the first phase of error recovery, @item incoming terminals during the second phase of error recovery, @item -the current lookahead when the parser aborts (either via an explicit +the current look-ahead when the parser aborts (either via an explicit call to @code{YYABORT}, or as a consequence of a failed error recovery). @end itemize @@ -5579,11 +5590,10 @@ constant integer. The default is 200. @c FIXME: C++ output. Because of semantical differences between C and C++, the -@acronym{LALR}(1) parsers -in C produced by Bison by compiled as C++ cannot grow. In this precise -case (compiling a C parser as C++) you are suggested to grow -@code{YYINITDEPTH}. In the near future, a C++ output output will be -provided which addresses this issue. +@acronym{LALR}(1) parsers in C produced by Bison by compiled as C++ +cannot grow. In this precise case (compiling a C parser as C++) you are +suggested to grow @code{YYINITDEPTH}. In the near future, a C++ output +output will be provided which addresses this issue. @node Error Recovery @chapter Error Recovery @@ -6887,19 +6897,18 @@ $ @kbd{printf 'one\ntwo\n' | ./split-lines} How can I generate parsers in C++? @end display -We are working on a C++ output for Bison, but unfortunately, for lack -of time, the skeleton is not finished. It is functional, but in -numerous respects, it will require additional work which @emph{might} -break backward compatibility. Since the skeleton for C++ is not -documented, we do not consider ourselves bound to this interface, -nevertheless, as much as possible we will try to keep compatibility. - -Another possibility is to use the regular C parsers, and to compile -them with a C++ compiler. This works properly, provided that you bear -some simple C++ rules in mind, such as not including ``real classes'' -(i.e., structure with constructors) in unions. Therefore, in the -@code{%union}, use pointers to classes, or better yet, a single -pointer type to the root of your lexical/syntactic hierarchy. +We are working on a C++ output for Bison, but unfortunately, for lack of +time, the skeleton is not finished. It is functional, but in numerous +respects, it will require additional work which @emph{might} break +backward compatibility. Since the skeleton for C++ is not documented, +we do not consider ourselves bound to this interface, nevertheless, as +much as possible we will try to keep compatibility. + +Another possibility is to use the regular C parsers, and to compile them +with a C++ compiler. This works properly, provided that you bear some +simple C++ rules in mind, such as not including ``real classes'' (i.e., +structure with constructors) in unions. Therefore, in the +@code{%union}, use pointers to classes. @node Implementing Gotos/Loops diff --git a/tests/actions.at b/tests/actions.at index d4d420e..2ffaffb 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -327,7 +327,7 @@ static bool yydebug; int yyparse () { - yy::Parser parser (yydebug, yy::Location ()); + yy::Parser parser (yydebug); return parser.parse (); } ], diff --git a/tests/calc.at b/tests/calc.at index b7808ac..eb59ac9 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -144,7 +144,7 @@ yy::Parser::error_ () int yyparse (AT_PARAM_IF([semantic_value *result, int *count])) { - yy::Parser parser (!!YYDEBUG[]AT_LOCATION_IF([, yy::Location ()])AT_PARAM_IF([, result, count])); + yy::Parser parser (!!YYDEBUG[]AT_PARAM_IF([, result, count])); return parser.parse (); } ], -- 2.7.4