我有一个项目,其中使用Bison来生成解析器。项目本身是用SCons构建的,我的所有代码都是用C ++编写的。我在开始时决定的一件事是将代码分成3个主要方面:includes,src和test,其中第一个只包含 public 标题, src 包含两个实现和私有标头,以及 test 只包含测试。
目前,此约定由3个文件打破: stack.hh , position.hh 和 location.hh 。它们是由Bison自动生成的,因为我在C ++模式下使用它。但是,虽然我可以使用参数 - defines = include / namespace / parser.hpp 来设置应该放置解析器标头的位置,但是我找不到一种方法来定义应该放置这3个文件的位置,所以他们保存在与 src / namespace / parser.cpp 相同的文件夹中。
我想知道如何干净利落地处理它。到目前为止,我提出了两个想法:首先是使用%define 和 api.location 将其设置为当前使用的类(这将阻止Bison再次生成这些文件)然后将那些文件移动到那里。另一种是我自己重新实现位置和位置类,并用所述api设置它们。一个想法听起来像是一个肮脏的黑客,而另一个想法对于这样一个简单的任务来说是一种过度杀伤。
是否有其他(干净)方法可以确保解析器使用的帮助程序放在 include 目录中,而 src 只包含实现?
编辑:
这些文件(或它们的替代品)应该放在公共头文件夹中的原因是它们被包含在Bison生成的 parser.hpp 文件中。因此,如果不将这些文件添加到搜索文件夹列表中,我将无法编译包含parser.hpp的任何文件。目前我必须添加包含源文件夹的路径,以便编译器只能在一个地方找到所需的3个文件:生成的parser.hpp标头,我无法控制它。这是不可能的,令人困惑,所以我想做对。
答案 0 :(得分:1)
您似乎对文件的位置感到困惑,或者至少让您感到困惑 me 。一方面,你说你的include /目录是为公共标题保留的,其他标题应该在src /下。另一方面,你说Bison的助手类的头文件 - 肯定是私有的 - 应该包含/因为不是实现代码。
Bison应该将这些标题与解析器的主要C ++文件一起删除(您似乎确认了它),根据您的一组标准,这似乎是正确的位置。如果你还想在其他地方使用这些标题,那么我认为你需要在事后复制或移动它们。我不关心SCons,但肯定它允许你编写规则来实现它。
答案 1 :(得分:0)
显然,我坚持使用的Bison版本2.5并没有给我很多选择。自2.7以来,我可以使用选项api.namespace
来阻止野牛生成position.hh
和location.hh
。然后我可以生成一次这些文件,手动移动它们,然后添加此选项。但是没有选择(即使在当前的3.0中)来防止创建stack.hh或者用我自己的东西替换它。
因此,我现在只能应用的解决方案是将这些文件移动到所需位置,每次生成器调用bison时。这是一个丑陋,肮脏的黑客,但它确保了系统其余部分的一致性,所以我现在就去使用它。在SCons中我实现了它:
# Directories configuration
# Main directories
fnb = 'f_n_b/'
include = 'include/'
source = 'src/'
###########################################################################
# Some modules and tests
###########################################################################
# Builds parser and scanner classes
Parser_yy_URI = fnb +'parser.yy'
Parser_cpp_URI = source +'parser.cpp'
Parser_hpp_URI = include+'parser.hpp'
Scanner_ll_URI = fnb +'scanner.ll'
Scanner_cpp_URI = source +'scanner.cpp'
Parser_cpp = env.CXXFile(
source=Parser_yy_URI,
target=Parser_cpp_URI,
YACCFLAGS=['--defines='+Parser_hpp_URI, '--verbose']
)
Scanner_cpp = env.CXXFile(
source=Scanner_ll_URI,
target=Scanner_cpp_URI
)
CorrectBisonInstallation = [
env.Command(
include+WronglyPlacedBisonHelper_hh.name,
WronglyPlacedBisonHelper_hh,
Move("$TARGET", "$SOURCE")
)
for WronglyPlacedBisonHelper_hh in Glob(source+'*.hh')
if WronglyPlacedBisonHelper_hh.name in [
'location.hh',
'position.hh',
'stack.hh'
]
]
Depends(
CorrectBisonInstallation,
[Parser_cpp, Scanner_cpp]
)
###########################################################################
# Some modules depending on Parser and Scanner classes
这远非完美的解决方案(在构建期间使用move
!)但是直到出现一些更好的解决方案我会使用这个。