c++: add support for api.position.file and api.location.file

* data/location.cc: Sort includes.
(b4_position_file, b4_location_file): New.
When there's a file for locations but not for positions, include the
definition of position in the location file.
* data/lalr1.cc (b4_shared_declarations): Include the
position/location file when it exists.
Otherwise, define the class.
* data/glr.cc: Likewise.
* tests/input.at (%define file variables): Check them.
* tests/output.at (C++ output): Check various cases with
api.position.file and api.location.file.
This commit is contained in:
Akim Demaille
2018-09-29 10:32:32 +02:00
parent b122a71c83
commit 667588ee8a
6 changed files with 89 additions and 29 deletions

View File

@@ -242,18 +242,24 @@ b4_namespace_close
m4_define([b4_shared_declarations], m4_define([b4_shared_declarations],
[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl [m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
b4_percent_code_get([[requires]])[ b4_percent_code_get([[requires]])[
#include <iostream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <iostream>]b4_defines_if([
b4_bison_locations_if([[#include "location.hh"]])])[ ]m4_ifdef([b4_position_file],
[[# include "]b4_position_file["]])[
]m4_ifdef([b4_location_file],
[[# include "]b4_location_file["]])[
]b4_null_define[
]b4_YYDEBUG_define[ ]b4_YYDEBUG_define[
]b4_namespace_open[ ]b4_namespace_open[
]b4_defines_if([], ]b4_bison_locations_if([m4_ifndef([b4_location_file],
[b4_bison_locations_if([b4_position_define [m4_ifndef([b4_position_file], [b4_position_define
b4_location_define])])[
])[]b4_location_define])])[
/// A Bison parser. /// A Bison parser.
class ]b4_parser_class_name[ class ]b4_parser_class_name[

View File

@@ -165,8 +165,10 @@ m4_define([b4_shared_declarations],
]b4_cxx_portability[ ]b4_cxx_portability[
]m4_ifdef([b4_stack_file], ]m4_ifdef([b4_stack_file],
[[# include "]b4_stack_file["]])[ [[# include "]b4_stack_file["]])[
]b4_defines_if([[ ]m4_ifdef([b4_position_file],
]b4_bison_locations_if([[# include "location.hh"]])])[ [[# include "]b4_position_file["]])[
]m4_ifdef([b4_location_file],
[[# include "]b4_location_file["]])[
]b4_variant_if([b4_variant_includes])[ ]b4_variant_if([b4_variant_includes])[
]b4_attribute_define[ ]b4_attribute_define[
@@ -176,10 +178,11 @@ m4_define([b4_shared_declarations],
]b4_namespace_open[ ]b4_namespace_open[
]m4_ifdef([b4_stack_file], [], [b4_stack_define])[ ]m4_ifndef([b4_stack_file], [b4_stack_define])[
]b4_defines_if([], ]b4_bison_locations_if([m4_ifndef([b4_location_file],
[b4_bison_locations_if([b4_position_define [m4_ifndef([b4_position_file], [b4_position_define
b4_location_define])])[
])[]b4_location_define])])[
]b4_variant_if([b4_variant_define])[ ]b4_variant_if([b4_variant_define])[

View File

@@ -18,6 +18,19 @@
m4_pushdef([b4_copyright_years], m4_pushdef([b4_copyright_years],
[2002-2015, 2018]) [2002-2015, 2018])
# b4_position_file
# b4_location_file
# ----------------
# Name of the file containing the position/location class,
# if we want this file.
b4_percent_define_check_file([b4_position_file],
[[api.position.file]],
b4_defines_if([[position.hh]]))
b4_percent_define_check_file([b4_location_file],
[[api.location.file]],
b4_defines_if([[location.hh]]))
# b4_position_define # b4_position_define
# ------------------ # ------------------
# Define class position. # Define class position.
@@ -287,16 +300,16 @@ m4_define([b4_location_define],
]]) ]])
b4_defines_if([ m4_ifdef([b4_position_file], [[
b4_output_begin([b4_dir_prefix[]position.hh]) ]b4_output_begin([b4_dir_prefix[]b4_position_file])[
b4_copyright([Positions for Bison parsers in C++])[ ]b4_copyright([Positions for Bison parsers in C++])[
/** /**
** \file ]b4_dir_prefix[position.hh ** \file ]b4_dir_prefix[]b4_position_file[
** Define the ]b4_namespace_ref[::position class. ** Define the ]b4_namespace_ref[::position class.
*/ */
]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[ ]b4_cpp_guard_open([b4_dir_prefix[]b4_position_file])[
# include <algorithm> // std::max # include <algorithm> // std::max
# include <iostream> # include <iostream>
@@ -307,28 +320,31 @@ b4_copyright([Positions for Bison parsers in C++])[
]b4_namespace_open[ ]b4_namespace_open[
]b4_position_define[ ]b4_position_define[
]b4_namespace_close[ ]b4_namespace_close[
]b4_cpp_guard_close([b4_dir_prefix[]position.hh]) ]b4_cpp_guard_close([b4_dir_prefix[]b4_position_file])[
b4_output_end ]b4_output_end[
]])
b4_output_begin([b4_dir_prefix[]location.hh]) m4_ifdef([b4_location_file], [[
b4_copyright([Locations for Bison parsers in C++])[ ]b4_output_begin([b4_dir_prefix[]b4_location_file])[
]b4_copyright([Locations for Bison parsers in C++])[
/** /**
** \file ]b4_dir_prefix[location.hh ** \file ]b4_dir_prefix[]b4_location_file[
** Define the ]b4_namespace_ref[::location class. ** Define the ]b4_namespace_ref[::location class.
*/ */
]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[ ]b4_cpp_guard_open([b4_dir_prefix[]b4_location_file])[
# include "position.hh" ]m4_ifdef([b4_position_file], [[#] include "b4_position_file"], [b4_null_define])[
]b4_namespace_open[ ]b4_namespace_open[
]m4_ifndef([b4_position_file], [b4_position_define])[
]b4_location_define[ ]b4_location_define[
]b4_namespace_close[ ]b4_namespace_close[
]b4_cpp_guard_close([b4_dir_prefix[]location.hh]) ]b4_cpp_guard_close([b4_dir_prefix[]b4_location_file])[
b4_output_end ]b4_output_end[
]) ]])
m4_popdef([b4_copyright_years]) m4_popdef([b4_copyright_years])

View File

@@ -695,8 +695,9 @@ AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix {c
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([%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 %define api.stack.file "my-stack.hh"])
AT_CHECK_CALC_LALR1_CC([%locations %defines %define api.stack.file none]) AT_CHECK_CALC_LALR1_CC([%locations %defines %define api.stack.file none %define api.location.file none %define api.position.file none])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define api.stack.file "my-stack.hh"]) AT_CHECK_CALC_LALR1_CC([%defines %locations %define api.stack.file "my-stack.hh"])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define api.stack.file "my-stack.hh" %define api.position.file none %define api.location.file "my-location.hh"])
# --------------------------- # # --------------------------- #

View File

@@ -1659,12 +1659,21 @@ AT_SETUP([["%define" file variables]])
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%skeleton "lalr1.cc" [[%skeleton "lalr1.cc"
%locations
%define api.stack.file bogus %define api.stack.file bogus
%define api.location.file {bogus}
%define api.position.file bogus
%% %%
start: %empty; start: %empty;
]]) ]])
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]], AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
[[input.y:2.9-22: error: %define variable 'api.stack.file' requires 'none' or '"..."' values [[input.y:5.9-25: error: %define variable 'api.position.file' requires 'none' or '"..."' values
%define api.position.file bogus
^^^^^^^^^^^^^^^^^
input.y:4.9-25: error: %define variable 'api.location.file' requires 'none' or '"..."' values
%define api.location.file {bogus}
^^^^^^^^^^^^^^^^^
input.y:3.9-22: error: %define variable 'api.stack.file' requires 'none' or '"..."' values
%define api.stack.file bogus %define api.stack.file bogus
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
]]) ]])

View File

@@ -190,6 +190,31 @@ AT_CHECK_OUTPUT([foo.yy],
[], [],
[foo.tab.cc foo.tab.hh]) [foo.tab.cc foo.tab.hh])
AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %define api.stack.file none %locations],
[],
[foo.tab.cc foo.tab.hh location.hh position.hh])
AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %define api.stack.file none %locations %define api.position.file none],
[],
[foo.tab.cc foo.tab.hh location.hh])
AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %define api.stack.file none %locations %define api.position.file none %define api.location.file none],
[],
[foo.tab.cc foo.tab.hh])
AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %define api.stack.file none %locations %define api.position.file none %define api.location.file "foo.loc.hh"],
[],
[foo.loc.hh foo.tab.cc foo.tab.hh])
AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %define api.stack.file none %locations %define api.position.file "foo.pos.hh" %define api.location.file "foo.loc.hh"],
[],
[foo.loc.hh foo.pos.hh foo.tab.cc foo.tab.hh])
AT_CHECK_OUTPUT([gram_dir/foo.yy], AT_CHECK_OUTPUT([gram_dir/foo.yy],
[%skeleton "lalr1.cc" %verbose %defines %define api.stack.file "foo.sta.hh" %file-prefix "output_dir/foo"], [%skeleton "lalr1.cc" %verbose %defines %define api.stack.file "foo.sta.hh" %file-prefix "output_dir/foo"],
[], [],