我每天开发的 DMS 系统在一台破旧的笔记本电脑上(刚刚在该笔记本电脑上测量)大约 7 秒内处理生产 IBM Enterprise COBOL 前端语法。
该语法有大约 500 个终端和 2500 个产生式,平均每个产生式大约 2.5 个标记。我们的产品与您描述的完全一样(没有 EBNF,只是买的东西不够重要,是的,我们是 DSL 的忠实拥护者。有时人们放入 DSL 的 geegaws 不值得)。解析器生成器产生 3800 个状态。(这些值也是刚刚测量的)。
DMS 具有完整的 C++11 语法,其中包含许多额外的东西来处理 GCC 和 MS 方言,以及 OpenMP。该语法有 457 个终端,大约 3000 个产生式,每个产生式平均有 2.3 个标记。解析器生成器产生 5800 个状态。需要更长的时间来生成:11 秒,在 i7 上。您可能会感到惊讶的是,生成词法分析器需要几十秒(实际上是多个词法分析器);C++11 中的词法怪异比你想象的要多得多。
生成器是我们自己实现的 GLR 生成器。
我们没有做很多优化生成时间的工作。它可能会加速 10 倍或更多;我们没有像大多数关于 LR 解析器生成的论文中建议的那样进行复杂的循环检测优化。结果是生成表需要更长的时间,但功能上没有任何损失。我们从来没有足够的动力进行这种优化,因为除了担心解析器表的生成时间之外,语言前端还有很多其他事情要做。
如果设计合理,我怀疑数据结构是否很重要。我们不太担心规则、项目集或状态的大小;我们只使用动态数组,它们会照顾自己。我们确实将前瞻打包到密集的位向量中。
作为额外的背景数据,您可能会发现这篇论文很有用:Tiago Alves 和 Joost Visser,SDF 语法的度量。技术报告,DI-Research.PURe-05.05.01,Departamento de Informática,Universidade do Minho,2005 年 5 月。
解析器生成器不是您在语法方面遇到困难的地方。它正在为特定的实现获取正确的语法规则。