[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] lalr1.cc: don't discard non-existent lookahead on syntax error.
From: |
Joel E. Denny |
Subject: |
[PATCH] lalr1.cc: don't discard non-existent lookahead on syntax error. |
Date: |
Sat, 19 Dec 2009 00:18:22 -0500 (EST) |
User-agent: |
Alpine 1.00 (DEB 882 2007-12-20) |
I pushed this to master. The bug does not exist on branch-2.5. The test
case makes this bug look pretty obscure, and maybe that's right, but I
really didn't spend much time searching for a simpler test case.
>From d59beda068aef97834ea84ce4f5cc99b487e4b68 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Fri, 18 Dec 2009 23:57:18 -0500
Subject: [PATCH] lalr1.cc: don't discard non-existent lookahead on syntax error.
* data/lalr1.cc (parser::parse): Check yyempty first.
* tests/c++.at (Syntax error discarding no lookahead): New test
group.
---
ChangeLog | 7 +++++
data/lalr1.cc | 2 +-
tests/c++.at | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2926da7..1c15cc5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-12-18 Joel E. Denny <address@hidden>
+
+ lalr1.cc: don't discard non-existent lookahead on syntax error.
+ * data/lalr1.cc (parser::parse): Check yyempty first.
+ * tests/c++.at (Syntax error discarding no lookahead): New test
+ group.
+
2009-12-17 Joel E. Denny <address@hidden>
Code cleanup.
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 9e0d522..6174e82 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -876,7 +876,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
/* Return failure if at end of input. */
if (yyla.type == yyeof_)
YYABORT;
- else
+ else if (!yyempty)
{
yy_destroy_ ("Error: discarding", yyla);
yyempty = true;
diff --git a/tests/c++.at b/tests/c++.at
index beffb1c..ce64d6d 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -286,8 +286,6 @@ AT_CHECK_DOXYGEN([Public])
AT_CHECK_DOXYGEN([Private])
-
-
## ------------ ##
## Namespaces. ##
## ------------ ##
@@ -369,3 +367,80 @@ AT_CHECK_NAMESPACE([[foo[3]::bar::baz]], [[-]])
AT_CHECK_NAMESPACE([[foo::bar,baz]], [[-]])
AT_CHECK_NAMESPACE([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
AT_CLEANUP
+
+
+## -------------------------------------- ##
+## Syntax error discarding no lookahead. ##
+## -------------------------------------- ##
+
+# After a syntax error, lalr1.cc used to not check whether there
+# actually is a lookahead before discarding the lookahead. As a result,
+# it mistakenly invoked the destructor for the previous lookahead.
+
+AT_SETUP([[Syntax error discarding no lookahead]])
+
+AT_DATA_GRAMMAR([[input.yy]],
+[[%skeleton "lalr1.cc"
+
+%code {
+ #include <string>
+ int yylex (yy::parser::semantic_type *, yy::location *);
+ #define USE(Args)
+}
+
+%defines
+%locations
+%define parse.error verbose
+
+%nonassoc 'a' ;
+
+%destructor {
+ std::cerr << "Discarding 'a'." << std::endl;
+} 'a'
+
+%%
+
+start: error-reduce consistent-error 'a' { USE ($3); };
+
+error-reduce:
+ 'a' 'a' consistent-error 'a' { USE (($1, $2, $4)); }
+| 'a' error { std::cerr << "Reducing 'a'." << std::endl; USE ($1); }
+;
+
+consistent-error:
+ 'a'
+| /*empty*/ %prec 'a'
+;
+
+%%
+
+int
+yylex (yy::parser::semantic_type *, yy::location *)
+{
+ static char const *input = "aa";
+ return *input++;
+}
+
+void
+yy::parser::error (const location_type &, const std::string &m)
+{
+ std::cerr << m << std::endl;
+}
+
+int
+main (void)
+{
+ yy::parser parser;
+ return parser.parse ();
+}
+]])
+AT_BISON_CHECK([[-o input.cc input.yy]], [[0]], [[]], [[ignore-nolog]])
+AT_COMPILE_CXX([[input]])
+# This used to print "Discarding 'a'." again at the end.
+AT_PARSER_CHECK([[./input]], [[1]], [[]],
+[[syntax error
+Discarding 'a'.
+Reducing 'a'.
+]])
+
+AT_CLEANUP
--
1.5.4.3
- [PATCH] lalr1.cc: don't discard non-existent lookahead on syntax error.,
Joel E. Denny <=