From ff601366544d2cb2218c80e37083a88c6102061c Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 8 Sep 2009 22:00:13 +0200 Subject: [PATCH] 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 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. -- 2.45.2