TCL 中面临的问题:引号中的列表元素后跟“;”而不是 space

Issue faced in TCL: list element in quotes followed by ";" instead of space

我是TCL的新手,正在尝试自学脚本。

我正在尝试解析一个文件并尝试先将每一行分开,然后将每一行分解为每个单词。但是,我的执行结束时给我以下消息:

  DISPLAY: output = "TDO";


list element in quotes followed by ";" instead of space
 while executing


"foreach word $line {
                     puts $word
             }"
 invoked from within


"if {[file exists default_xl.vif]} {
     puts "\ndefault_xl.vif exists"
     set fp [open "default_xl.vif" r]
     #set file_data [read $fp]
     #set lines [split ..."
 (file "second.tcl" line 96)

这是导致问题的代码片段:

while {[gets $fp line] > -1} {       
             set word_len [split $line "\n"]
             puts -nonewline "DISPLAY: "
             puts $line
             foreach word $line {
                     puts $word
             }
     }

以下是我试图解析的文件中的行:

input = "TMS" sync="fine_delay_clk";
output = "TDO";
 output = "veloce_outclk";

显示 "output = "TDO"" 的行是造成问题的行。

我无法弄清楚这里出了什么问题,因为该行之前的行可以正常工作,但以输出开头的行不起作用。

谁能帮帮我。

您的问题正是错误消息所说的:引号中的列表元素 ("TDO") 后跟一个分号。这是非法的列表语法。之前的行很好,因为以分号 (sync="fine_delay_clk";) 结尾的单词不以双引号开头。如果您在等号周围添加空格,如果您尝试将其用作列表,您也会遇到该行的问题。

先把行分开,就可以了(假设line包含output = "TDO";):

foreach word [split $line] {
    puts $word
}
# output:
output
=
"TDO";

注1:假设等号左边的名字和双引号内的字符串都不包含空格字符。如果他们这样做,您将不得不使用其他方法,例如在等号上拆分。

注意 2:将行作为单词列表遍历并不是解析似乎是属性分配的真正好方法。这样的代码可能会更好(假设每个值都被引用,并且双引号不会出现在值中,即使是转义引号(\")):

foreach {- name value} [regexp -inline -all {(\w+)\s*=\s*"([^"]*)"} $line] {
    puts "$name -- $value"
}

或者像这样(假设等号和分号从不出现在名称或值中):

foreach {name value} [string map {= { } ; {}} $line] {
    puts "$name -- $value"
}

但最好的方法究竟是什么取决于您的需要和要求。在大多数情况下,必须定制数据预处理以适应实际数据;在大多数情况下,这样做很容易。

注意 3:Tcl 不是为了妨碍您而设计的。如果您告诉 Tcl 将列表操作应用于非纯列表形式的数据,它会尽力而为并在不得不放弃时报告(当然您也可以先问:string is list $line 会告诉你是否可以将字符串作为列表处理)。您有责任确保您使用的每条数据都格式正确且在语义上适合您要对其执行的操作。幸运的是,这在 Tcl 中比在其他一些语言中要容易得多。

文档:foreach, puts, regexp, split, string