0

我使用 Tatsu 为 Gerber 格式开发了一个语法检查器。它工作正常,我感谢 Tatsu 开发人员。但是,它并不算太快,我现在正在优化语法。

Gerber 格式是一个命令流,这是由语法的主循环处理的,如下所示:

开始 =

{
    | ['X' integer] ['Y' integer] ((['I' integer 'J' integer] 'D01*')|'D02*'|'D03*')
    | ('G01*'|'G02*'|'G03*'|'G1*'|'G2*'|'G3*')
    ... about 25 rules
}*
M02
$;

整数 = /[+-]?[0-9]+/;

在大文件中,性能很重要,选择中的第一条规则涵盖了绝大多数语句。(实际上是三个命令。通过将它们放在首位,然后合并以消除公共元素,使检查器快 2-3 倍。)现在我尝试用正则表达式替换第一条规则,假设正则表达式在 C 中更快.

在第一步中,我内联了整数:

    | ['X' /[+-]?[0-9]+/] ['Y' /[+-]?[0-9]+/] ((['I' /[+-]?[0-9]+/ 'J' /[+-]?[0-9]+/] 'D01*')|'D02*'|'D03*')

这工作得很好,并给出了适度的加速。

然后我尝试了整个规则的正则表达式。失败。作为测试,我只修改了序列中的第一条规则:

    | /(X[+-]?[0-9]+)?/ ['Y' /[+-]?[0-9]+/] ((['I' /[+-]?[0-9]+/ 'J' /[+-]?[0-9]+/] 'D01*')|'D02*'|'D03*')

这无法识别以下命令:X81479571Y-38450761D01*

我看不出 ['X' /[+-]?[0-9]+/] 和 /(X[+-]?[0-9]+)?/ 之间的区别

我想念什么?

4

1 回答 1

0

不同之处在于,可选表达式 with[]将超越空格和注释,而模式表达式 with//不会。它在文档中。这种情况的一个技巧是将模式置于它自己的初始小写规则中,因此在应用模式之前有空格和注释标记化,尽管我不认为添加间接会有助于提高性能。

至于优化,我在“...25 more rules”案例中使用的一个技巧是将具有相似前缀的规则分组在 a 下&lookahead,例如&/G0/在您的案例中。

TatSu 旨在对语法作者友好,有利于表现出色。如果您需要极快的速度,通过在 C 中生成解析器,您可能需要查看pegen,它是 CPython 中新的 PEG 解析器的前身。

于 2022-01-28T11:07:45.927 回答