首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TatSu:如何优化以下语法逻辑以加快解析时间?

TatSu:如何优化以下语法逻辑以加快解析时间?
EN

Stack Overflow用户
提问于 2019-11-19 04:37:18
回答 2查看 179关注 0票数 1

我在TatSu中有以下语法。为了减少解析时间,我实现了裁剪操作(即,一旦看到特定的令牌,就提交到特定的规则选项)。

然而,我仍然看到长的运行时。在一个大约830K行的文件上,它大约需要25分钟(没有剪切表达式,它接近40分钟)。我认为进一步改进是可能的,但我不知道如何更好地重写以下逻辑。

我认为主要的问题是占用大量时间(通过观察TatSu语法匹配跟踪)是vec_data_string/vec_data_string。对于如何进一步改善这一点,有什么建议吗?

代码语言:javascript
复制
pattern_stmt
    =
    (('V'|'C')&'{' | 'Vector' | 'Condition') '{' ~ {vec_data_block} '}'
    | ('Macro' | 'Call') identifier '{' ~ {vec_data_block} '}'
    | ('Macro' | 'Call') identifier ';'
    | ('W' | 'WaveformTable') ~ identifier ';'
    | annotation
    | 'Loop' ~ integer '{' ~ [pattern_statements] '}'
    | 'MatchLoop' ~ ('Infinite' | integer) ~ '{' ~ pattern_statements 'BreakPoint' ~ '{' ~ pattern_statements '}' ~ '}'
    | ('GoTo' | 'ScanChain') ~ identifier ';'
    | 'BreakPoint' '{' ~ pattern_statements '}'
    | ('BreakPoint' | 'IddqTestPoint' | 'Stop') ~ ';'
    | 'TimeUnit' ~ "'" ~ number [siunit] "'" ~ ';'
    ;
vec_data_block
        =
        | signal_reference_expr '=' ~ vec_data_string ';'
        signal_reference_expr '{' ~ {vec_data_strings} '}'
    vec_data_strings
        =
        {vec_data_string ';'}+
        ;
    vec_data_string
        =
        {wfc_data}+
        | {hex_data}+
        | {dec_data}+
        ;
    wfc_data
        =
        ['\\r' ~ integer] wfcs
        | hex_mode
        | dec_mode
        ;
    hex_data
        =
        ['\\r' ~ integer] hex
        | wfc_mode
        | dec_mode
        ;
    dec_data
        =
        ['\\r' ~ integer] integer
        | wfc_mode
        | hex_mode
        ;
    hex_mode
        =
        '\\h' ~ [wfcs] {hex_data}+
        ;
    wfc_mode
        =
        '\\w' ~ {wfc_data}+
        ;
    dec_mode
        =
        '\\d' ~ [wfcs] {dec_data}+
        ;
    wfcs
        =
        /[a-zA-Z0-9#%]+/
        ;
    hex
        =
        /[0-9a-fA-F]+/
        ;

    integer::int
        =
        /\d+/
        ;

我的测试文件有很多这样的序列:

代码语言:javascript
复制
 "ALLPIs" = 001 \r27 Z 10001ZZ0 \r22 Z 0 \r22 Z 0 \r22 Z 0 \r20 Z 1111 \r133 Z 0Z0010; 
    "ALLPOs" = \r243 X ; 
    "ALLCIOs" = \r557 Z 0 \r10 Z 0ZZ0001001 \r19 Z ;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-20 14:41:35

通过分解一些常见的子表达式,您可以大大减少调用的次数。

例如:

代码语言:javascript
复制
    | ('Macro' | 'Call') identifier '{' ~ {vec_data_block} '}'
    | ('Macro' | 'Call') identifier ';'

可以写成:

代码语言:javascript
复制
    | ('Macro' | 'Call') identifier (';' | '{' ~ {vec_data_block} '}')

使用TatSu对保留字的支持也会有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2019-11-19 10:21:16

通过执行以下两项操作,我能够显著降低运行时(约50%):

  1. ,而不是试图解析来为长字符串创建AST。我只是用正则表达式一读一遍。稍后我将对字符串进行后处理。
  2. 我注意到大部分时间是由{vec_data_block}占用的。每次匹配之后,它将尝试再进行4次匹配,并在继续匹配“}”令牌之前失败。为了解决这个问题,我添加了一个查找规则(& '}‘),如果它看到了’}‘令牌,就会传递它。这种行为类似于“剪切”表达式,并防止发生4次失败的匹配+递归。这是加速的主要部分。不确定这是否是正确的方法,但它是有效的。

下面是两个变化的更新语法:

代码语言:javascript
复制
pattern_stmt
    =
    (('V'|'C')&'{' | 'Vector' | 'Condition') '{' ~ {vec_data_block} '}'
    | ('Macro' | 'Call') identifier '{' ~ {vec_data_block} '}'
    | ('Macro' | 'Call') identifier ';'
    | ('W' | 'WaveformTable') ~ identifier ';'
    | annotation
    | 'Loop' ~ integer '{' ~ [pattern_statements] '}'
    | 'MatchLoop' ~ ('Infinite' | integer) ~ '{' ~ pattern_statements 'BreakPoint' ~ '{' ~ pattern_statements '}' ~ '}'
    | ('GoTo' | 'ScanChain') ~ identifier ';'
    | 'BreakPoint' '{' ~ pattern_statements '}'
    | ('BreakPoint' | 'IddqTestPoint' | 'Stop') ~ ';'
    | 'TimeUnit' ~ "'" ~ number [siunit] "'" ~ ';'
    ;
vec_data_block
    =
    | &'}'  <-- Short circuit the next 4 matches if lookahead and find a '}'
    | signal_reference_expr '=' ~ vec_data_string ';'
    | signal_reference_expr '{' ~ {vec_data_strings} '}'
    | annotation
    | non_cyclized_data
    ;
non_cyclized_data
    =
    '@' integer event_pair ';'
     | '@' integer '{' ~ ';'.{event_pair} '}'
    ;
event_pair
    =
    signal_reference_expr '=' ~ event
    | annotation
    ;
vec_data_strings
    =
    {vec_data_string ';'}+
    | annotation
    ;
foo
    =
    /[0-9A-Za-z#%\\r\\h\\d\\w]+/
    ;
vec_data_string
    =
    {foo}+   <-- Just read the tokens into one big string for post-processing later.
    ;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58926723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档