Compare commits

...
Author SHA1 Message Date
Akim Demaille 2b63a84a5b lalr1.cc: provide %printer-based syntax-error messages.
* data/c++.m4: .
	* data/lalr1.cc: .
	* data/variant.hh: .
2009-08-26 13:33:33 +02:00
Akim Demaille a57ca64a80 lalr1.cc: pass the full lookahead to yysyntax_error_.
* data/lalr1.cc (yysyntax_error_): Instead of only taking the kind
	of the guilty token, take the full lookahead.
2009-08-26 13:25:11 +02:00
Akim Demaille 560d4c8dd9 lalr1.cc: minor changes.
* data/c++.m4: Space changes.
	* data/lalr1.cc (yysyntax_error_): Adjust signature.
2009-08-26 13:25:11 +02:00
Akim Demaille 911497f140 examples: fix variant.
* examples/variant.yy: Update to parse.assert and parse.trace.
2009-08-26 13:25:11 +02:00
4 changed files with 105 additions and 46 deletions
+72 -2
View File
@@ -148,6 +148,16 @@ m4_define([b4_public_types_declare],
[const semantic_type& v], [const semantic_type& v],
b4_locations_if([const location_type& l]))[); b4_locations_if([const location_type& l]))[);
/// Release the memory allocated to members.
/// Reclaim the semantic value using the %destructor directive.
void clear ();
/// Print the semantic value using the %printer directive.
std::ostream& print (std::ostream& o) const;
/// Print everything about the symbol (type, value, location).
std::ostream& dump (std::ostream& o) const;
/// Return this with its exact type. /// Return this with its exact type.
const Exact& self () const; const Exact& self () const;
Exact& self (); Exact& self ();
@@ -155,6 +165,11 @@ m4_define([b4_public_types_declare],
/// Return the type of this symbol. /// Return the type of this symbol.
int type_get () const; int type_get () const;
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
/// The name for the type.
const char *type_name () const;
#endif
/// The semantic value. /// The semantic value.
semantic_type value;]b4_locations_if([ semantic_type value;]b4_locations_if([
@@ -186,7 +201,7 @@ m4_define([b4_public_types_declare],
inline int type_get_ () const; inline int type_get_ () const;
/// Its token. /// Its token.
inline token_type token () const; token_type token () const;
}; };
]b4_symbol_constructor_declare]) ]b4_symbol_constructor_declare])
@@ -219,6 +234,53 @@ m4_define([b4_public_types_define],
{ {
} }
template <typename Exact>
void
]b4_parser_class_name[::symbol_base_type<Exact>::clear ()
{
int yytype = type_get ();
// User destructor.
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}]b4_variant_if([
// Type destructor.
b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
}
template <typename Exact>
std::ostream&
]b4_parser_class_name[::symbol_base_type<Exact>::print (std::ostream& yystream) const
{
#define debug_stream() yystream
switch (type_get ())
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
#undef debug_stream
return yystream;
}
template <typename Exact>
std::ostream&
]b4_parser_class_name[::symbol_base_type<Exact>::dump (std::ostream& yystream) const
{
int yytype = type_get ();
yystream << (yytype < yyntokens_ ? "token" : "nterm")
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
<< ' ' << type_name ()
#endif
<< " ("]b4_locations_if([
<< location << ": "])[;
print (yystream);
return yystream << ')';
}
template <typename Exact> template <typename Exact>
const Exact& const Exact&
]b4_parser_class_name[::symbol_base_type<Exact>::self () const ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
@@ -240,6 +302,14 @@ m4_define([b4_public_types_define],
return self ().type_get_ (); return self ().type_get_ ();
} }
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
template <typename Exact>
const char *
]b4_parser_class_name[::symbol_base_type<Exact>::type_name () const
{
return ]b4_parser_class_name[::yytname_[type_get ()];
}
#endif
// symbol_type. // symbol_type.
]b4_parser_class_name[::symbol_type::symbol_type () ]b4_parser_class_name[::symbol_type::symbol_type ()
: super_type () : super_type ()
@@ -310,7 +380,7 @@ m4_define([b4_yytranslate_define],
const token_number_type const token_number_type
translate_table[] = translate_table[] =
{ {
]b4_translate[ ]b4_translate[
}; };
const unsigned int user_token_number_max_ = ]b4_user_token_number_max[; const unsigned int user_token_number_max_ = ]b4_user_token_number_max[;
const token_number_type undef_token_ = ]b4_undef_token_number[; const token_number_type undef_token_ = ]b4_undef_token_number[;
+30 -41
View File
@@ -29,7 +29,7 @@ m4_define([b4_integral_parser_table_declare],
]) ])
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT) # b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
# --------------------------------------------- # -------------------------------------------------------------
# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT. # Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
m4_define([b4_integral_parser_table_define], m4_define([b4_integral_parser_table_define],
[ const b4_int_type_for([$2]) [ const b4_int_type_for([$2])
@@ -100,10 +100,10 @@ m4_define([b4_rhs_location],
m4_define([b4_symbol_action], m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2], [b4_symbol_if([$1], [has_$2],
[m4_pushdef([b4_dollar_dollar], [m4_pushdef([b4_dollar_dollar],
[b4_symbol_value_template([yysym.value], [b4_symbol_value_template([value],
b4_symbol_if([$1], [has_type], b4_symbol_if([$1], [has_type],
[b4_symbol([$1], [type])]))])dnl [b4_symbol([$1], [type])]))])dnl
m4_pushdef([b4_at_dollar], [yysym.location])dnl m4_pushdef([b4_at_dollar], [location])dnl
b4_symbol_case_([$1]) b4_symbol_case_([$1])
b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"]) b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
b4_symbol([$1], [$2]) b4_symbol([$1], [$2])
@@ -147,8 +147,9 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_percent_code_get([[requires]])[ ]b4_percent_code_get([[requires]])[
]b4_parse_assert_if([#include <cassert>])[ ]b4_parse_assert_if([#include <cassert>])[
#include <string>
#include <iostream> #include <iostream>
#include <string>
#include <sstream>
#include "stack.hh" #include "stack.hh"
]b4_namespace_open[ ]b4_namespace_open[
@@ -237,8 +238,9 @@ do { \
/// Generate an error message. /// Generate an error message.
/// \param yystate the state where the error occurred. /// \param yystate the state where the error occurred.
/// \param yytoken the lookahead token. /// \param yyla the (invalid) lookahead token.
virtual std::string yysyntax_error_ (state_type yystate, int yytoken); virtual std::string yysyntax_error_ (state_type yystate,
const symbol_type& yyla);
/// Compute post-reduction state. /// Compute post-reduction state.
/// \param yystate the current state /// \param yystate the current state
@@ -267,7 +269,7 @@ do { \
#endif]b4_error_verbose_if([ #endif]b4_error_verbose_if([
/// Convert the symbol name \a n to a form suitable for a diagnostic. /// Convert the symbol name \a n to a form suitable for a diagnostic.
static std::string yytnamerr_ (const char *n);])[ static std::string yytnamerr_ (const std::string& n);])[
#if YYDEBUG #if YYDEBUG
]b4_integral_parser_table_declare([rline], [b4_rline], ]b4_integral_parser_table_declare([rline], [b4_rline],
@@ -364,8 +366,7 @@ do { \
]b4_parse_param_vars[ ]b4_parse_param_vars[
}; };
]b4_lex_symbol_if([b4_yytranslate_define ]b4_lex_symbol_if([b4_yytranslate_define])[
b4_public_types_define])[
]b4_namespace_close[ ]b4_namespace_close[
]b4_percent_define_flag_if([[global_tokens_and_yystype]], ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
@@ -464,12 +465,12 @@ b4_percent_code_get[]dnl
apostrophe, a comma, or backslash (other than backslash-backslash). apostrophe, a comma, or backslash (other than backslash-backslash).
YYSTR is taken from yytname. */ YYSTR is taken from yytname. */
std::string std::string
]b4_parser_class_name[::yytnamerr_ (const char *yystr) ]b4_parser_class_name[::yytnamerr_ (const std::string& yystr)
{ {
if (*yystr == '"') if (yystr[0] == '"')
{ {
std::string yyr = ""; std::string yyr = "";
char const *yyp = yystr; char const *yyp = yystr.c_str ();
for (;;) for (;;)
switch (*++yyp) switch (*++yyp)
@@ -496,6 +497,8 @@ b4_percent_code_get[]dnl
} }
]])[ ]])[
]b4_lex_symbol_if([b4_public_types_define])[
/// Build a parser object. /// Build a parser object.
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [ ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
:])[ :])[
@@ -545,21 +548,9 @@ b4_percent_code_get[]dnl
]b4_parser_class_name[::yy_destroy_ (const char* yymsg, ]b4_parser_class_name[::yy_destroy_ (const char* yymsg,
symbol_base_type<Exact>& yysym) const symbol_base_type<Exact>& yysym) const
{ {
int yytype = yysym.type_get ();
YYUSE (yymsg);
if (yymsg) if (yymsg)
YY_SYMBOL_PRINT (yymsg, yysym); YY_SYMBOL_PRINT (yymsg, yysym);
yysym.clear ();
// User destructor.
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}]b4_variant_if([
// Type destructor.
b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[
} }
#if YYDEBUG #if YYDEBUG
@@ -568,17 +559,7 @@ b4_percent_code_get[]dnl
]b4_parser_class_name[::yy_print_ (std::ostream& yyo, ]b4_parser_class_name[::yy_print_ (std::ostream& yyo,
const symbol_base_type<Exact>& yysym) const const symbol_base_type<Exact>& yysym) const
{ {
int yytype = yysym.type_get (); yysym.dump (yyo);
yyo << (yytype < yyntokens_ ? "token" : "nterm")
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([
<< yysym.location << ": "])[;
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
yyo << ')';
} }
#endif #endif
@@ -853,7 +834,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
{ {
++yynerrs_; ++yynerrs_;
error (]b4_args(b4_locations_if([yyla.location]), error (]b4_args(b4_locations_if([yyla.location]),
[[yysyntax_error_ (yystack_[0].state, yyla.type)]])[); [[yysyntax_error_ (yystack_[0].state, yyla)]])[);
} }
]b4_locations_if([[ ]b4_locations_if([[
@@ -966,8 +947,8 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
// Generate an error message. // Generate an error message.
std::string std::string
]b4_parser_class_name[::yysyntax_error_ (]dnl ]b4_parser_class_name[::yysyntax_error_ (]dnl
b4_error_verbose_if([state_type yystate, int yytoken], b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
[int, int])[) [state_type, const symbol_type&])[)
{ {
std::string yyres;]b4_error_verbose_if([[ std::string yyres;]b4_error_verbose_if([[
int yyn = yypact_[yystate]; int yyn = yypact_[yystate];
@@ -989,7 +970,8 @@ b4_error_verbose_if([state_type yystate, int yytoken],
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
// Arguments of yyformat. // Arguments of yyformat.
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
yyarg[yycount++] = yytname_[yytoken]; // The unexpected token.
yyarg[yycount++] = yytname_[yyla.type_get ()];
for (int yyx = yyxbegin; yyx < yyxend; ++yyx) for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_ if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
&& !yy_table_value_is_error_ (yytable_[yyx + yyn])) && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
@@ -1019,10 +1001,17 @@ b4_error_verbose_if([state_type yystate, int yytoken],
} }
// Argument number. // Argument number.
size_t yyi = 0; size_t yyi = 0;
// The unexpected token. Try to print its value.
std::ostringstream yyo;
yyla.print (yyo);
for (char const* yyp = yyformat; *yyp; ++yyp) for (char const* yyp = yyformat; *yyp; ++yyp)
if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount) if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
{ {
yyres += yytnamerr_ (yyarg[yyi++]); if (!yyi && !yyo.str ().empty ())
yyres += yyo.str ();
else
yyres += yytnamerr_ (yyarg[yyi]);
++yyi;
++yyp; ++yyp;
} }
else else
+1 -1
View File
@@ -231,7 +231,7 @@ m4_define([b4_symbol_value_template],
# these SYMBOL-NUMBERS. Use at class-level. # these SYMBOL-NUMBERS. Use at class-level.
m4_define([b4_symbol_constructor_declare_], m4_define([b4_symbol_constructor_declare_],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id], [b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ static inline [ static // inline
symbol_type symbol_type
make_[]b4_symbol_([$1], [id]) (dnl make_[]b4_symbol_([$1], [id]) (dnl
b4_args(b4_symbol_if([$1], [has_type], b4_args(b4_symbol_if([$1], [has_type],
+2 -2
View File
@@ -1,7 +1,7 @@
%debug
%skeleton "lalr1.cc" %skeleton "lalr1.cc"
%defines %defines
%define assert %define parse.assert
%define parse.trace
%define variant %define variant
%define lex_symbol %define lex_symbol
%locations %locations