mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-15 15:23:02 +00:00
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.
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
2009-12-18 Joel E. Denny <jdenny@clemson.edu>
|
||||||
|
|
||||||
|
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 <jdenny@clemson.edu>
|
2009-12-17 Joel E. Denny <jdenny@clemson.edu>
|
||||||
|
|
||||||
Code cleanup.
|
Code cleanup.
|
||||||
|
|||||||
@@ -876,7 +876,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
|
|||||||
/* Return failure if at end of input. */
|
/* Return failure if at end of input. */
|
||||||
if (yyla.type == yyeof_)
|
if (yyla.type == yyeof_)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
else
|
else if (!yyempty)
|
||||||
{
|
{
|
||||||
yy_destroy_ ("Error: discarding", yyla);
|
yy_destroy_ ("Error: discarding", yyla);
|
||||||
yyempty = true;
|
yyempty = true;
|
||||||
|
|||||||
79
tests/c++.at
79
tests/c++.at
@@ -286,8 +286,6 @@ AT_CHECK_DOXYGEN([Public])
|
|||||||
AT_CHECK_DOXYGEN([Private])
|
AT_CHECK_DOXYGEN([Private])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ------------ ##
|
## ------------ ##
|
||||||
## Namespaces. ##
|
## Namespaces. ##
|
||||||
## ------------ ##
|
## ------------ ##
|
||||||
@@ -369,3 +367,80 @@ AT_CHECK_NAMESPACE([[foo[3]::bar::baz]], [[-]])
|
|||||||
AT_CHECK_NAMESPACE([[foo::bar,baz]], [[-]])
|
AT_CHECK_NAMESPACE([[foo::bar,baz]], [[-]])
|
||||||
AT_CHECK_NAMESPACE([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
|
AT_CHECK_NAMESPACE([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
|
||||||
AT_CLEANUP
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user