9

在问了这个问题之后,我现在开始尝试使用解析器生成器,在此之前我打算手动编写东西。

但是,我似乎找不到任何生成 C++ 代码的解析器,也找不到正确处理 Unicode 的解析器。(请注意,我的输入在 UCS-2 中——如果这会使构建解析器更加困难,我不关心支持基本多语言平面之外的位)

有一些解析器可以生成 C,但这些解析器似乎都将异常安全抛到了窗外,这将阻止我在任何语义操作中使用 C++。

是否存在满足这两个原则的解析器生成器,还是我被困在手动做所有事情?

编辑:哦,我的项目是 BSL 许可的,所以对解析器生成器本身的输出的使用没有太多限制。

4

8 回答 8

5

C++中有两种方式。使用程序从以自由形式或使用模板编写的语法生成 C++ 文件。

当您在模板类型中编写语法时,您有两个选择。使用 boost::proto,其中每个运算符都被重新定义以在 boost::fusion 中构建语法树(用于 boost::spirit、boost::msm、boost::xpressive)。(基本思路在这里:Expression Templates)或者借助自己的模板构建一个手写的表达式树并直接存储在 boost::mpl 容器中。该技术用于饼干。

在饼干里你有

or_<>, seq_<>, char_<>, ..

模板。Biscuit 基于 Yard,但扩展了 boost::range 以获得更好的子匹配能力。

饼干解析器库 1

饼干解析器库 2

另一个用于 C++ 的递归下降 (YARD) 解析框架

于 2010-12-09T19:27:59.670 回答
4

好吧,这可能是一个长镜头,但是有一个解析器生成器(LALR)作为 Qt 的一个附带项目,它被称为QLALR,它是一个非常薄的层,词法分析仍然取决于你,但所有工作都可以通过 QStrings 完成支持unicode。它没有很多功能,您使用为每个标记执行工作的代码编写语法,它会为您生成解析器。但是我已经使用它成功地生成了一个具有约 100 条规则的解析器,创建了一个已解析语言的 AST。

于 2010-12-04T15:52:14.680 回答
1

ANTLR支持 Unicode。它支持 C++(以及 C、Java 和其他一些语言),但我从未使用过 C++ 支持,所以我不确定它的开发程度。

于 2010-11-30T19:44:24.650 回答
1

似乎有对 unicode 的初步支持boost::spirit

于 2010-11-30T20:13:30.690 回答
1

如果你有心情进行实验,这个支持宽字符但很模糊:http ://wiki.winprog.org/wiki/LibCC_Parse

于 2010-11-30T20:18:43.897 回答
1

解析器不关心字符,因为它处理令牌。

Lexing Unicode 非常昂贵。这是因为您要么为分类支付巨大的函数调用开销,要么用大量表杀死你的内存。通常,您只支持 Unicode 是 PL 中的特定位置,例如字符串文字,也许还有标识符,手工制作的函数可以有效地完成这项工作。

我曾经在 Ocamllex 中编写了一个词法分析器,该词法分析器将接受 ISO C++ 标准规定的标识符(其中包括一组在各种语言中被视为“字母”的 Unicode 代码点范围)。尽管代码点范围的数量非常少(大约 20 个左右范围),但用于此的 UTF-8 DFA 具有超过 64K 的状态并炸毁了词法分析器生成器 :)

我的建议是:你必须手工制作你的词法分析器。事实上,很容易低效地做到这一点。有效地做到这一点要困难得多:我会查看 Judy 数组以获得支持(这是地球上最快的数据结构)。

于 2010-12-04T20:48:16.873 回答
0

试试Boost.Spirit。您可以插入自己的“流解码器”,它处理您问题的 unicode 部分。让Sprit工作wchar_t应该是可能的——尽管我自己没有尝试过。

于 2010-12-09T15:50:38.860 回答
0

我不知道很多关于解析器的理论,所以如果这不符合要求,请原谅我,但是有 Ragel。

Ragel生成状态机。Mongrel HTTP 服务器使用它(也许是最著名的?)用于 Ruby 解析 HTTP 请求。

Ragel 针对纯 C(以及其他),但所有状态机数据都是静态 const 或堆栈分配的,因此应该减轻 C++ 异常的一些重要问题。如果需要特殊的异常处理,Ragel 不会回避暴露其内部结构。(不像听起来那么复杂。)

Unicode 应该是可能的,因为 input 是任何基本类型的数组,通常是char,但可能是shortint你的情况下。如果不这样做,您甚至可以用您自己的机制替换数组迭代以获取下一个输入项/令牌/事件。

于 2010-12-09T19:44:39.700 回答