diff --git a/data/bison.m4 b/data/bison.m4 index 1a458b87..87ad0ca1 100644 --- a/data/bison.m4 +++ b/data/bison.m4 @@ -784,6 +784,39 @@ m4_define([b4_percent_define_ifdef], [$3])]) +# b4_percent_define_check_file_complain(VARIABLE) +# ----------------------------------------------- +# Warn about %define variable VARIABLE having an incorrect +# value. +m4_define([b4_percent_define_check_file_complain], +[b4_complain_at(b4_percent_define_get_loc([$1]), + [[%%define variable '%s' requires 'none' or '"..."' values]], + [$1])]) + + +# b4_percent_define_check_file(MACRO, VARIABLE, DEFAULT) +# ------------------------------------------------------ +# If the %define variable VARIABLE: +# - is undefined, then if DEFAULT is non-empty, define MACRO to DEFAULT +# - is a string, define MACRO to its value +# - is the keyword 'none', do nothing +# - otherwise, warn about the incorrect value. +m4_define([b4_percent_define_check_file], +[b4_percent_define_ifdef([$2], + [m4_case(b4_percent_define_get_kind([$2]), + [string], + [m4_define([$1], b4_percent_define_get([$2]))], + [keyword], + [m4_if(b4_percent_define_get([$2]), [none], [], + [b4_percent_define_check_file_complain([$2])])], + [b4_percent_define_check_file_complain([$2])]) + ], + [m4_ifval([$3], + [m4_define([$1], [$3])])]) +]) + + + ## --------- ## ## Options. ## ## --------- ## diff --git a/data/lalr1.cc b/data/lalr1.cc index a5839ac5..03243eb3 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -20,6 +20,7 @@ m4_include(b4_pkgdatadir/[c++.m4]) # api.value.type=variant is valid. m4_define([b4_value_type_setup_variant]) + # b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT) # -------------------------------------------------------------- # Declare "parser::yy_" whose contents is CONTENT. @@ -162,8 +163,9 @@ m4_define([b4_shared_declarations], # include ]b4_cxx_portability[ +]m4_ifdef([b4_stack_file], + [[# include "]b4_stack_file["]])[ ]b4_defines_if([[ -# include "stack.hh" ]b4_bison_locations_if([[# include "location.hh"]])])[ ]b4_variant_if([b4_variant_includes])[ @@ -174,9 +176,9 @@ m4_define([b4_shared_declarations], ]b4_namespace_open[ +]m4_ifdef([b4_stack_file], [], [b4_stack_define])[ ]b4_defines_if([], -[b4_stack_define -b4_bison_locations_if([b4_position_define +[b4_bison_locations_if([b4_position_define b4_location_define])])[ ]b4_variant_if([b4_variant_define])[ diff --git a/data/stack.hh b/data/stack.hh index 0ee2208b..69898992 100644 --- a/data/stack.hh +++ b/data/stack.hh @@ -18,6 +18,14 @@ m4_pushdef([b4_copyright_years], [2002-2015, 2018]) +# b4_stack_file +# ------------- +# Name of the file containing the stack class, if we want this file. +b4_percent_define_check_file([b4_stack_file], + [[api.stack.file]], + b4_defines_if([[stack.hh]])) + + # b4_stack_define # --------------- m4_define([b4_stack_define], @@ -129,16 +137,17 @@ m4_define([b4_stack_define], }; ]]) -b4_defines_if( -[b4_output_begin([b4_dir_prefix[]stack.hh]) -b4_copyright([Stack handling for Bison parsers in C++])[ + +m4_ifdef([b4_stack_file], +[b4_output_begin([b4_dir_prefix[]b4_stack_file])[ +]b4_copyright([Stack handling for Bison parsers in C++])[ /** - ** \file ]b4_dir_prefix[stack.hh + ** \file ]b4_dir_prefix[]b4_stack_file[ ** Define the ]b4_namespace_ref[::stack class. */ -]b4_cpp_guard_open([b4_dir_prefix[]stack.hh])[ +]b4_cpp_guard_open([b4_dir_prefix[]b4_stack_file])[ # include @@ -148,7 +157,8 @@ b4_copyright([Stack handling for Bison parsers in C++])[ ]b4_stack_define[ ]b4_namespace_close[ -]b4_cpp_guard_close([b4_dir_prefix[]stack.hh])[ -]b4_output_end]) +]b4_cpp_guard_close([b4_dir_prefix[]b4_stack_file])[ +]b4_output_end[ +]]) m4_popdef([b4_copyright_years]) diff --git a/tests/calc.at b/tests/calc.at index 17cecdc3..9c8030d4 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -694,6 +694,9 @@ AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug % AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) +AT_CHECK_CALC_LALR1_CC([%locations %define api.stack.file "my-stack.hh"]) +AT_CHECK_CALC_LALR1_CC([%locations %defines %define api.stack.file none]) +AT_CHECK_CALC_LALR1_CC([%defines %locations %define api.stack.file "my-stack.hh"]) # --------------------------- # diff --git a/tests/input.at b/tests/input.at index 9b8c453b..9927ddf3 100644 --- a/tests/input.at +++ b/tests/input.at @@ -1649,6 +1649,28 @@ input.y:1.9-21: accepted value: 'both' AT_CLEANUP + + +## ------------------------ ## +## %define file variables. ## +## ------------------------ ## + +AT_SETUP([["%define" file variables]]) + +AT_DATA([[input.y]], +[[%skeleton "lalr1.cc" +%define api.stack.file bogus +%% +start: %empty; +]]) +AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]], +[[input.y:2.9-22: error: %define variable 'api.stack.file' requires 'none' or '"..."' values + %define api.stack.file bogus + ^^^^^^^^^^^^^^ +]]) + +AT_CLEANUP + ## -------------------------------- ## ## %define backward compatibility. ## ## -------------------------------- ## diff --git a/tests/output.at b/tests/output.at index 600f82fa..8b5080e0 100644 --- a/tests/output.at +++ b/tests/output.at @@ -145,6 +145,9 @@ AT_CHECK([grep 'include .subdir/' $1.cc], 1, []) AT_CHECK([grep 'include .subdir/' $1.hh], 1, []) ]) +AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc"], [], + [foo.tab.cc]) + AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %verbose], [], [foo.output foo.tab.cc]) @@ -176,6 +179,22 @@ AT_CHECK_OUTPUT([gram_dir/foo.yy], [], [output_dir/foo.output output_dir/foo.tab.cc output_dir/foo.tab.hh output_dir/location.hh output_dir/position.hh output_dir/stack.hh]) +# api.stack.file. +AT_CHECK_OUTPUT([foo.yy], + [%skeleton "lalr1.cc" %define api.stack.file "foo.sta.hh"], + [], + [foo.sta.hh foo.tab.cc]) + +AT_CHECK_OUTPUT([foo.yy], + [%skeleton "lalr1.cc" %defines %define api.stack.file none], + [], + [foo.tab.cc foo.tab.hh]) + +AT_CHECK_OUTPUT([gram_dir/foo.yy], + [%skeleton "lalr1.cc" %verbose %defines %define api.stack.file "foo.sta.hh" %file-prefix "output_dir/foo"], + [], + [output_dir/foo.output output_dir/foo.sta.hh output_dir/foo.tab.cc output_dir/foo.tab.hh]) + # AT_CHECK_CONFLICTING_OUTPUT(INPUT-FILE, DIRECTIVES, FLAGS, STDERR, # [EXIT-STATUS])