diff --git a/ChangeLog b/ChangeLog index 572ebdc2..02d15de9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-09-09 Akim Demaille + + lalr1.cc: syntax_error as exceptions. + It is common to use sort of factories in the user actions. These + factories may check some "syntactic" constraints that are not + enforced by the grammar itself. This is possible using YYERROR + within the action itself. Provide the user with a means to throw + a syntax_error exception. + + * data/c++.m4 (b4_public_types_declare, b4_public_types_define): + Declare and define yy::parser::syntax_error. + * data/lalr1.cc: Include stdexcept. + (yy::parser::parse): Wrap the user action within a try/catch. + * data/glr.cc: Include stdexcept. + 2009-09-09 Akim Demaille lalr1.cc: add missing "inline". diff --git a/data/c++.m4 b/data/c++.m4 index cfe8a6cb..3157e47b 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -126,6 +126,13 @@ m4_define([b4_public_types_declare], /// Symbol locations. typedef b4_percent_define_get([[location_type]]) location_type;])[ + /// Syntax errors thrown from user actions. + struct syntax_error : std::runtime_error + { + syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m);]b4_locations_if([ + location_type location;])[ + }; + /// Tokens. struct token { @@ -195,8 +202,15 @@ m4_define([b4_public_types_declare], # ---------------------- # Provide the implementation needed by the public types. m4_define([b4_public_types_define], -[[ // symbol_base_type. +[[ inline + ]b4_parser_class_name[::syntax_error::syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m) + : std::runtime_error (m)]b4_locations_if([ + , location (l)])[ + {} + + // symbol_base_type. template + inline ]b4_parser_class_name[::symbol_base_type::symbol_base_type () : value()]b4_locations_if([ , location()])[ diff --git a/data/glr.cc b/data/glr.cc index 0d9e0496..87e3eab1 100644 --- a/data/glr.cc +++ b/data/glr.cc @@ -224,6 +224,7 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C++], ]b4_percent_code_get([[requires]])[ +#include #include #include diff --git a/data/lalr1.cc b/data/lalr1.cc index 8e79333e..ac2fa35b 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -147,6 +147,7 @@ dnl FIXME: This is wrong, we want computed header guards. ]b4_percent_code_get([[requires]])[ ]b4_parse_assert_if([#include ])[ +#include #include #include #include "stack.hh" @@ -814,12 +815,21 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ // Perform the reduction. YY_REDUCE_PRINT (yyn); - switch (yyn) + try + { + switch (yyn) { ]b4_user_actions[ default: break; } + } + catch (const syntax_error& yyexc) + { + error (]b4_args(b4_locations_if([yyexc.location]), + [[yyexc.what()]])[); + YYERROR; + } YY_SYMBOL_PRINT ("-> $$ =", yylhs); ]b4_variant_if([[ // Destroy the rhs symbols.