【问题标题】:C++ Parsing Library with UTF-8 support支持 UTF-8 的 C++ 解析库
【发布时间】:2011-12-09 15:26:29
【问题描述】:

假设我想为一种编程语言(EBNF 已知)制作一个解析器,并希望尽可能少地大惊小怪。另外,我想支持任何 UTF-8 字母的标识符。我想要它在 C++ 中。

flex/bison 不存在 UTF-8 支持,正如我所读。 ANTLR 似乎没有可用的 C++ 输出。

我考虑过boost::spirit,他们在他们的网站上声明它实际上并不适用于完整的解析器。

还剩下什么?用手完全滚动?

【问题讨论】:

  • 我认为boost::spirit 可以正常工作。见boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/…
  • 您可以使用 AX C++11 解析器生成器(带有 VC2010)。它支持宽字符,您需要编写规则将 UTF8 映射到 wchar_t,这并不难。 wchar_t 需要能够表示关联语言环境中的任何字符。不过没有正则表达式。
  • 我现在正在尝试 boost::spirit,但这在 UTF8 上似乎也不太好
  • boost::spirit 存在一个巨大的问题,即对于超过十几个规则的 EBNF 的任何东西,编译时间都会过长。恕我直言,它不适用于现实世界的问题。 stackoverflow.com/questions/5504997/…
  • @phresnel 我无法想象一个现实世界的问题需要精神来解决。当然,家庭作业练习,但在现实世界中存在特殊情况和极端情况,每种情况都需要添加额外的规则来处理。我认为精神是邪恶的。它很优雅,似乎在测试用例中运行良好,因此您需要花费数天时间来学习错综复杂的东西——当您意识到它在现实世界中毫无用处时,这些时间就被浪费了。这就是它被称为精神的原因吗?

标签: c++ parsing utf-8


【解决方案1】:

如果您没有找到具有您想要的支持的东西,请不要忘记 flex 主要独立于编码。它对八位字节流进行词法分析,我用它对纯二进制数据进行了词法分析。以 UTF-8 编码的东西是八位字节流,如果您接受手动完成某些工作,则可以由 flex 处理。 IE。而不是拥有

idletter [a-zA-Z]

如果您想接受 Latin1 补充范围内除 NBSP 之外的所有内容作为字母(换句话说,在 U00A1-U00FF 范围内),您必须执行类似的操作(我可能弄乱了编码,但您得到了想法)

idletter [a-zA-Z]|\xC2[\xA1-\xFF]|\xC3[\x80-\xBF]

您甚至可以编写一个为您完成大部分工作的预处理器(即将 \u00A1 替换为 \xC2\xA1 并将 [\u00A1-\u00FF] 替换为 \xC2[\xA1-\xFF]|\xC3[ \x80-\xBF],预处理器的工作量取决于您希望输入的通用性,有时您可能会更好地将工作集成到 flex 中并在上游贡献)

【讨论】:

    【解决方案2】:

    解析器使用令牌,知道编码不是它的职责。它通常只会比较令牌的 id,如果您编写特殊规则,您可以像在其他任何地方那样比较带下划线的 UTF-8 字符串。

    所以你需要一个 UTF-8 词法分析器?好吧,这在很大程度上取决于您如何定义问题。如果您将标识符定义为由 ASCII 字母数字和其他任何非 ASCII 字符组成,那么 flex 将很好地满足您的需求。如果您想实际将 Unicode 范围提供给词法分析器,则需要更复杂的东西。你可以看看Quex。我自己从未使用过它,但它声称支持 Unicode。 (虽然我会因为“基于字符索引的免费告诉/搜索”而杀死某人)

    编辑:Here is a similar question,它声称 flex 无法工作,因为它忽略了某些实现可能具有签名字符的错误......不过它可能已经过时了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-07
      • 2021-08-01
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多