3

我有一个项目,其中使用 Bison 生成解析器。项目本身是用 SCons 构建的,我所有的代码都是用 C++ 编写的。一开始我决定将代码分成 3 个主要目录:includes、src 和 test,其中第一个可以只包含公共头文件,src包含实现和私有头文件,而test只包含测试。

目前这个约定被 3 个文件打破:stack.hhposition.hhlocation.hh。它们是由 Bison 自动生成的,因为我在 C++ 模式下使用它。但是,虽然我可以使用参数--defines=include/namespace/parser.hpp来设置解析器的头文件应该放在哪里,但我找不到定义这 3 个文件应该放在哪里的方法,所以它们保存在同一个文件夹中src/命名空间/parser.cpp

我想知道如何干净地处理它。到目前为止,我提出了 2 个想法:首先是使用%defineapi.location将其设置为当前使用的类(这将阻止 Bison 再次生成这些文件),然后将这些文件移动到那里。另一种是我自己重新实现位置位置类并使用所述api设置它们。一个想法对我来说听起来像是一个肮脏的黑客,而另一个想法对于这样一个简单的任务来说是一种过度杀伤力。

是否有任何其他(干净的)方法可以确保解析器使用的帮助器将放置在包含目录中,而src将仅包含实现?

编辑:

这些文件(或它们的替换文件)应该放在公共头文件夹中的原因是它们被包含在Bison 生成的parser.hpp文件中。因此,如果不将这些文件添加到搜索文件夹列表中,我将无法编译任何包含 parser.hpp 的文件。目前我必须添加到源文件夹的路径以包含,以便编译器可以找到仅在 1 个地方需要的这 3 个文件:生成的 parser.hpp 标头,我无法控制它。这是无关紧要和令人困惑的,所以我想把它改正。

4

2 回答 2

1

你似乎对你的文件应该去哪里感到困惑,或者至少你让我感到困惑。一方面你说你的 include/ 目录是为公共头文件保留的,其他头文件应该放在 src/ 下。另一方面,您是说 Bison 的辅助类的头文件(肯定是私有的)应该进入 include/ ,因为它不是实现代码。

Bison 应该将这些标头放在解析器的主 C++ 文件旁边(您似乎已确认确实如此),根据您的一组标准,这似乎是正确的位置。如果您仍然希望在其他地方使用这些标题,那么我认为您需要在事后复制或移动它们。我不关心 SCons,但它肯定允许你编写规则来实现这一点。

于 2013-10-28T21:09:14.113 回答
0

显然,我坚持使用的 Bison 2.5 版并没有给我太多选择。从 2.7 开始,我可以使用选项api.namespace来防止野牛生成position.hhlocation.hh. 然后我可以一次生成这些文件,手动移动它们,然后添加这个选项。但是没有选项(即使在当前的 3.0 中)可以防止创建 stack.hh 或用我自己的东西替换它。

因此,我现在可以应用的唯一解决方案是将这些文件移动到所需的位置,每次构建器调用野牛时。这是丑陋、肮脏的 hack,但它确保了系统其余部分的一致性,所以我现在将继续使用它。在 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在构建期间使用!),但在出现更好的解决方案之前,我将使用这个解决方案。

于 2013-11-02T15:17:55.567 回答