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.
This commit is contained in:
Akim Demaille
2004-09-20 15:25:25 +00:00
parent 18d192f0ea
commit 451364edb1
6 changed files with 84 additions and 52 deletions

View File

@@ -1,3 +1,22 @@
2004-09-20 Akim Demaille <akim@epita.fr>
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 <akim@epita.fr> 2004-09-20 Akim Demaille <akim@epita.fr>
* doc/bison.texinfo (Initial Action Decl): New. * doc/bison.texinfo (Initial Action Decl): New.

View File

@@ -218,17 +218,9 @@ namespace yy
typedef Stack< SemanticType > SemanticStack; typedef Stack< SemanticType > SemanticStack;
typedef Stack< LocationType > LocationStack; 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_parser_class_name[ (bool debug][]b4_param[]b4_parse_param_decl[) :
]b4_constructor[][debug_ (debug), ]b4_constructor[][debug_ (debug),
cdebug_ (std::cerr)]b4_parse_param_cons[ cdebug_ (std::cerr)]b4_parse_param_cons[
#endif
{ {
} }
@@ -325,18 +317,17 @@ namespace yy
/* Message. */ /* Message. */
std::string message; std::string message;
/* Semantic value and location of look-ahead token. */ /// Semantic value of the look-ahead.
SemanticType value; SemanticType value;
/// Location of the look-ahead.
LocationType location; LocationType location;
/// The locations where the error started and ended. /// The locations where the error started and ended.
Location error_range_[2]; Location error_range_[2];
/* @@$ and $$. */ /// $$.
SemanticType yyval; SemanticType yyval;
/// @@$.
LocationType yyloc; LocationType yyloc;
/* Initial location. */
LocationType initlocation_;
]b4_parse_param_vars[ ]b4_parse_param_vars[
}; };
} }
@@ -446,24 +437,34 @@ yy::]b4_parser_class_name[::pop (unsigned int n)
int int
yy::]b4_parser_class_name[::parse () yy::]b4_parser_class_name[::parse ()
{ {
YYCDEBUG << "Starting parse" << std::endl;
nerrs_ = 0; nerrs_ = 0;
errstatus_ = 0; errstatus_ = 0;
/* 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. */ /* Start. */
state_ = 0; state_ = 0;
looka_ = empty_; looka_ = empty_;
#if YYLSP_NEEDED
location = initlocation_; ]m4_ifdef([b4_initial_action], [
#endif m4_pushdef([b4_at_dollar], [location])dnl
YYCDEBUG << "Starting parse" << std::endl; 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 (0);
location_stack_ = LocationStack (0);
semantic_stack_.push (value);
location_stack_.push (location);
/* New state. */ /* New state. */
yynewstate: yynewstate:

View File

@@ -821,20 +821,23 @@ b4_c_function_def([yyparse], [int], b4_parse_param)
]b4_location_if([[ yylsp = yyls; ]b4_location_if([[ yylsp = yyls;
#if YYLTYPE_IS_TRIVIAL #if YYLTYPE_IS_TRIVIAL
/* Initialize the default location before parsing starts. */ /* Initialize the default location before parsing starts. */
yyls[0].first_line = yyls[0].last_line = 1; yylloc.first_line = yylloc.last_line = 1;
yyls[0].first_column = yyls[0].last_column = 0; yylloc.first_column = yylloc.last_column = 0;
#endif #endif
]]) ]])
m4_ifdef([b4_initial_action], [ m4_ifdef([b4_initial_action], [
m4_pushdef([b4_at_dollar], [(*yylsp)])dnl m4_pushdef([b4_at_dollar], [(yylloc)])dnl
m4_pushdef([b4_dollar_dollar], [(*yyvsp)])dnl m4_pushdef([b4_dollar_dollar], [(yylval)])dnl
/* User initialization code. */ /* User initialization code. */
b4_initial_action b4_initial_action
m4_popdef([b4_dollar_dollar])dnl m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])dnl m4_popdef([b4_at_dollar])dnl
/* Line __line__ of yacc.c. */ /* Line __line__ of yacc.c. */
b4_syncline([@oline@], [@ofile@])])dnl b4_syncline([@oline@], [@ofile@])])dnl
[
yyvsp[0] = yylval;
]b4_location_if([[ yylsp[0] = yylloc;
]])
[ goto yysetstate; [ goto yysetstate;
/*------------------------------------------------------------. /*------------------------------------------------------------.

View File

@@ -3742,10 +3742,21 @@ code.
@deffn {Directive} %initial-action @{ @var{code} @} @deffn {Directive} %initial-action @{ @var{code} @}
@findex %initial-action @findex %initial-action
Declare that the @var{code} must be invoked before parsing each time Declare that the @var{code} must be invoked before parsing each time
@code{yyparse} is called. The @var{code} may use @code{@@$} to @code{yyparse} is called. The @var{code} may use @code{$$} and
designate the initial location, and the @code{%parse-param}. @code{@@$} --- initial value and location of the look-ahead --- and the
@code{%parse-param}.
@end deffn @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 @node Destructor Decl
@subsection Freeing Discarded Symbols @subsection Freeing Discarded Symbols
@@ -3822,7 +3833,7 @@ stacked symbols popped during the first phase of error recovery,
@item @item
incoming terminals during the second phase of error recovery, incoming terminals during the second phase of error recovery,
@item @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). call to @code{YYABORT}, or as a consequence of a failed error recovery).
@end itemize @end itemize
@@ -5579,11 +5590,10 @@ constant integer. The default is 200.
@c FIXME: C++ output. @c FIXME: C++ output.
Because of semantical differences between C and C++, the Because of semantical differences between C and C++, the
@acronym{LALR}(1) parsers @acronym{LALR}(1) parsers in C produced by Bison by compiled as C++
in C produced by Bison by compiled as C++ cannot grow. In this precise cannot grow. In this precise case (compiling a C parser as C++) you are
case (compiling a C parser as C++) you are suggested to grow suggested to grow @code{YYINITDEPTH}. In the near future, a C++ output
@code{YYINITDEPTH}. In the near future, a C++ output output will be output will be provided which addresses this issue.
provided which addresses this issue.
@node Error Recovery @node Error Recovery
@chapter Error Recovery @chapter Error Recovery
@@ -6887,19 +6897,18 @@ $ @kbd{printf 'one\ntwo\n' | ./split-lines}
How can I generate parsers in C++? How can I generate parsers in C++?
@end display @end display
We are working on a C++ output for Bison, but unfortunately, for lack We are working on a C++ output for Bison, but unfortunately, for lack of
of time, the skeleton is not finished. It is functional, but in time, the skeleton is not finished. It is functional, but in numerous
numerous respects, it will require additional work which @emph{might} respects, it will require additional work which @emph{might} break
break backward compatibility. Since the skeleton for C++ is not backward compatibility. Since the skeleton for C++ is not documented,
documented, we do not consider ourselves bound to this interface, we do not consider ourselves bound to this interface, nevertheless, as
nevertheless, as much as possible we will try to keep compatibility. much as possible we will try to keep compatibility.
Another possibility is to use the regular C parsers, and to compile Another possibility is to use the regular C parsers, and to compile them
them with a C++ compiler. This works properly, provided that you bear with a C++ compiler. This works properly, provided that you bear some
some simple C++ rules in mind, such as not including ``real classes'' simple C++ rules in mind, such as not including ``real classes'' (i.e.,
(i.e., structure with constructors) in unions. Therefore, in the structure with constructors) in unions. Therefore, in the
@code{%union}, use pointers to classes, or better yet, a single @code{%union}, use pointers to classes.
pointer type to the root of your lexical/syntactic hierarchy.
@node Implementing Gotos/Loops @node Implementing Gotos/Loops

View File

@@ -327,7 +327,7 @@ static bool yydebug;
int int
yyparse () yyparse ()
{ {
yy::Parser parser (yydebug, yy::Location ()); yy::Parser parser (yydebug);
return parser.parse (); return parser.parse ();
} }
], ],

View File

@@ -144,7 +144,7 @@ yy::Parser::error_ ()
int int
yyparse (AT_PARAM_IF([semantic_value *result, int *count])) 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 (); return parser.parse ();
} }
], ],