mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
lalr1.cc: also handle syntax_error when calling yylex.
* data/lalr1.cc (parse): Catch syntax_error around yylex and forward them to errlab1. * tests/c++.at (Syntax error as exception): Check support for syntax exceptions raised by the scanner. * NEWS, doc/bison.texinfo: Document it.
This commit is contained in:
9
NEWS
9
NEWS
@@ -24,6 +24,15 @@ Bison News
|
||||
Also, it is possible to add code to the parser's constructors using
|
||||
"%code init" and "%define init_throws".
|
||||
|
||||
** C++ skeleton improvements
|
||||
|
||||
The C++ parser features a syntax_error exception, which can be
|
||||
thrown from the scanner or from user rules to raise syntax errors.
|
||||
This facilitates reporting errors caught in sub-functions (e.g.,
|
||||
rejecting too large integral literals from a conversion function
|
||||
used by the scanner, or rejecting invalid combinations from a
|
||||
factory invoked by the user actions).
|
||||
|
||||
** Variable api.tokens.prefix
|
||||
|
||||
The variable api.tokens.prefix changes the way tokens are identified in
|
||||
|
||||
@@ -209,6 +209,9 @@ b4_namespace_close])[
|
||||
/// \param msg a description of the syntax error.
|
||||
virtual void error (]b4_locations_if([const location_type& loc, ])[const std::string& msg);
|
||||
|
||||
/// Report a syntax error.
|
||||
void error (const syntax_error& err);
|
||||
|
||||
private:
|
||||
/// State numbers.
|
||||
typedef int state_type;
|
||||
@@ -734,13 +737,21 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
if (yyempty)
|
||||
{
|
||||
YYCDEBUG << "Reading a token: ";
|
||||
try
|
||||
{
|
||||
]b4_lex_symbol_if(
|
||||
[ yyla = b4_c_function_call([yylex], [symbol_type],
|
||||
m4_ifdef([b4_lex_param], b4_lex_param));],
|
||||
[ yyla.type = yytranslate_ (b4_c_function_call([yylex], [int],
|
||||
[ yyla = b4_c_function_call([yylex], [symbol_type],
|
||||
m4_ifdef([b4_lex_param], b4_lex_param));],
|
||||
[ yyla.type = yytranslate_ (b4_c_function_call([yylex], [int],
|
||||
[[YYSTYPE*], [&yyla.value]][]dnl
|
||||
b4_locations_if([, [[location*], [&yyla.location]]])dnl
|
||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
|
||||
}
|
||||
catch (const syntax_error& yyexc)
|
||||
{
|
||||
error (yyexc);
|
||||
goto yyerrlab1;
|
||||
}
|
||||
yyempty = false;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("Next token is", yyla);
|
||||
@@ -823,8 +834,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
|
||||
}
|
||||
catch (const syntax_error& yyexc)
|
||||
{
|
||||
error (]b4_args(b4_locations_if([yyexc.location]),
|
||||
[[yyexc.what()]])[);
|
||||
error (yyexc);
|
||||
YYERROR;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
|
||||
@@ -971,6 +981,13 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
|
||||
return yyresult;
|
||||
}
|
||||
|
||||
void
|
||||
]b4_parser_class_name[::error (const syntax_error& yyexc)
|
||||
{
|
||||
error (]b4_args(b4_locations_if([yyexc.location]),
|
||||
[[yyexc.what()]])[);
|
||||
}
|
||||
|
||||
// Generate an error message.
|
||||
std::string
|
||||
]b4_parser_class_name[::yysyntax_error_ (]dnl
|
||||
|
||||
@@ -9270,7 +9270,8 @@ scanner should use @code{yy::parser::token::FOO}. The scanner can use
|
||||
|
||||
@defcv {Type} {parser} {syntax_error}
|
||||
This class derives from @code{std::runtime_error}. Throw instances of it
|
||||
from user actions to raise parse errors. This is equivalent with first
|
||||
from the scanner or from the user actions to raise parse errors. This is
|
||||
equivalent with first
|
||||
invoking @code{error} to report the location and message of the syntax
|
||||
error, and then to invoke @code{YYERROR} to enter the error-recovery mode.
|
||||
But contrary to @code{YYERROR} which can only be invoked from user actions
|
||||
|
||||
@@ -492,9 +492,12 @@ item:
|
||||
int
|
||||
yylex (yy::parser::semantic_type *)
|
||||
{
|
||||
static char const *input = "as";
|
||||
// 's': syntax error, 'l': lexical error.
|
||||
static char const *input = "asal";
|
||||
switch (int res = *input++)
|
||||
{
|
||||
case 'l':
|
||||
throw yy::parser::syntax_error("invalid character");
|
||||
default:
|
||||
return res;
|
||||
}
|
||||
@@ -520,6 +523,8 @@ AT_COMPILE_CXX([[input]])
|
||||
AT_PARSER_CHECK([[./input]], [[0]], [[]],
|
||||
[[error: invalid expression
|
||||
caught error
|
||||
error: invalid character
|
||||
caught error
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
Reference in New Issue
Block a user