From 2ea7730c5640c6a987dce6907363e96fc65c071b Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 25 Aug 2008 13:52:51 +0200 Subject: [PATCH] Locations are no longer required by lalr1.cc. * data/lalr1.cc (_b4_args, b4_args): New. Adjust all uses of locations to make them optional. * tests/c++.at (AT_CHECK_VARIANTS): No longer use the locations. (AT_CHECK_NAMESPACE): Check the use of locations. * tests/calc.at (_AT_DATA_CALC_Y): Adjust to be usable with or without locations with lalr1.cc. Test these cases. * tests/output.at: Check lalr1.cc with and without location support. * tests/regression.at (_AT_DATA_EXPECT2_Y, _AT_DATA_DANCER_Y): Don't use locations. --- ChangeLog | 15 ++++ data/lalr1.cc | 182 ++++++++++++++++++++++++++++---------------- tests/c++.at | 8 +- tests/calc.at | 22 +++--- tests/output.at | 16 +++- tests/regression.at | 4 +- 6 files changed, 160 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index d9a7b2e8..d5d38001 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-11-11 Akim Demaille + + Locations are no longer required by lalr1.cc. + * data/lalr1.cc (_b4_args, b4_args): New. + Adjust all uses of locations to make them optional. + * tests/c++.at (AT_CHECK_VARIANTS): No longer use the locations. + (AT_CHECK_NAMESPACE): Check the use of locations. + * tests/calc.at (_AT_DATA_CALC_Y): Adjust to be usable with or + without locations with lalr1.cc. + Test these cases. + * tests/output.at: Check lalr1.cc with and without location + support. + * tests/regression.at (_AT_DATA_EXPECT2_Y, _AT_DATA_DANCER_Y): + Don't use locations. + 2008-11-11 Akim Demaille AT_FULL_COMPILE. diff --git a/data/lalr1.cc b/data/lalr1.cc index 056c6bd0..fd5e5ec8 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -18,6 +18,29 @@ m4_include(b4_pkgdatadir/[c++.m4]) + +# b4_args(ARG1, ...) +# _b4_args(ARG1, ...) +# ------------------- +# Join with comma, skipping empty arguments. +# b4_args calls itself recursively until it sees the first non-empty +# argument, then calls _b4_args which prepends each non-empty argument +# with a comma. +m4_define([b4_args], +[m4_if([$#$1], + [1], [], + [m4_ifval([$1], + [$1[]_$0(m4_shift($@))], + [$0(m4_shift($@))])])]) + +# _b4_args(ARGS1, ...) +# -------------------- +m4_define([_b4_args], +[m4_if([$#$1], + [1], [], + [m4_ifval([$1], [, $1])[]$0(m4_shift($@))])]) + + # b4_table_define(TABLE-NAME, CONTENT) # ------------------------------------ # Define "parser::yy_" which contents is CONTENT. @@ -179,9 +202,9 @@ m4_define([b4_type_action_], m4_define([b4_symbol_constructor_declaration_], [ template static inline symbol_type - make_symbol (b4_symbol_if([$1], [has_type_name], - [const b4_symbol([$1], [type_name])& v, ])dnl -const location_type& l); + make_symbol (b4_args(b4_symbol_if([$1], [has_type_name], + [const b4_symbol([$1], [type_name])& v]), + b4_locations_if([const location_type& l]))); ]) @@ -207,9 +230,9 @@ m4_define([b4_symbol_constructor_specialization_], inline b4_parser_class_name::symbol_type b4_parser_class_name::make_symbol (dnl -b4_symbol_if([$1], [has_type_name], - [const b4_symbol([$1], [type_name])& v, ])dnl -const b4_parser_class_name::location_type& l); +b4_args(b4_symbol_if([$1], [has_type_name], + [const b4_symbol([$1], [type_name])& v]), + b4_locations_if([const b4_parser_class_name::location_type& l]))); ])])]) # b4_symbol_constructor_specializations @@ -232,12 +255,13 @@ m4_define([b4_symbol_constructor_definition_], [ template <> b4_parser_class_name::symbol_type b4_parser_class_name::make_symbol (dnl -b4_symbol_if([$1], [has_type_name], - [const b4_symbol([$1], [type_name])& v, ])dnl -const location_type& l) +b4_args(b4_symbol_if([$1], [has_type_name], + [const b4_symbol([$1], [type_name])& v]), + b4_locations_if([const location_type& l]))) { - return symbol_type (yytranslate_ (token::b4_symbol([$1], [tag])),dnl - b4_symbol_if([$1], [has_type_name], [v, ])l); + return symbol_type (b4_args([yytranslate_ (token::b4_symbol([$1], [tag]))], + b4_symbol_if([$1], [has_type_name], [v]), + b4_locations_if([l]))); } ])])]) @@ -309,9 +333,10 @@ m4_define([b4_parser_class_name], b4_defines_if([], [b4_fatal([b4_skeleton[: using %%defines is mandatory]])]) -# Backward compatibility. +b4_locations_if( +[# Backward compatibility. m4_define([b4_location_constructors]) -m4_include(b4_pkgdatadir/[location.cc]) +m4_include(b4_pkgdatadir/[location.cc])]) # We do want M4 expansion after # for CPP macros. m4_changecom() @@ -333,8 +358,8 @@ dnl FIXME: This is wrong, we want computed header guards. #include "stack.hh" ]b4_namespace_open[ - class position; - class location; +]b4_locations_if([ class position; + class location;])[ ]b4_variant_if( [[ /// A char[S] buffer to store and retrieve objects. @@ -435,7 +460,7 @@ dnl FIXME: This is wrong, we want computed header guards. ]])[ ]b4_namespace_close[ -#include "location.hh" +]b4_locations_if([#include "location.hh"])[ /* Enabling traces. */ #ifndef YYDEBUG @@ -455,7 +480,8 @@ dnl FIXME: This is wrong, we want computed header guards. # define YYTOKEN_TABLE ]b4_token_table[ #endif -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +]b4_locations_if([dnl +[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ @@ -472,7 +498,7 @@ do { \ (Current).begin = (Current).end = (Rhs)[0].location.end; \ } \ } while (false) -#endif +#endif]])[ ]b4_namespace_open[ @@ -499,9 +525,9 @@ m4_ifdef([b4_stype], [[ typedef YYSTYPE semantic_type;]])])])[ #else typedef YYSTYPE semantic_type; -#endif +#endif]b4_locations_if([ /// Symbol locations. - typedef ]b4_percent_define_get([[location_type]])[ location_type; + typedef b4_percent_define_get([[location_type]]) location_type;])[ /// Tokens. struct token { @@ -533,10 +559,10 @@ m4_ifdef([b4_stype], #endif private: - /// Report a syntax error. - /// \param loc where the syntax error is found. + /// Report a syntax error.]b4_locations_if([ + /// \param loc where the syntax error is found.])[ /// \param msg a description of the syntax error. - virtual void error (const location_type& loc, const std::string& msg); + virtual void error (]b4_locations_if([const location_type& loc, ])[const std::string& msg); /// Generate an error message. /// \param state the state where the error occurred. @@ -612,9 +638,11 @@ m4_ifdef([b4_stype], /// Default constructor. inline symbol_base_type (); - /// Constructor. - inline symbol_base_type (const location_type& l); - inline symbol_base_type (const semantic_type& v, const location_type& l); + /// Constructor.]b4_locations_if([ + inline symbol_base_type (const location_type& l)])[; + inline symbol_base_type (]b4_args( + [const semantic_type& v], + b4_locations_if([const location_type& l]))[); /// Return this with its exact type. const Exact& self () const; @@ -624,10 +652,10 @@ m4_ifdef([b4_stype], int type_get () const; /// The semantic value. - semantic_type value; + semantic_type value;]b4_locations_if([ /// The location. - location_type location; + location_type location;])[ }; #if YYDEBUG @@ -658,11 +686,12 @@ m4_ifdef([b4_stype], inline symbol_type (); /// Constructor. - inline symbol_type (int t, - const semantic_type& v, const location_type& l); + inline symbol_type (]b4_args([int t], + [const semantic_type& v], + b4_locations_if([const location_type& l]))[); - inline symbol_type (int t, - const location_type& l); + inline symbol_type (]b4_args([int t], + b4_locations_if([const location_type& l]))[); /// The symbol type. int type; @@ -684,8 +713,9 @@ m4_ifdef([b4_stype], inline stack_symbol_type (); /// Constructor. - inline stack_symbol_type (state_type s, - const semantic_type& v, const location_type& l); + inline stack_symbol_type (]b4_args([state_type s], + [const semantic_type& v], + b4_locations_if([const location_type& l]))[); /// The state. state_type state; @@ -886,22 +916,24 @@ b4_percent_code_get[]dnl // symbol_base_type. template ]b4_parser_class_name[::symbol_base_type::symbol_base_type () - : value() - , location() + : value()]b4_locations_if([ + , location()])[ { - } + }]b4_locations_if([[ template ]b4_parser_class_name[::symbol_base_type::symbol_base_type (const location_type& l) : value() , location(l) { - } + }]])[ template - ]b4_parser_class_name[::symbol_base_type::symbol_base_type (const semantic_type& v, const location_type& l) - : value(v) - , location(l) + ]b4_parser_class_name[::symbol_base_type::symbol_base_type (]b4_args( + [const semantic_type& v], + b4_locations_if([const location_type& l]))[) + : value(v)]b4_locations_if([ + , location(l)])[ { } @@ -933,16 +965,19 @@ b4_percent_code_get[]dnl { } - ]b4_parser_class_name[::symbol_type::symbol_type (int t, - const location_type& l) - : super_type (l) + ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args( + [int t], + b4_locations_if([const location_type& l]))[) + : super_type (]b4_locations_if([l])[) , type (t) { } - ]b4_parser_class_name[::symbol_type::symbol_type (int t, - const semantic_type& v, const location_type& l) - : super_type (v, l) + ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args( + [int t], + [const semantic_type& v], + b4_locations_if([const location_type& l]))[) + : super_type (v]b4_locations_if([, l])[) , type (t) { } @@ -962,9 +997,11 @@ b4_percent_code_get[]dnl { } - ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (state_type s, - const semantic_type& v, const location_type& l) - : super_type (v, l) + ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (]b4_args( + [state_type s], + [const semantic_type& v], + b4_locations_if([const location_type& l]))[) + : super_type (v]b4_locations_if([, l])[) , state (s) { } @@ -1006,8 +1043,8 @@ b4_percent_code_get[]dnl { int yytype = yysym.type_get (); yyo << (yytype < yyntokens_ ? "token" : "nterm") - << ' ' << yytname_[yytype] << " (" - << yysym.location << ": "; + << ' ' << yytname_[yytype] << " ("]b4_locations_if([ + << yysym.location << ": "])[; switch (yytype) { ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))[ @@ -1025,10 +1062,16 @@ b4_percent_code_get[]dnl if (m) YY_SYMBOL_PRINT (m, sym); ]b4_variant_if( -[[ yystack_.push (stack_symbol_type (s, semantic_type(), sym.location)); +[[ yystack_.push (stack_symbol_type (]b4_args( + [s], + [semantic_type()], + b4_locations_if([sym.location]))[)); ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], [build], [sym.value])], -[ yystack_.push (stack_symbol_type (s, sym.value, sym.location));])[ +[[ yystack_.push (stack_symbol_type (]b4_args( + [s], + [sym.value], + b4_locations_if([sym.location]))[));]])[ } void @@ -1037,7 +1080,10 @@ b4_percent_code_get[]dnl if (m) YY_SYMBOL_PRINT (m, s); ]b4_variant_if( -[[ yystack_.push (stack_symbol_type (s.state, semantic_type(), s.location)); +[[ yystack_.push (stack_symbol_type (]b4_args( + [s.state], + [semantic_type()], + b4_locations_if([s.location]))[)); ]b4_symbol_variant([[yystos_[s.state]]], [[yystack_[0].value]], [build], [s.value])], [ yystack_.push (s);])[ @@ -1092,10 +1138,10 @@ b4_percent_code_get[]dnl int yyerrstatus_ = 0; /// The lookahead symbol. - symbol_type yyla; + symbol_type yyla;]b4_locations_if([[ /// The locations where the error started and ended. - stack_symbol_type yyerror_range[2]; + stack_symbol_type yyerror_range[2];]])[ /// $$ and @@$. stack_symbol_type yylhs; @@ -1211,12 +1257,13 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ yylhs.value = yystack_@{yylen - 1@}.value; else yylhs.value = yystack_@{0@}.value;])[ - +]b4_locations_if([dnl +[ // Compute the default @@$. { slice slice (yystack_, yylen); YYLLOC_DEFAULT (yylhs.location, slice, yylen); - } + }]])[ // Perform the reduction. YY_REDUCE_PRINT (yyn); @@ -1265,10 +1312,12 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ if (!yyerrstatus_) { ++yynerrs_; - error (yyla.location, yysyntax_error_ (yystate, yyla.type)); + error (]b4_args(b4_locations_if([yyla.location]), + [yysyntax_error_ (yystate, yyla.type)])[); } - yyerror_range[0].location = yyla.location; +]b4_locations_if([[ + yyerror_range[0].location = yyla.location;]])[ if (yyerrstatus_ == 3) { /* If just tried and failed to reuse lookahead token after an @@ -1300,7 +1349,8 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ if (false) goto yyerrorlab; - yyerror_range[0].location = yystack_[yylen - 1].location; +]b4_locations_if([[ + yyerror_range[0].location = yystack_[yylen - 1].location;]])[ /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ yypop_ (yylen); @@ -1332,16 +1382,16 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ // Pop the current state because it cannot handle the error token. if (yystack_.size () == 1) YYABORT; - - yyerror_range[0].location = yystack_[0].location; +]b4_locations_if([[ + yyerror_range[0].location = yystack_[0].location;]])[ yy_destroy_ ("Error: popping", yystack_[0]); yypop_ (); yystate = yystack_[0].state; YY_STACK_PRINT (); } - +]b4_locations_if([[ yyerror_range[1].location = yyla.location; - YYLLOC_DEFAULT (error_token.location, (yyerror_range - 1), 2); + YYLLOC_DEFAULT (error_token.location, (yyerror_range - 1), 2);]])[ /* Shift the error token. */ error_token.state = yystate = yyn; diff --git a/tests/c++.at b/tests/c++.at index fefeda37..f00e1096 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -141,10 +141,9 @@ yylex(yy::parser::semantic_type* yylval) } void -yy::parser::error(const yy::parser::location_type& yylloc, - const std::string& message) +yy::parser::error(const std::string& message) { - std::cerr << yylloc << ": " << message << std::endl; + std::cerr << message << std::endl; } int @@ -278,10 +277,11 @@ AT_DATA_GRAMMAR([[input.y]], %define namespace "]$1[" %union { int i; } %define global_tokens_and_yystype +%locations %code { // YYSTYPE contains a namespace reference. - int yylex (YYSTYPE *lval) { + int yylex (YYSTYPE *lval, const ]$1[::parser::location_type* lloc) { lval->i = 3; return 0; } diff --git a/tests/calc.at b/tests/calc.at index 8adf9e76..0c1c1ce2 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -90,16 +90,16 @@ static int get_char (]AT_LEX_FORMALS[); static void unget_char (]AT_LEX_PRE_FORMALS[ int c); %} -]AT_SKEL_CC_IF( -[/* The lalr1.cc skeleton, for backward compatibility, defines +]AT_SKEL_CC_IF([AT_LOCATION_IF([ +/* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are - excluded in C++. */ + excluded in C++). */ %initial-action { @$.initialize (0); } -])[ +])])[ /* Bison Declarations */ %token CALC_EOF 0 "end of input" @@ -150,9 +150,8 @@ static FILE *input; ]AT_SKEL_CC_IF( [/* A C++ error reporting function. */ void -AT_NAME_PREFIX::parser::error (const location& l, const std::string& m) +AT_NAME_PREFIX::parser::error (AT_LOCATION_IF([const location& l, ])const std::string& m) { - (void) l; std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl; } @@ -627,16 +626,17 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines %locations]) # Start a testing chunk which compiles `calc' grammar with # the C++ skeleton, and performs several tests over the parser. m4_define([AT_CHECK_CALC_LALR1_CC], -[AT_CHECK_CALC([%language "C++" %defines %locations] $@)]) +[AT_CHECK_CALC([%language "C++" %defines] $@)]) AT_CHECK_CALC_LALR1_CC([]) -AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR1_CC([%locations]) +AT_CHECK_CALC_LALR1_CC([%locations %error-verbose %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR1_CC([%locations %error-verbose %debug %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) diff --git a/tests/output.at b/tests/output.at index a20baef1..a62d77a5 100644 --- a/tests/output.at +++ b/tests/output.at @@ -107,13 +107,16 @@ AT_CHECK([grep 'include .subdir/' $1.hh], 1, []) ]) AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %defines %verbose], [], + [foo.tab.cc foo.tab.hh foo.output stack.hh]) + +AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %defines %verbose %locations], [], [foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh]) AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose], [], - [foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh], + [foo.tab.cc foo.tab.hh foo.output stack.hh], [], [AT_CHECK_NO_SUBDIR_PART([foo.tab])]) -AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose], +AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose %locations], [-o subdir/foo.cc], [subdir/foo.cc subdir/foo.hh subdir/foo.output subdir/location.hh subdir/stack.hh subdir/position.hh], [], [AT_CHECK_NO_SUBDIR_PART([subdir/foo])]) @@ -121,6 +124,11 @@ AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose], AT_CHECK_OUTPUT([gram_dir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose %file-prefix "output_dir/foo"], [], + [output_dir/foo.tab.cc output_dir/foo.tab.hh output_dir/foo.output output_dir/stack.hh]) + +AT_CHECK_OUTPUT([gram_dir/foo.yy], + [%skeleton "lalr1.cc" %defines %locations %verbose %file-prefix "output_dir/foo"], + [], [output_dir/foo.tab.cc output_dir/foo.tab.hh output_dir/foo.output output_dir/location.hh output_dir/stack.hh output_dir/position.hh]) @@ -153,7 +161,7 @@ AT_CHECK_CONFLICTING_OUTPUT([foo.y], ]) AT_CHECK_CONFLICTING_OUTPUT([foo.y], -[%skeleton "lalr1.cc" %defines], [--graph="location.hh"], +[%skeleton "lalr1.cc" %defines %locations], [--graph="location.hh"], [foo.y: warning: conflicting outputs to file `location.hh' ]) @@ -163,7 +171,7 @@ AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y], # AT_CHECK_OUTPUT_FILE_NAME(FILE-NAME-PREFIX, [ADDITIONAL-TESTS]) -# ----------------------------------------------------------------------------- +# --------------------------------------------------------------- m4_define([AT_CHECK_OUTPUT_FILE_NAME], [AT_SETUP([Output file name: $1]) diff --git a/tests/regression.at b/tests/regression.at index fa2278a8..18455242 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -887,7 +887,7 @@ member: STRING AT_LALR1_CC_IF( [/* A C++ error reporting function. */ void -yy::parser::error (const location&, const std::string& m) +yy::parser::error (const std::string& m) { std::cerr << m << std::endl; } @@ -986,7 +986,7 @@ t: A | B; AT_LALR1_CC_IF( [/* A C++ error reporting function. */ void -yy::parser::error (const location&, const std::string& m) +yy::parser::error (const std::string& m) { std::cerr << m << std::endl; } -- 2.47.2