[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 7/9] lalr1.cc: check (and fix) %printer exception safety
From: |
Akim Demaille |
Subject: |
[PATCH 7/9] lalr1.cc: check (and fix) %printer exception safety |
Date: |
Tue, 2 Oct 2012 19:11:12 +0200 |
* tests/c++.at (Exception safety): Let the parser support the --debug
option.
On 'p', throw an exception from the %printer.
* data/lalr1.cc (yyparse): Do not display the values we discard, as it
uses %printer, which might have thrown the exception.
---
data/lalr1.cc | 14 +++++++++-----
tests/c++.at | 47 +++++++++++++++++++++++++++++++++++------------
2 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 2ec1d0d..3b8c921 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -227,6 +227,7 @@ b4_user_stype
/// \brief Reclaim the memory associated to a symbol.
/// \param yymsg Why this token is reclaimed.
+ /// If null, do not display the symbol, just free it.
/// \param yytype The symbol type.
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
@@ -446,7 +447,8 @@ do { \
YYUSE (yymsg);
YYUSE (yyvaluep);
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+ if (yymsg)
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
switch (yytype)
{
@@ -841,20 +843,22 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
}
catch (...)
{
- YYCDEBUG << "Exception caught" << std::endl;
+ YYCDEBUG << "Exception caught: cleaning lookahead and stack"
+ << std::endl;
+ // Do not try to display the values of the reclaimed symbols,
+ // as their printer might throw an exception.
if (yychar != yyempty_)
{
/* Make sure we have latest lookahead translation. See
comments at user semantic actions for why this is
necessary. */
yytoken = yytranslate_ (yychar);
- yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval,
- &yylloc);
+ yydestruct_ (YY_NULL, yytoken, &yylval, &yylloc);
}
while (1 < yystate_stack_.height ())
{
- yydestruct_ ("Cleanup: popping",
+ yydestruct_ (YY_NULL,
yystos_[yystate_stack_[0]],
&yysemantic_stack_[0],
&yylocation_stack_[0]);
diff --git a/tests/c++.at b/tests/c++.at
index e4a7911..9a60bfd 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -203,11 +203,14 @@ AT_DATA_GRAMMAR([[input.yy]],
int debug = 0;
+ /// A class that counts its number of instances.
struct Object
{
static size_t counter;
+ int val;
- Object ()
+ Object (int v)
+ : val (v)
{
++counter;
if (debug)
@@ -245,9 +248,14 @@ AT_DATA_GRAMMAR([[input.yy]],
}
%destructor { delete $$; } <obj>;
-%printer { yyo << "counter == " << $$->counter; } <obj>;
+%printer
+{
+ yyo << "counter == " << $$->counter;
+ if ($$->val == 'p')
+ throw std::runtime_error ("printer");
+} <obj>;
-%token <obj> 'a' 's'
+%token <obj> 'a' 'p' 's'
%type <obj> list item
%%
@@ -256,14 +264,12 @@ start: list { delete $1; };
list:
item { $$ = $1; }
-| item list { $$ = $1; delete $2; } /* Right recursion to load the stack. */
+| item list { $$ = $1; delete $2; } // Right recursion to load the stack.
;
item:
- 'a'
- {
- std::swap ($$, $1);
- }
+ 'a' { std::swap ($$, $1); }
+| 'p' { std::swap ($$, $1); }
| 's'
{
std::swap ($$, $1);
@@ -284,7 +290,7 @@ yylex (yy::parser::semantic_type *lvalp)
case 'l':
throw std::runtime_error ("yylex");
default:
- lvalp->obj = new Object;
+ lvalp->obj = new Object (res);
// Fall through.
case 0:
return res;
@@ -296,10 +302,22 @@ yylex (yy::parser::semantic_type *lvalp)
int
main (int argc, const char *argv[])
{
- assert (argc == 2);
- input = argv[1];
+ switch (argc)
+ {
+ case 2:
+ input = argv[1];
+ break;
+ case 3:
+ assert (!strcmp (argv[1], "--debug"));
+ debug = 1;
+ input = argv[2];
+ break;
+ default:
+ abort ();
+ }
+
yy::parser parser;
- debug = !!getenv ("YYDEBUG");
+ debug |= !!getenv ("YYDEBUG");
parser.set_debug_level (debug);
int res = 2;
try
@@ -333,6 +351,11 @@ AT_PARSER_CHECK([[./input i]], [[2]], [[]],
[[exception caught: initial-action
]])
+AT_PARSER_CHECK([[./input aaaap]])
+
+AT_PARSER_CHECK([[./input --debug aaaap]], [[2]], [[]], [[stderr]])
+AT_PARSER_CHECK([[grep '^exception caught: printer$' stderr]], [], [ignore])
+
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
--
1.7.12.2
- [PATCH 0/9] {maint} lalr1.cc: exception safety, Akim Demaille, 2012/10/02
- [PATCH 4/9] lalr1.cc: check exception safety., Akim Demaille, 2012/10/02
- [PATCH 7/9] lalr1.cc: check (and fix) %printer exception safety,
Akim Demaille <=
- [PATCH 6/9] lalr1.cc: check (and fix) %initial-action exception safety, Akim Demaille, 2012/10/02
- [PATCH 1/9] tests: minor improvements, Akim Demaille, 2012/10/02
- [PATCH 8/9] lalr1.cc: check exception safety of yyerror, Akim Demaille, 2012/10/02
- [PATCH 5/9] lalr1.cc: fix exception safety, Akim Demaille, 2012/10/02
- [PATCH 2/9] lalr1.cc: don't leave macros define to nothing, Akim Demaille, 2012/10/02
- [PATCH 3/9] lalr1.cc: indentation fixes., Akim Demaille, 2012/10/02
- [PATCH 9/9] lalr1.cc: document exception safety, Akim Demaille, 2012/10/02
- Re: [PATCH 0/9] {maint} lalr1.cc: exception safety, Akim Demaille, 2012/10/03