ragel是不是设计用于文件?

时间:2017-12-01 13:14:47

标签: lexer ragel

调查ragel,无法弄清楚如何合理地从文件中读取。据我所知,它需要一个内存缓冲区,它不会在令牌中间被破坏。这显然是很多工作要实现的,特别是如果我不知道令牌的大小,例如如果我实现了所有这些,我不确定我是否需要ragel了。

有没有更好的方法?

2 个答案:

答案 0 :(得分:1)

如果将文件映射到内存(mmap,CreateFileMapping),您将整个文件作为一个连续的内存块提供。

另请参阅Ragel用户指南(5.9维护输入数据的指针),其中包含一些用于处理该情况的示例代码。对于可能超过固定缓冲区大小的字符串或标记,可以使用可变大小的缓冲区,该缓冲区会根据需要增长。

答案 1 :(得分:0)

要做到正确并依赖于你正在进行的解析,这非常棘手。

对于文件,您只需将整个文件映射到内存中并进行处理即可。

这是最好的选择。

如果您以块的形式读取数据,您仍然可以解析它,但是您需要在解析调用之间跟踪状态变量。我通常通过将它们放在一个类中并使用方法解析来逐步解析数据缓冲区来实现这一点。

如果要从数据中提取令牌,则需要在返回之前将令牌捕获到字符串中。当您恢复解析时,当您完成匹配令牌时,您将它与先前匹配的部分连接起来,这就是完整的令牌。在最坏的情况下,您的令牌缓冲区可能与原始文件一样大。

你可以在这里看到一些例子:

  1. 如果解析器标记了令牌的开头,但尚未完成,则会存储:https://github.com/kurocha/async-http/blob/eff77f61f7a85a3ac21f7a8f51ba07f069063cbe/source/Async/HTTP/V1/RequestParser.rl#L52-L54
  2. 在解析调用中保留解析器状态:https://github.com/kurocha/async-http/blob/eff77f61f7a85a3ac21f7a8f51ba07f069063cbe/source/Async/HTTP/V1/Parser.hpp#L57-L73
  3. 读取数据并调用parse的循环:https://github.com/kurocha/async-http/blob/eff77f61f7a85a3ac21f7a8f51ba07f069063cbe/source/Async/HTTP/V1/Protocol.cpp#L36-L54