You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ActiveState TCL中括号内非贪婪捕获失效问题求助

TCL正则匹配Verilog实例时的贪婪匹配问题修复

问题重现

在Windows上使用ActiveState TCL提取Verilog模块实例时,试图通过#\(.*?\)实现括号内非贪婪匹配,却出现贪婪匹配覆盖后续语句的情况,输出与预期不符。

原代码

proc extract_verilog_instances {text} {

    set rexp {(\w+)\s+(\#\s*\((?:.*?)\)\s*)?(\w+(?:\[\d+\])?)\s*\(}

    # rexp will match any of the following statement types:
    #
    #   module_name instance_name ( 
    #   module_name instance_name[0] (
    #   module_name #(parameter1, parameter2) instance_name (
    #   module_name #(parameter1, parameter2) instance_name[0] (


    set regrun [regexp -inline -all -indices -expanded $rexp $text]

    foreach {m0 m1 m2 m3} $regrun {
        set start_index    [lindex $m0 0]
        set end_index      [lindex $m0 1]
        set module   [string range $text [lindex $m1 0] [lindex $m1 1]]
        set instance [string range $text [lindex $m3 0] [lindex $m3 1]]

       puts "module:$module instance:$instance"
    }
}

set vlog {
    
    second_module #(2) inst2 (.in2(sig2), .out2(sig3));

    third_module inst3 (.in3(sig3), .out3(sig4));

    fourth_module #(.in4_clk_freq(50), .in4_rst_val(1'b0)) inst4 (.in4_clk(clk), .in4_rst(rst), .in4_in1(sig4), .in4_in2(sig5), .out4(sig6));
}

extract_verilog_instances $vlog

预期输出

module:second_module instance:inst2
module:third_module instance:inst3
module:fourth_module instance:inst4

实际输出

module:second_module instance:inst4

错误原因

  1. 非贪婪匹配仍跨范围:.*?虽为非贪婪模式,但会匹配所有字符(包括换行),导致从第一个#(开始,一直匹配到最后一个),覆盖中间所有语句。
  2. 未处理嵌套括号:Verilog参数中存在嵌套括号(如.in4_clk_freq(50)),原正则的.*?会在遇到第一个)时停止,但结合整体正则结构,最终仍会扩大匹配范围。
  3. 正则无语句边界限制:原正则未限制匹配仅在单个实例语句内进行,导致跨多个实例匹配。

修复方案

修改正则表达式解决上述问题:

  1. 用[^\n]*?替代.*?,限制匹配不跨换行,确保每个实例语句独立匹配。
  2. 针对嵌套括号,使用递归匹配逻辑:(?:[^()]|\((?:[^()]|\([^()]*\))*\))*,精准匹配括号内内容(包括嵌套括号)。
  3. 调整空白匹配逻辑,避免过度匹配。

修复后的代码

proc extract_verilog_instances {text} {
    # 修正后的正则:处理嵌套括号,限制不跨换行,精准匹配每个实例
    set rexp {(\w+)\s+(#\s*\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\)\s*)?(\w+(?:\[\d+\])?)\s*\(}

    set regrun [regexp -inline -all -indices -expanded $rexp $text]

    foreach {m0 m1 m2 m3} $regrun {
        set module   [string range $text [lindex $m1 0] [lindex $m1 1]]
        set instance [string range $text [lindex $m3 0] [lindex $m3 1]]

        puts "module:$module instance:$instance"
    }
}

set vlog {
    
    second_module #(2) inst2 (.in2(sig2), .out2(sig3));

    third_module inst3 (.in3(sig3), .out3(sig4));

    fourth_module #(.in4_clk_freq(50), .in4_rst_val(1'b0)) inst4 (.in4_clk(clk), .in4_rst(rst), .in4_in1(sig4), .in4_in2(sig5), .out4(sig6));
}

extract_verilog_instances $vlog

修复后输出

module:second_module instance:inst2
module:third_module instance:inst3
module:fourth_module instance:inst4

内容的提问来源于stack exchange,提问作者Bill Moore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:58:09