如何解析包含模式库的文本文件

时间:2014-12-22 10:24:02

标签: tcl

我是TCL脚本的新手,我想解析一个txt文件来创建一个基于2个字符串作为输入的模式列表。

我的文件如下:

keyw1: data1
keyw1: data2
keyw1: Arg1
:
:
keyword: Pattern2Extract
{
some_lines
keyw1: Arg1
keyw2: patternP1
{
some_lines
}
keyw2: Arg2
{
some_lines
}

keyw2: patternP2
{
some_lines
}
.
.
some_others blocks of declaration between braces {}
.
.
}

keyword: Pattern2Extract
{
some_lines
keyw1: Arg1
keyw2: Arg2
{
some_lines
}

keyw2: patternP1
{
some_lines
}
keyw2: patternP2
{
some_lines
}

.
.
some_others blocks of declaration between braces {}
.
.
}

所以,我想输出2个' Pattern2Extract'

的列表
  • list1:如果在花括号{}
  • 之间的结构中找到Arg1
  • list2:如果arg1和arg2都在花括号{}
  • 之间的结构中分组

我已尝试lsearchlindex并且它正在为list1工作,但我不知道如何为list2执行此操作。< / p>

这是我的剧本:

proc inst_nm {inpFile outFile} {
    set chanId [open $inpFile r]
    set data [list]
    while {[gets $chanId line] != -1} {
        lappend data $line
    }
    close $chanId
    foreach dt $data {
            set MasDat [lindex $dt 0]
            set pinDat [lindex $dt 1]
    }   
        set intId [open "./filetoparse.txt" r]
    set instDat [list]
    while {[gets $intId line] != -1} {
        lappend instDat $line
    }
    close $intId
    set writeId [open $outFile a]
    set MasterList [lreplace  [lsearch -all  $instDat *$MasDat*] 0 0]
    foreach elem $MasterList {
        set cellLn   [lindex [split [lindex $instDat $elem ] ":"] 1]
        set instName [lindex [split [lindex $instDat [expr $elem -5]] ":"] 1]
        set PinLn    [lindex [split [lindex $instDat [expr $elem +1]] ":"] 1]
        foreach ele $PinLn {
            if {"$ele"=="$pinDat" } { 
                puts $writeId "$instName $pinDat $cellLn"   
            } else {
                puts $writeId "$instName $ele $cellLn" 
            }
        }
    } 
    close $writeId
}
inst_nm [lindex $::argv 0] [lindex $::argv 1]

3 个答案:

答案 0 :(得分:0)

它有助于将代码分解为另一个proc。在Tcl中,proc必须在你调用它之前声明。数据文件没有反映您的解析器,并且MasterList可能正在删除您要查找的找到的项目。下面是您的解析器,其中包含反映其正在执行的示例文件。

#!/usr/bin/tclsh

proc findPin {MasDat pinDat instDat} {
    # set MasterList to the list of indexes found for *$MastDat*
    set MasterList [lsearch -glob -all  $instDat *$MasDat*]
    set found [list]

    # for each index number in MasterList
    foreach elem $MasterList {

        # n-5 (key: value(instName))
        # n-4
        # n-3
        # n-2
        # n-1
        # n (key: value(cellLn)
        # n+1 (key: value(PinLn)

        set cellLn   [lindex [split [lindex $instDat $elem ] ":"] 1]
        set instName [lindex [split [lindex $instDat [expr $elem -5]] ":"] 1]
        set PinLn    [lindex [split [lindex $instDat [expr $elem +1]] ":"] 1]

        foreach ele $PinLn {
            if {"$ele"=="$pinDat" } { 
                lappend found "$instName $pinDat $cellLn"
            }
        }
    }

    return $found
}

proc inst_nm {inpFile outFile} {

    # geta all lines in filestoparse.txt
    set intId [open "./filetoparse.txt" r]
    set instDat [list]
    while {[gets $intId line] != -1} {
        lappend instDat $line
    }
    close $intId

    set writeId [open $outFile a]

    # Search each line in inpFile
    set chanId [open $inpFile r]
    while {[gets $chanId line] != -1} {
        set MasDat [lindex $line 0]
        set pinDat [lindex $line 1]
        foreach {item} [findPin $MasDat $pinDat $instDat] {
             puts $writeId $item
        }
    }

    close $chanId
    close $writeId
}

inst_nm [lindex $::argv 0] [lindex $::argv 1]

filetoparse.txt

INST_NAME:MyInst
unknown-1
unknown-2
unknown-3
unknown-4
CELL_LN:MyCellLn
PIN_LN:pin1 pin2 pin3 pin4 pin5

unknown...

INST_NAME:TestInst
unknown-1
unknown-2
unknown-3
unknown-4
CELL_LN:TestCell
PIN_LN:test1 test2 test3

inputfile.txt

MyCellLn pin4
MyCellLn pin25
TestCell test1
TestCell test10
MyCellLn pin3

输出:

% ./keylist.tcl inputfile.txt keylist_found.txt
% cat keylist_found.txt
MyInst pin4 MyCellLn
TestInst test1 TestCell
MyInst pin3 MyCellLn

答案 1 :(得分:0)

目前,inpFile可能有很多行,比如$ MastDat $ pinDat,我需要收集每对对应的instDat($ MastDat,$ pinDat)。 在file_to_parse中,我们知道instName在$ MastDat之前排在第五行。但是,我们不知道包含$ pinDat声明的行的位置,这种模式可能存在于实例部分中:

keyword: Pattern2Extract { some_lines keyw1: Arg1 keyw2: patternP1 { some_lines } keyw2: Arg2 { some_lines } keyw2: patternP2 { some_lines } . . some_others blocks of declaration between braces {} . . }

所以,在list2中我们应该在找到$ pinDat的地方获取所有insName 谢谢你的帮助

答案 2 :(得分:0)

实际上,我只是打印&#39; $ instName&#39;来自inpFile&$ 39; $ cellLn $ pinDat&#39;

的每一对线

filetoparse.txt:

    INST_NAME:Inst1
    {
    4 unknown lines
    CELL_LN: Cell1
    other unkown lines
    PIN_LN:pin1 
    unkown
    PIN_LN:pin5
    unknown...
    }

    INST_NAME:Inst2
    {
    4 unknown lines
    CELL_LN: Cell1
    other unkown lines
    PIN_LN:pin3
    unkown
    PIN_LN:pin5
    unknown...
    }

    INST_NAME:Inst3
    {
    4 unknown lines
    CELL_LN: Cell2
    other unkown lines
    PIN_LN:pin2
    unkown
    PIN_LN:pin4
    unknown...
    }

INST_NAME:Inst4
    {
    4 unknown lines
    CELL_LN: Cell2
    other unkown lines
    PIN_LN:pin5
    unkown
    PIN_LN:pin2
    unknown...
    }

inpFile.txt

cell1 pin1
cell2 pin2

所以,我想在OutputFile中有类似的东西:

- for cell1 pin1:
list1: {Inst1 Inst2}
list2: {Inst1}

- for cell2 pin2:
list1: {Inst3 Inst4}
list2: {Inst3 Inst4}

感谢您的帮助,