tcl 文本处理 - 根据用户定义的值重新排列行和列中的值 [英] tcl text processing - rearrange values in rows and columns based on user defined value

查看:40
本文介绍了tcl 文本处理 - 根据用户定义的值重新排列行和列中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 tcl 的新手,想在一个简单案例的文本处理中使用它.以下格式是用于芯片设计的 Liberty(.lib 文件).对此我真的很感激.

I am new to tcl and would like to use it in text processing of a simple case. The following format is in Liberty (.lib file) which is used in chip design. I would be truly indebted for any help on this.

这是我的文件的片段(仅对值"进行文本处理)

Here is a snippet of my file (text processing to be done only on the "values")

timing () {  
    related_pin : "clk";  
    timing_type : setup_rising;  
    rise_constraint (constraint_template_5X5) {  
      index_1 ("0.01, 0.05, 0.12, 0.2, 0.4");  
      index_2 ("0.005, 0.025, 0.06, 0.1, 0.3");  
      index_3 ("0.084, 0.84, 3.36, 8.4, 13.44") ;  
      values ( \  
        "1.1, 1.2, 1.3, 1.4, 1.5", \        
        "2.1, 2.2, 2.3, 2.4, 2.5", \  
        "3.1, 3.2, 3.3, 3.4, 3.5", \  
        "4.1, 4.2, 4.3, 4.4, 4.5", \  
        "5.1, 5.2, 5.3, 5.4, 5.5", \  
        "6.1, 6.2, 6.3, 6.4, 6.5", \  
        "7.1 ,7.2, 7.3, 7.4, 7.5", \  
        "8.1, 8.2, 8.3, 8.4, 8.5", \  
        "9.1, 9.2, 9.3, 9.4, 9.5", \  
        "10.1,10.2,10.3,10.4,10.5", \  
        "11.1,11.2,11.3,11.4,11.5", \  
        "12.1,12.2,12.3,12.4,12.5", \  
        "13.1,13.2,13.3,13.4,13.5", \  
        "14.1,14.2,14.3,14.4,14.5", \  
        "15.1,15.2,15.3,15.4,15.5", \  
        "16.1,16.2,16.3,16.4,16.5", \  
        "17.1,17.2,17.3,17.4,17.5", \  
        "18.1,18.2,18.3,18.4,18.5", \  
        "19.1,19.2,19.3,19.4,19.5", \  
        "20.1,20.2,20.3,20.4,20.5", \  
        "21.1,21.2,21.3,21.4,21.5", \  
        "22.1,22.2,22.3,22.4,22.5", \  
        "23.1,23.2,23.3,23.4,23.5", \  
        "24.1,24.2,24.3,24.4,24.5", \  
        "25.1,25.2,25.3,25.4,25.5", \  
      );  
    } 

所以所有值"都是 25 行 x 5 列查找表格式,我希望将其更改为 5 行 x 5 列表格式.为此,我想在映射完成之前询问用户他/她想要 index_3 中的 5 个值中的哪一个(同时删除 index_3 行):

So all the "values" are in a 25 rows x 5 columns lookup table format which I wish to change to a 5 rows x 5 columns table format. To accomplish this, I would like to ask the user which of the 5 values in index_3 he/she wants before mapping is done as follows (while also removing the index_3 line):

C 是基于 index_3 的用户定义列:(0.084 的第 1 列,0.84 的第 2 列,3.36 的第 3 列,8.4 的第 4 列,13.44 的第 5 列).*用户只能选择1个值

C is the user defined column based on index_3: (column 1 for 0.084, column 2 for 0.84, column 3 for 3.36, column 4 for 8.4, column 5 for 13.44). *Only 1 value can be chosen by user

映射方案:

   1,C -> row 1 column 1  
   2,C -> row 2 column 1  
   3,C -> row 3 column 1  
   4,C -> row 4 column 1  
   5,C -> row 5 column 1  
   6,C -> row 1 column 2  
   7,C -> row 2 column 2  
   8,C -> row 3 column 2

等等..

例如,假设用户选择第 1 列(来自 index_3 的值 0.084)--> '选择''values' 中数据的整个第一列进行文本处理/排列

For EXAMPLE, say a user chooses column 1 (value 0.084 from index_3) --> which 'chooses' entire 1st column of the data in 'values' to be text processed/arranged

因此,tcl 基于映射方案完成的文本处理结果应该是:

Hence, resulting text processing done by tcl based on the mapping scheme should be:

index_1 ("0.01, 0.05, 0.12, 0.2, 0.4");  
index_2 ("0.005, 0.025, 0.06, 0.1, 0.3");

 values ( \  
        "1.1, 6.1, 11.1, 16.1, 21.1", \  
        "2.1, 7.1, 12.1, 17.1, 22.1", \  
        "3.1, 8.1, 13.1, 18.1, 23.1", \  
        "4.1, 9.1, 14.1, 19.1, 24.1", \  
        "5.1, 10.1,15.1, 20.1, 25.1", \  
  ); 

我的策略是这样的:

  1. 搜索rise_constraint"到零,在整个文件中文本处理哪些值

  1. search for "rise_constraint" to zero in on which values to text process in the entire file

注释掉index_3 (...)"行;重印处理后的文件行首和行尾添加/*和*/(可选)

comment out line "index_3 (...)"; add /* and */ at beginning and end of line in reprinted processed file (optional)

根据所选的 Index_3 值(用户定义的列选择")将值"从 25 行 x 5 列表转换为 5 行 x 5 列表

convert 'values' from 25 rows x 5 columns table to 5 rows x 5 columns table BASED on Index_3 value chosen ("user defined column choice")

按原样重新打印其他行(包括处理过的文本值")

re-print other lines as is (including the text processed 'values')

我尽力解释我的编码请求.你们中的任何人都可以帮我想出在 tcl 中我可以做这样的文本处理的正确方法吗?非常感谢!!

I tried my very best to explain my coding request. Can any of you meastros please help me think of a proper way in tcl I can do such text processing? Many thanks!!

推荐答案

我终于对这个真正感兴趣了,并根据我更好的判断编写了一个完整的答案.我不会以任何方式记录它.阅读它,阅读文档,了解您不理解的命令,然后来提问.

I finally got really interested in this, and against my better judgement coded up a complete answer. I'm not going to document it in any way. Read it, read the docs for commands you don't understand, then come and ask questions.

查看您的自由文件,我发现它非常接近原生 Tcl 语法.所以你可以创建一些名为timing"、rise_constraint"等的程序,基本上就可以作为脚本运行了.

Looking at your liberty file, I see it's very close to native Tcl syntax. So you can create a few procedures named "timing", "rise_constraint", etc, and you can basically run it as a script.

package require struct::list

######################################################################
proc main {libfile} {
    global lines idx3 vals
    set lines [list]
    set idx3 [list]
    set vals [list]

    evaluate_liberty $libfile

    set idx [get_choice "select an index_3 value: " $idx3]
    set column [struct::list mapfor elem $vals {lindex $elem $idx}]

    set newvalues [list]
    for {set i 0} {$i < 5} {incr i} {
        lappend newvalues [lrange $column [expr {5*$i}] [expr {5*($i+1)-1}]]
    }

    print_liberty $newvalues
}

######################################################################
proc evaluate_liberty {libfile} {
    set fh [open $libfile r]
    # handle known syntax error in liberty file
    set contents [string map {\", \"} [read -nonewline $fh]]
    regsub -all -line {\s+$} $contents {} contents
    close $fh

    uplevel #0 $contents
}

proc get_choice {prompt values} {
    while {1} {
        for {set i 0} {$i < [llength $values]} {incr i} {
            puts stderr [format "%2d. %s" $i [lindex $values $i]]
        }
        puts -nonewline stderr $prompt
        gets stdin answer
        if {[string is integer -strict $answer]} {
            if {0 <= $answer && $answer < [llength $values]} {
                return $answer
            }
        }
    }
}

proc print_liberty {newvalues} {
    global lines close_braces
    puts [join $lines \n]

    puts "values ( \\"
    foreach elem $newvalues {
        puts [format "\"%s\", \\" [join $elem {, }]]
    }
    puts ");"

    for {set i 1} {$i <= $close_braces} {incr i} {
        puts [format %c 125]
    }
}

######################################################################
# define DSL
proc timing {label script} {
    lappend ::lines [format "timing %s %c" $label 123]
    incr ::close_braces
    uplevel 1 $script
}

proc rise_constraint {label script} {
    lappend ::lines [format "rise_constraint %s %c" $label 123]
    incr ::close_braces
    uplevel 1 $script
}

proc index_3 {args} {
    global idx3
    foreach item $args {
        lappend idx3 [string map {( "" \" "" , "" ) ""} $item]
    }
}

proc values {args} {
    global vals
    foreach set [lrange $args 1 end-1] {
        lappend vals [split [regsub -all {\s*,\s*} $set { }]]
    }
}

rename unknown system_unknown

proc unknown args {
    lappend ::lines "[join $args];"
}

######################################################################
if {$argc == 0} {
    puts "usage: $argv0 filename.lib"
    exit
}

set libfile [lindex $argv 0]
if {![file exists $libfile]} {
    error "no such file: $libfile"
}

main $libfile

运行:

$ tclsh liberty.tcl test.lib  > newlib.lib
 0. 0.084
 1. 0.84
 2. 3.36
 3. 8.4
 4. 13.44
select an index_3 value: 0

$ cat newlib.lib 
timing () {
related_pin : clk;
timing_type : setup_rising;
rise_constraint (constraint_template_5X5) {
index_1 ("0.01, 0.05, 0.12, 0.2, 0.4");
index_2 ("0.005, 0.025, 0.06, 0.1, 0.3");
values ( \
"1.1, 2.1, 3.1, 4.1, 5.1", \
"6.1, 7.1, 8.1, 9.1, 10.1", \
"11.1, 12.1, 13.1, 14.1, 15.1", \
"16.1, 17.1, 18.1, 19.1, 20.1", \
"21.1, 22.1, 23.1, 24.1, 25.1", \
);
}
}

你确实失去了所有漂亮的缩进,但你得到了你想要的值.

You do lose all your nice indentation, but you get the values you want.

这篇关于tcl 文本处理 - 根据用户定义的值重新排列行和列中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆