From ff601366544d2cb2218c80e37083a88c6102061c Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 8 Sep 2009 22:00:13 +0200 Subject: [PATCH 2/2] 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. --- ChangeLog | 15 +++++++++++++++ data/c++.m4 | 16 +++++++++++++++- data/glr.cc | 1 + data/lalr1.cc | 12 +++++++++++- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 572ebdc..02d15de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 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". * data/c++.m4 (b4_public_types_define): Add missing inline to implementations provided in headers. diff --git a/data/c++.m4 b/data/c++.m4 index cfe8a6c..3157e47 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 0d9e049..87e3eab 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 8e79333..ac2fa35 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. -- 1.6.4