我又在为 Boost.Spirit.X3 苦苦挣扎。
我有几个逻辑解析器组(语句、表达式等),每个解析器都由几个文件表示:
group.hpp
- 包含“外部”使用的解析器typedef
的 sBOOST_SPIRIT_DECLARE
和extern
变量声明group_def.hpp
- 包括前一个并包含解析器的实际定义BOOST_SPIRIT_DEFINE
,等等。group.cpp
- 包括前一个并包含显式模板实例化(通过BOOST_SPIRIT_INSTANTIATE
)
基本上,它或多或少遵循官方教程中提出的结构。唯一的区别是我的语法要复杂得多,所以我试图把它分成几个翻译单元。然后将所有这些 TU 编译到一个库中,然后将其链接到主可执行文件。
我试图在这里做一个“最小”的例子(活在 Wandbox 上),因为在这里列出所有文件会很不方便。 由于一些未解决的外部因素,它不起作用,所以,很可能,我错误地实例化了一些东西,但我已经为此花了大约一周的时间,所以我很绝望,不觉得我能我自己来处理这个。
几个问题和答案:
为什么我更喜欢每个“组”使用三个文件?
首先,因为我试图以这样一种方式制作它,即我不想在任何小的更改上重新编译所有内容(不确定我是否成功了),所以这个想法somegroup.hpp
只是一个带有声明的“轻量级”标题,somegroup_def.hpp
是带有定义的标题,somegroup.cpp
仅用于创建翻译单元。
其次,我拆分_def.hpp
,.cpp
因为我还将这些_def.hpp
文件直接包含到测试中,我不仅涵盖extern
解析器,还涵盖“内部”辅助解析器。
为什么我要使用extern
变量?
我也尝试使用返回解析器的函数(类似于教程中的完成方式)。基本上,这就是它的实现方式和现在的工作方式。我不喜欢它,因为例如,给定一个解析器lang::parser::import
,我必须给一个函数另一个名称(lang::parser::import_
)或将它放在另一个名称空间中(即lang::import
)。此外,我喜欢直接使用解析器的方式,它是如何在 Spirit 本身中完成的(即不带括号:import
vs import_()
)。
我的实际问题如下:
- 如果我想将解析器分布在多个翻译单元上,如何正确组织结构?
- 我在上面的代码示例中究竟遗漏了什么,所以它没有链接?
我将不胜感激任何帮助。