2

我正在使用 TatSu python 库实现语法。我的语法工作正常,但有一条规则会消耗相当多的时间。在大约 3000 行的块上(更大语法的一部分),如果我采用这条完整规则,解析整个块大约需要 42 秒。如果我将此规则减少到几个标记,则运行时间会从 42 秒下降到 33 秒(改进约 20%)。

该规则如下所示,它应该匹配一系列由“/”分隔的事件。

events
    =
    '/'%{event}
    ;
event
    =
    'D' | 'U' | 'Z' | 'P' | 'L' | 'H' | 'x' | 'X' | 'T' | 'V' | 'l' | 'h' | 't' | 'v' | 'N' | 'A' | 'B' | 'F' | '?' | 'G' | 'R' | 'Q' | 'M'
    | 'ForceDown' | 'ForceUp' | 'ForceOff' | 'ForcePrior' | 'CompareLow' | 'CompareHigh' | 'CompareUnknown' | 'CompareOff'
    | 'CompareValid' | 'CompareLowWindow' | 'CompareHighWindow' | 'CompareOffWindow' | 'CompareValidWindow' | 'ForceUnknown'
    | 'LogicLow' | 'LogicHigh' | 'LogicZ' | 'Unknown' | 'ExpectHigh' | 'ExpectLow' | 'ExpectOff' | 'Marker'
    ;

如果我将事件更改为以下内容,我会得到更快的解析。

event
  =
  /[DUZPLHXT]/
  ;

那么是否有可能以某种方式改进上述规则以获得更快的处理?感谢您的任何想法。

4

1 回答 1

2

正如您所指出的,对于具有许多只是标记的选项的规则,使用模式(正则表达式)效率更高。

但运行时最终取决于某些规则如何相互调用。

您可以尝试的一个简单优化是添加一个 cut ( ˜) 表达式,以便每个表达式event最多尝试一次(尽管表达式中应该隐含一个cut%)。

event
    =
    (
    'D' | 'U' | 'Z' | 'P' | 'L' | 'H' | 'x' | 'X' | 'T' | 'V' | 'l' | 'h' | 't' | 'v' | 'N' | 'A' | 'B' | 'F' | '?' | 'G' | 'R' | 'Q' | 'M'
    | 'ForceDown' | 'ForceUp' | 'ForceOff' | 'ForcePrior' | 'CompareLow' | 'CompareHigh' | 'CompareUnknown' | 'CompareOff'
    | 'CompareValid' | 'CompareLowWindow' | 'CompareHighWindow' | 'CompareOffWindow' | 'CompareValidWindow' | 'ForceUnknown'
    | 'LogicLow' | 'LogicHigh' | 'LogicZ' | 'Unknown' | 'ExpectHigh' | 'ExpectLow' | 'ExpectOff' | 'Marker'
    ) ~
    ;

就是说,因为规则太多是词汇类型,所以我会选择正则表达式。

event
    =
    /(?x)
    'D' | 'U' | 'Z' | 'P' | 'L' | 'H' | 'x' | 'X' | 'T' | 'V' | 'l' | 'h' | 't' | 'v' | 'N' | 'A' | 'B' | 'F' | '?' | 'G' | 'R' | 'Q' | 'M'
    | 'ForceDown' | 'ForceUp' | 'ForceOff' | 'ForcePrior' | 'CompareLow' | 'CompareHigh' | 'CompareUnknown' | 'CompareOff'
    | 'CompareValid' | 'CompareLowWindow' | 'CompareHighWindow' | 'CompareOffWindow' | 'CompareValidWindow' | 'ForceUnknown'
    | 'LogicLow' | 'LogicHigh' | 'LogicZ' | 'Unknown' | 'ExpectHigh' | 'ExpectLow' | 'ExpectOff' | 'Marker'
    /
    ;
于 2019-11-15T11:23:55.473 回答