我是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“” 这一行是引起麻烦的行。
我无法弄清楚这里出了什么问题,因为该行之前的行可以正常工作,但以输出开头的行不起作用。
任何人都可以在这里帮忙。
答案 0 :(得分:3)
您的问题正是错误消息所说的:引号("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中比在其他语言中容易得多。