summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <demaille@gostai.com>2009-08-26 11:16:04 +0200
committerAkim Demaille <demaille@gostai.com>2009-08-26 13:33:33 +0200
commit2b63a84a5b931e8821b59eef23acd13f68d1a9c9 (patch)
treedfbfbcd49332a6acb8050bdbd353822361279368
parenta57ca64a80b6823e329237558c92295b6604b286 (diff)
downloadbison-candidates/semantic-error-messages.tar.gz
lalr1.cc: provide %printer-based syntax-error messages.candidates/semantic-error-messages
* data/c++.m4: . * data/lalr1.cc: . * data/variant.hh: .
-rw-r--r--data/c++.m472
-rw-r--r--data/lalr1.cc57
-rw-r--r--data/variant.hh2
3 files changed, 94 insertions, 37 deletions
diff --git a/data/c++.m4 b/data/c++.m4
index 92c2c5ed..b8e1772a 100644
--- a/data/c++.m4
+++ b/data/c++.m4
@@ -148,6 +148,16 @@ m4_define([b4_public_types_declare],
[const semantic_type& v],
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.
const Exact& self () const;
Exact& self ();
@@ -155,6 +165,11 @@ m4_define([b4_public_types_declare],
/// Return the type of this symbol.
int type_get () const;
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+ /// The name for the type.
+ const char *type_name () const;
+#endif
+
/// The semantic value.
semantic_type value;]b4_locations_if([
@@ -186,7 +201,7 @@ m4_define([b4_public_types_declare],
inline int type_get_ () const;
/// Its token.
- inline token_type token () const;
+ token_type token () const;
};
]b4_symbol_constructor_declare])
@@ -220,6 +235,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>
const Exact&
]b4_parser_class_name[::symbol_base_type<Exact>::self () const
{
@@ -240,6 +302,14 @@ m4_define([b4_public_types_define],
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.
]b4_parser_class_name[::symbol_type::symbol_type ()
: super_type ()
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 5ad33287..07372585 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -29,7 +29,7 @@ m4_define([b4_integral_parser_table_declare],
])
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
-# ---------------------------------------------
+# -------------------------------------------------------------
# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
m4_define([b4_integral_parser_table_define],
[ const b4_int_type_for([$2])
@@ -100,10 +100,10 @@ m4_define([b4_rhs_location],
m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2],
[m4_pushdef([b4_dollar_dollar],
- [b4_symbol_value_template([yysym.value],
+ [b4_symbol_value_template([value],
b4_symbol_if([$1], [has_type],
[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_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
b4_symbol([$1], [$2])
@@ -147,8 +147,9 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_percent_code_get([[requires]])[
]b4_parse_assert_if([#include <cassert>])[
-#include <string>
#include <iostream>
+#include <string>
+#include <sstream>
#include "stack.hh"
]b4_namespace_open[
@@ -268,7 +269,7 @@ do { \
#endif]b4_error_verbose_if([
/// 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
]b4_integral_parser_table_declare([rline], [b4_rline],
@@ -365,8 +366,7 @@ do { \
]b4_parse_param_vars[
};
-]b4_lex_symbol_if([b4_yytranslate_define
-b4_public_types_define])[
+]b4_lex_symbol_if([b4_yytranslate_define])[
]b4_namespace_close[
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
@@ -465,12 +465,12 @@ b4_percent_code_get[]dnl
apostrophe, a comma, or backslash (other than backslash-backslash).
YYSTR is taken from yytname. */
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 = "";
- char const *yyp = yystr;
+ char const *yyp = yystr.c_str ();
for (;;)
switch (*++yyp)
@@ -497,6 +497,8 @@ b4_percent_code_get[]dnl
}
]])[
+]b4_lex_symbol_if([b4_public_types_define])[
+
/// Build a parser object.
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
:])[
@@ -546,21 +548,9 @@ b4_percent_code_get[]dnl
]b4_parser_class_name[::yy_destroy_ (const char* yymsg,
symbol_base_type<Exact>& yysym) const
{
- int yytype = yysym.type_get ();
- YYUSE (yymsg);
if (yymsg)
YY_SYMBOL_PRINT (yymsg, yysym);
-
- // 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]])])[
+ yysym.clear ();
}
#if YYDEBUG
@@ -569,17 +559,7 @@ b4_percent_code_get[]dnl
]b4_parser_class_name[::yy_print_ (std::ostream& yyo,
const symbol_base_type<Exact>& yysym) const
{
- int yytype = yysym.type_get ();
- yyo << (yytype < yyntokens_ ? "token" : "nterm")
- << ' ' << yytname_[yytype] << " ("]b4_locations_if([
- << yysym.location << ": "])[;
- switch (yytype)
- {
-]b4_symbol_foreach([b4_symbol_printer])dnl
-[ default:
- break;
- }
- yyo << ')';
+ yysym.dump (yyo);
}
#endif
@@ -1021,10 +1001,17 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
}
// Argument number.
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)
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;
}
else
diff --git a/data/variant.hh b/data/variant.hh
index ae26f5b8..10ce56c0 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -231,7 +231,7 @@ m4_define([b4_symbol_value_template],
# these SYMBOL-NUMBERS. Use at class-level.
m4_define([b4_symbol_constructor_declare_],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
-[ static inline
+[ static // inline
symbol_type
make_[]b4_symbol_([$1], [id]) (dnl
b4_args(b4_symbol_if([$1], [has_type],