如何在 C++ 模式下为 Flex 编写自定义输入函数?

How to write custom input function for Flex in C++ mode?

我有一个游戏引擎和一个着色器解析器。该引擎有一个 API 用于从虚拟文件系统读取。我希望能够通过这个 API 加载着色器。我正在考虑实现自己的 std::ifstream,但我不喜欢它,我的 api 非常简单,我不想做很多不必要的工作。我只需要能够从 VFS 读取 N 个字节。为了更方便,我使用了 C++ mod,但最终我找不到解决这个问题的方法,因为关于这个的官方信息很少。 CAPI什么都有,至少我可以调用scan_string函数,我在yyFlexParser接口中没有找到这样的函数

老实说,我想放弃解析器中的 std::ifstream ,而 return 只有 C api 。我使用 Flex C++ mode 的唯一目的是与 Bison C++ API 交互,这样解析器就可以在多线程环境中使用,但这也可以通过CAPI。 我只是无法使用 C++ 编译器编译 C 解析器。

  1. 如果有办法通过某种宏添加此类功能,我会很高兴。
  2. 如果有办法 return yy_scan_string 函数,我不介意,我可以自己读取整个文件并只提供一个字符串。

简单的解决方案,如果你只想提供一个字符串输入,就是把字符串变成一个std::istringstream,这是一个有效的std::istream。此解决方案的简单性减少了对等同于 yy_scan_string.

的需求

另一方面,如果您想要读取的数据源不是从 std::istream 派生的,则可以轻松创建一个词法扫描器,它可以执行任何必要的操作。只需 ,添加您需要的任何私有数据成员和一个初始化它们的构造函数,并覆盖 int LexerInput(char* buffer, size_t maxsize); 以将至少一个且不超过 maxsize 字节读入 buffer , 返回读取的字符数。 (YY_INPUT 也适用于 C++ 接口,但子类化更方便正是因为它可以让您保持自己的 reader 状态。)

备注:

  1. 如果您决定子类化并覆盖LexerInput,您需要注意“交互”模式实际上是在LexerInput中实现的。所以如果你想让你的词法分析器有一个交互模式,你也必须在你的覆盖中实现它。在交互模式下,LexerInput 始终只读取一个字符(当然,除非它位于文件末尾)。

  2. 如您在Flex code repository中所见,Flex的未来版本将使用这些功能的重构版本,因此您可能需要准备好将来修改您的代码,尽管 Flex 通常会长期保持向后兼容性。