干净的方式将Bison的stack.hh,position.hh和location.hh放在另一个文件夹中

时间:2013-10-20 10:22:39

标签: c++ bison

我有一个项目,其中使用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标头,我无法控制它。这是不可能的,令人困惑,所以我想做对。

2 个答案:

答案 0 :(得分:1)

您似乎对文件的位置感到困惑,或者至少让您感到困惑 me 。一方面,你说你的include /目录是为公共标题保留的,其他标题应该在src /下。另一方面,你说Bison的助手类的头文件 - 肯定是私有的 - 应该包含/因为不是实现代码。

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

答案 1 :(得分:0)

显然,我坚持使用的Bison版本2.5并没有给我很多选择。自2.7以来,我可以使用选项api.namespace来阻止野牛生成position.hhlocation.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!)但是直到出现一些更好的解决方案我会使用这个。