TCL语法自整理
参考:简矽芯学堂,Vivado/Tcl零基础入门与案例实战
这篇文章主要是为了方便大家可以快速查到相关命令 有的高级语法也不是很全(至少我是没遇到过),
如有错误,请各位及时在评论区或私我改正
1.基本语法
脚本,命令和单词符
一个tcl脚本可以有一个或多个命令。命令之间必须用换行符或分号隔开
set a 1
set x 10;
变量置换
由$标记
expr表示后面是一个整体
set y $x+100 //y的值是10+100 字符串
set y [expr $x+100] //y=110
反斜杠置换(转义字符)
TCL中反斜杠置换类似于C语言中的反斜杠置换,主要用于在单词符号中插入诸如换行符,空格,[,$等被TCL解释器当作特殊符号对待的字符
$不再当作特殊字符 []也不具有特殊含义
set msg mult\ space //msg的值为mult space
set msga money\ \$3333\ \A\[2] //money $3333 A[2]
反斜杠置换表:
Backslash content | Replaced By |
---|---|
\a | 警告音 |
\b | 删除 |
\f | 换页符 |
\n | 换行符 |
\r | 回车 |
\t | 制表符(Tab) |
\v | 垂直制表符 |
\ooo | 八进制格式(o可以是1 2 3) |
\xhh | 十六进制格式(h可以任意个) |
\ (newline space) | 空格符 |
(如果还有经常使用的字符以后会更新。。)
反斜杠中的变量置换
set a \x48 //十六进制的48正好是72 对应ASCII码中的H
H
set a \110 //八进制的110是72 ,也是H
H
set a [expr \2+3] //转到下一行继续
双引号和花括号
set x 100
set y "$x ddd" //""内部作为一个整体,执行特殊字符命令,执行结果为 100 ddd
set y {/n$x[expr 10+100]} // /n$x[expr 10+100](把花括号内部看成一个整体,但不执行特殊字符命令)
此处做一个小结:
字符 | 含义 |
---|---|
$ | 展开变量的值 |
[] | 命令或调用过程的结果值 |
“” | 内容作为一个整体,内部可执行$ [] |
{} | 内容作为一个整体,内部不可执行$ [] |
\ | 转义字符 |
2.变量
set 变量名 值
其实前面也理解的差不多了
那么请在TCL环境中输入如下命令:
set Name jack
puts $Name
set x puts
set y $Name
$x "Hello $y"
3.数据类型
TCL的数据类型实际上只有一种:字符串
TCL是支持数值计算的(包括数学函数),不过仅能用在expr命令中
set x 100
set y [expr $x + 1] //101 赋值给y
incr y -2 //incr是加减法命令 这里运算是101 -2 = 9
expr double($x) //转换为双精度浮点型
set y [expr $x*2.3] //x*2.3复制给y
expr abs(sin($x)) //计算sinx后计算绝对值
set z[format "This is %-8.2f!" $y] //This is 230
4.数据结构
列表
列表是TCL里面功能非常强大非常灵活的一种数据结构
例4-1:
//各个值按序排列
//创建一个list 元素为arg1 arg2 arg3 之后这个list赋值给x再用命令置换符[]置换成元素,即给x赋值为arg1,arg2,arg3
set x [list arg1 arg2 arg3]
//按指定分隔符拆分一个字符串
set Str "1,2,3" //给Str赋值为1,2,3(整体)
set x [split $Str ","] //将逗号去掉,将字符串分开作为list 输出结果为 1 2 3
例4-2:
set x "1 2 3 4" //x赋值1 2 3 4
llength $x //计算x中元素个数 返回值为4
split $x "" //将x中的字符串分开作为list 返回结果是1 2 3 4
set x " 1 2 3 4" //x赋值 1 2 3 4 (带个空格)
llength $x //计算x中元素个数 返回值为4
split $x "" //将x中的字符串分开作为list 返回结果是{} 1 2 3 4
set x [list 1 2 3 "" 4] //创建一个list 1 2 3 "" 4 返回结果是 1 2 3 {} 4
llength $x //5个元素
split $x "" //1 2 3 {} 4
数组提供一个或多个值到另一个值的映射,或者这种映射的集合
例4-3
set Data(1) 1.0 //生成一个Data数组,同时再数组中生成一个名为1的数组元素,并将值设置为1.0
set Data(-2.3) abc
set Data(Name) Markel
set Data() "Hello,"
set Data( ) "a space"
set Data( "My Name" ) "Markel"
puts "$Data() $Data( "My Name" )" //Hello, Markel
set Data(hello,$Data(Name)) "$Data() $Data( "My Name" )"
puts $Data(hello,Markel) //Hello Markel!
数组
在C语言中,数组的索引只能是整数,但在Tcl中任何合法的字符串都能作为数组名或元素名,也可以作为变量值。
数组可以通过set命令单独设置,也可以通过array set命令同时设置多个元素。
set myArray(0) "value0"
set myArray(1) "value1"
#等价于
array set myArray 0 "value0" 1 "value1"
#获得数组结果
set getarray [array get height]
#删除数组元素
unset myArray(0)
#检查数组是否存在
if {[array exists myArray(0)]} {
puts "Array element exists"
} else {
puts "Array element does not exist"
}
#遍历数组
foreach index [array names myArray] {
set value [myArray($index)]
puts "Index: $index, Value: $value"
}
5.表达式
操作数
TCL的操作数通常是整数或实数。整数一般是十进制的 0开头是八进制 0x是十六进制(和C语言一样)
运算符和优先级
也和C语言一样,不做详细赘述
6.控制结构—条件分支
if语句
if {expr}{
......
}else if {expr2}{
......
}else{
......
}
for循环
for {start_expr}{test_condition}{next or step}{
body;
}
//举例
for {set x 0}{$x<10}{incr x}{
puts"x is $x"
}
foreach循环
set NameList " John Mark Jack Bill"
foreach Name $NameList{
puts "He is $Name"
}
扩展
foreach {Name Job}{John Engineer Mark Manager}{
puts "$Name is $Job\n"
}
foreach Name "John Mark" Job "Engineer Manager"{
puts "$Name is $Job\n"
}
//输出结果均为:
//John is Engineer
//Mark is Manager
while循环
while {test_condition}{
body;
}
7.程序结构
source 外部执行 可用于将文件读入
global 声明全局变量
load 加载外部函数库
过程语句proc 类似C语言函数 需要通过return返回过程值
举例 比较大小
proc get_max {num1 num2} {
if {$num1 > $num2} {
set res $num1
} else {
set res $num2
}
return $res
}
set num1 10
set num2 20
set max [get_max $num1 $num2]
puts "最大的数是: $max"
带参数名列表的proc
proc my_proc {arg1 arg2} {
return [expr {$arg1 + $arg2}]
}
set result [my_proc 10 20]
puts "结果是: $result"
如果没有return 返回值为最后一条命令的返回值。
在proc中的是局部变量 外部是全局变量(和C语言类似 按C语言方式理解就行)
upvar命令(待续 目前还没有用到)
8.命名空间(待续 目前还没有用到)
(这个在DFT或后端中的脚本我目前没遇到过)
9.文件
#文件exists:检查文件或目录是否存在
if {[file exists filename]} {
puts "文件存在"
} else {
puts "文件不存在"
}
#删除文件
file delete filename
#重命名文件
file rename oldname newname
复制文件
file copy source destination
#移动文件
file move source destination
#打开文件,用于读取或写入文件
set f [open filename r] # 读取模式
set f [open filename w] # 写入模式
set f [open filename a] # 追加模式
#从文件中读取数据
set line [read $f]
#向文件中写入数据
write $f "Hello, World!"
#关闭文件
close $f
文件权限
#改变文件权限
file chmod mode filename
#改变文件所有者
file chown owner filename
目录操作
#创建目录
file mkdir directory
#删除目录
file rmdir directory
#列出目录内容
set dirs [file list directory]
#改变当前工作目录
file cd directory
#打印当前工作目录
file pwd
#获取文件的路径
set path [file path filename]
#将目录和文件名组合成路径
set fullPath [file join directory filename]
#将路径分解为目录和文件名
set dir [file split $path .]
10.正则匹配相关
regexp
基本语法
regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?
exp: 正则表达式模式。
string: 要匹配的字符串。
matchVar: 用于存储整个匹配结果的变量。
subMatchVar: 用于存储子匹配结果的变量。
-nocase: 忽略大小写。
-indices: 返回匹配的起始和结束索引。
-inline: 直接返回匹配结果而不是通过变量。
-all: 匹配所有符合模式的部分。
示例:
set str "Hello, World!"
regexp {Hello} $str result
puts $result ;# 输出:1
#忽略大小写
set str "Hello, World!"
regexp -nocase {hello} $str result
puts $result ;# 输出:1
#获取匹配结果
set str "Hello, World!"
regexp {(Hello), (World)} $str match fullMatch1 fullMatch2
puts $match ;# 输出:1
puts $fullMatch1 ;# 输出:Hello
puts $fullMatch2 ;# 输出:World
#返回匹配的起始和结束索引
set str "Hello, World!"
regexp -indices {World} $str match indices
puts $match ;# 输出:1
puts $indices ;# 输出:{7 11}
#匹配所有符合模式的部分
set str "one two three"
regexp -all -inline {\w+} $str
# 结果:{one} {two} {three}
高级方法:
在正则表达式中,\w+ 和 \d+ 是常用的模式匹配符,用于匹配特定类型的字符。以下是它们的详细解释:
\w+
\w: 匹配任何字母、数字或下划线字符。相当于字符类 [a-zA-Z0-9_]。
+: 匹配前面的字符一次或多次。
因此,\w+ 可以匹配一个或多个字母、数字或下划线。例如,abc123、hello_world 都能匹配
\d+
\d: 匹配任何数字字符。相当于字符类 [0-9]。
+: 匹配前面的字符一次或多次。
因此,\d+ 可以匹配一个或多个数字字符。例如,123、4567 都能匹配。
举例说明:
#使用正则表达式分组
set str "abc 123 def 456"
regexp {(\w+) (\d+)} $str match word number
puts $word ;# 输出:abc
puts $number ;# 输出:123
#多次匹配
set str "one two three"
set matches [regexp -all -inline {(\w+)} $str]
foreach match $matches {
puts $match
}
# 输出:
# one
# two
# three
glob
TCL 中的 glob 命令用于匹配文件路径名,类似于 Unix shell 中的文件名通配符。它允许你查找匹配特定模式的文件和目录。
glob ?switches? patternList
patternList: 要匹配的文件名模式,可以包含通配符(*、?、[])。
switches: 可选参数,用于控制匹配行为。
-directory dir: 指定搜索的目录。
-types typeList: 只匹配特定类型(f 为文件,d 为目录)。
-nocomplain: 如果没有匹配到文件,不会报错。
-path: 返回完整路径名。
-tails: 只返回文件名而不包括目录路径。
-join: 将匹配到的文件合并成一个字符串返回。
*: 匹配任意数量的字符。
?: 匹配任意单个字符。
[]: 匹配括号内的任意一个字符
示例:
#匹配当前目录下所有的文件
set files [glob *]
puts $files
#匹配特定目录下的所有文件
set files [glob -directory /path/to/dir *]
puts $files
#匹配特定类型(文件或目录)
set dirs [glob -types d *] #d是匹配目录 f是文件
puts $dirs
#返回匹配文件的完整路径
set files [glob -path *]
puts $files
#在没有匹配到文件时不报错
set files [glob -nocomplain *.nonexistent]
puts $files
#只返回文件名,不包括路径
set files [glob -tails -directory /path/to/dir *]
puts $files
#在一个目录中查找所有以 test 开头且以 .tcl 结尾的文件,并返回它们的完整路径:
set files [glob -path -directory /path/to/dir test*.tcl]
foreach file $files {
puts $file
}