7

我正在尝试为C/AL 编程语言创建某种lint工具。所以基本上我需要对源代码进行语法和词法分析。我计划从头开始编写解析器,但后来发现有很多工具可以帮助自动生成这些解析器。

我需要性能,因为在一段中检查 20 兆字节的代码是正常情况,我需要该工具可以通过自定义规则进行扩展。所以我决定使用 JavaScript。

到目前为止,我已经找到了两个可以使用JisonPEG.js的生成器。

它们中的哪一个给了我更多的解析性能?也许不是比较库,而是算法?

哪一个更适合我的需求(解析通用编程语言)?

更新: 我发现了类似的问答:

4

3 回答 3

7

一般来说,你会从一个 shift-reduce 解析器中获得非常好的解析性能,比如 Jison 实现的解析器。这可能有点老派,但它可以在非常紧张的内存需求和线性时间中工作。

PEG 产生一种不同类型的解析器,它可能功能更强大,但需要更多内存才能产生相同的结果。即 PEG 将需要与输入成比例的内存量,而 LALR 解析器将在更少的空间(一些表和一个小堆栈)中完成它。

于 2012-08-01T11:55:04.853 回答
6

“我需要性能(对于 20Mb)......所以我决定使用 Javascript”。这些都是矛盾的。

仔细编码的递归下降解析器可以非常快,但您必须编写大量代码。通常,LALR(1) 解析器(由 Bison 从语法等生成)非常快,并且非常容易编码。(有技术论文展示了如何将 LALR 解析器直接编译为机器代码;这些解析器速度非常快,但您需要实现许多自定义机器来构建一个)。

如果你想以最少的汗水实现高性能解析,你应该考虑LRStar。(我知道并高度尊重作者,但除此之外与此无关)。这会产生非常快的 LALR 解析器。缺点:你必须让你的语法 LALR 兼容。您必须像扩展任何其他 C 程序一样扩展您的“规则”:通过编写 C 代码。恕我直言,这似乎并不比编写 JavaScript 差多少,但规则可能会执行得更快,并且在您考虑的规模上这很重要。

GLR 解析必然比 LALR 慢,因为它需要做更多的簿记工作。但这只是一个不变的因素。与 LRStar 这样的高性能引擎相比,它可能是显着的(例如,100 倍)。这可能是值得的麻烦,因为它更容易塑造你的语法,而且不那么复杂的语法可能会使编写自定义规则更容易。如果你真的有数百万行代码,这些解析器充其量只能是中等速度。

PEG基本上是一种回溯。它必须尝试一些事情,并在它们不起作用时回溯。它们必须比 LALR 解析器慢,至少要慢于它们所做的回溯量。你还有语法塑造问题。

但是,您会发现,如果您想做任何最微不足道的事情,仅仅解析是不够的。在这种情况下,您不想优化解析;您想优化基础设施以进行程序分析。请参阅我关于 解析后的生活的文章以获取另一种选择。

于 2012-08-01T14:23:06.763 回答
3

到目前为止,我已经找到了两个可以使用 Jison 和 PEG.js 的生成器。它们中的哪一个给了我更多的解析性能?

根据我创建的 JavaScript Parser Libraries 基准测试,PEG.js 似乎更快(至少在 Chrome/V8 上)。

你可以在这里在线运行它:http: //sap.github.io/chevrotain/performance/

请注意,此基准测试使用非常简单的 JSON 语法来比较解析库的性能,而不是使用更大更复杂的编程语言语法。

于 2017-03-30T12:05:11.523 回答