tcl脚本(一) - 基本语法

news/2024/10/30 9:30:06/

文章目录

  • 介绍
  • 置换
    • 普通置换
    • 变量置换
    • 命令置换
    • 反斜杠 \ 置换
    • 花括号{ }和双引号“”
      • 双引号""
      • 花括号{ }
  • 变量
    • 数组
    • 集合
  • 控制流
    • if 命令
    • while命令
    • for循环命令
    • foreach循环命令
    • switch命令
    • 其他命令
  • 过程
    • proc 命令
    • 局部变量和全局变量
  • 字符串操作
    • format命令
    • scan命令
    • regexp命令
  • 文件访问
    • open命令
    • gets命令
    • puts命令
    • flush field
    • glob命令
    • file命令

实际脚本用例的讲解请看:tcl脚本用于questasim回归测试

介绍

TCL是一种解释执行的脚本语言。提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。

TCL的解释器是用一个C\C++语言的过程库实现的,某种意义上,可以将TCL看做一个C库,每个应用程序都可以根据自己的需要对TCL语言进行扩展。

扩展后的TCL语言将继承TCL核心部分的所有功能,包括核心命令、控制结构、数据类型、对过程的支持等。

学习核心:

  • TCL脚本执行依赖于解释器(逐行执行,没有编译这回事);
  • TCL有效命令行以命令+字符串(结合空间间隔符形成);
  • 明白**置换( $ 、[ ]、 \ )引用( " " 、{ } )**的差别与联系;
  • 明白命令eval、expr、source、exec的差别;
  • 掌握 { * } 配合glob等返回list后的操作。

置换

  • 一个TCL脚本可以包含一个或多个命令。命令之间必须要用换行符或者分号隔开,例如:

    # 以下均合法
    set a 1  #设置a的值为1
    set b 2	 #设置b的值为2
    set a 1;set b 2
    set a 	 ##读取a的值,结果为1
    
  • tcl的每一个命令包含一个或几个单词,第一个单词代表命令名,另外的单词则是这个命令的参数,单词之间必需用空格或Tab隔开

普通置换

TCL解释器在分析命令时,会把所有的命令当做字符串,例如

%set x 10  		#定义变量x,并把x的值赋值为10,这个10也是字符串,而不是我们认为的int等类型
%set y x+100  	#定义变量y,并把y的值赋值为字符串 x+100 ,但注意并非是 110 或者10+100,因为把x当做字符串来看待

变量置换

变量置换有一个 $ 符号标记,如下:

%set x 10 
%set y $x+100   #此时y为字符串 10+100,因为x被置换成了10
#由此我们发现,还不是我们想要的y=110的结果

命令置换

命令置换是由符号 [ ] 括起来的命令及参数,

%set x 10 
%set y [expr $x+100]	#此时y=110

注解:

  • 当TCL解释器。从左到右遇到第一个"[" 时,就会把随后的expr当做一个命令,从而激活expr对应的c/c++过程。
  • 因为中括号[ ]的存在,tcl会把中括号里面的expr $x+100当做一个新的运算来计算,

反斜杠 \ 置换

类似其他语言中的转义字符,在单词符号中插入如换行符、空格、[ 、$等作为特殊符号时,就需要用到 **\ **符号来置换。

%set msg multiple\ space   #添加了一个空格,结果为“multiple space” 

花括号{ }和双引号“”

除了使用反斜杠以外,还可以使用花括号{ }和双引号"",也可以将一些具有命令作用的字符作为特殊字符使用。

双引号""

  • tcl解释器对于双引号""中的各种分隔符将不做处理,但是对换行符以及 $ 和 [ ] 两种置换符会照常处理
%set x 10 
%set y "$x ddd"   #结果为“10 ddd”

花括号{ }

  • 如果变量中有字母、数字或下划线的字符,又要用置换,可以用花括号{ }把变量括起来。
%set a 2
%set a.1 4 		# a.1的值为4
#我们期待  a.1这个变量的值为4,赋值给b,如何操作?
%set b $a.1		# 设置b为2.1,结果不是我们期待的
%set b ${a.1}	# b的值为4,是我们期待的 %set a {kdfh jk} #设置a为“kdfh jk”
%set a 			#读取a的值,结果为“kdfh jk”

变量

数组

在TCL中,不能单独声明一个数组,数组只能和数组元素在一起声明。数组中,数组元素的名字包含两个部分:**数组名和数组中元素的名字。**TCL中数组元素的名字可以为任何字符串

%set day(monday) 1  #day是数组名,Monday是数组中的索引值,Monday对应的值为1
%set day(tuesday) 2

相关命令:

  • unset会从解释器中删除变量,后面跟任意多个参数,每个参数是一个变量名(包括数组或数组元素)
% unset a b day(monday)
  • append命令可以将文本追加到一个变量的后面,也就是增加字符串的长度
% set txt hello
% append txt "!world!"  # txt的值为“hello!world!”
  • incr命令是把一个变量的值加上一个整数。要求:变量原来的值和新加的值都必须时整数
%set b 2;incr b 3      #b的结果为5
## 相当于  %set a 2;$set b [expr $a+3]

集合

集合(list)是由一堆元素组成的有序集合。list可以嵌套定义,list中的每个元素可以是任意字符串或list

语法:

  • list ? value value…
  • concat list list …
% list 1 2 {3,4}   # 元素有三个 1 ,2 ,{3,4}
% concat {1 2 3} {4 5 6} # 整合数组 ,{1 2 3 4 5 6}

list相关的命令:

  • **lindex **list index 返回 list 中索引值对应的值,index从0开始计
  • llength list 返回list中的元素个数
  • linsert list index value value… 在list中指定index出插入元素
% lindex {1 2 {3 4}} 2  #返回list的第三个元素,结果为3 4
% llength {1 2 {3 4}}   #返回list中的元素个数
% linsert {1 2 3 4} 1 7 8  #在索引为1处插入 7 8 两个元素,结果为{1 7 8 2 3 4}

控制流

if 命令

  • 语法:if { test1} {body1} elseif {test2} {body 2} …
  • TCL先把test1当做一个表达式求值,如果值非0,则把body1当做一个脚本执行并返回所得值。否则会把Test2当做一个表达式,如果值非0,则把body2当做一个脚本执行。…

注意:

  • "{"必须要在上一行写,不能换行。
  • elseif是连着写的
  • if 和 elseif 与 { 之间要有一个空格,否则解释器会把 if{ 当做一个整体。
if {$x>0} {
...} elseif {$x==1} {
...} elseif {$x<0} {
...} 

while命令

  • 语法:while test body
  • 参数test是一个表达式,body是一个脚本。如果表达式值非0,就运行脚本,直至表达式为0 才停止循环。此时while中断并返回一个空字符串
# 把list a中的数据赋值给了b
set b " "
set i [expr[llength $a] -1]
while {$i>=0} {
lappend b [lindex $a $i]
incr i -1
}

for循环命令

  • 语法: for init test reinit body
  • 参数init是一个初始化脚本,第二个参数test是表达式,用来决定循环什么时候中断。第三个参数reinit是一个重新初始化的脚本,第四个参数body也是脚本,代表循环体。
set b " "
for {set i [expr [llength $a -1] -1]} {$i>=0} {incr i -1} {lappend b [lindex $a $i]}
# a是一个list 

foreach循环命令

  • 语法:foreach varName list body
  • 第一个参数varName是变量,第二个是一个list,第三个body是一个循环体。
  • 每次取得链表list中的一个元素,就执行一次循环
set b " "
foreach i $a {
set b [linsert $b 0 $i]
}
# a是一个list 

switch命令

相当于case语句

%switch $x {
b {incr t1}
c{incr t2}
}

其他命令

  • break、continue 命令:中断循环,其中break命令结束整个循环过程,并从循环中跳出,continue只是结束本次循环。
  • source 命令:读一个文件并把文件的内容作为一个脚本进行求值
%source e:/tcl/hello_word.tcl 
  • eval命令:构造和执行TCL脚本命令。可以接受一个或多个参数,然后把所有的参数以空格隔开,组合到一起成为一个脚本,最后对这个脚本求值。
%eval set a 2;set b 4

过程

TCL支持过程的定义和调用,在TCL中,过程可以看做是用TCL脚本实现的命令,效果与TCL固有命令相似。

proc 命令

proc 命令来对过程定义,相当于函数一样的作用

% proc add {x y} {expr $x+$y}
% add 1 2 	# 调用add过程,传递两个参数
# 结果为3

局部变量和全局变量

global在proc中声明变量来自外部,引用外部变量。

% set a 4 
% proc sample {x} {global a  #用global声明,这个变量来自外部,即全局变量incr areturn [expr $a+$x]
}
% sample 3 # 值为8
% set a  # 值为5

字符串操作

format命令

语法:format formatstring value value …

按照formatstring提供的格式,把各个value的值组合到formatstring中形成新字符串返回

%set name lisa
%set age 20
%set msg [format "%s is %d years old" $name $age]

scan命令

语法:scan string format varName varName …

可以认为是format命令的逆命令。按照format提供的格式分析string字符串,然后把结果存到变量varName中。

注意:除了空格和TAB键之外,string和format中的字符和百分号 % 必须匹配。

% scan "some 26 34" "some %d %d" a b
%set a	#26
%set b  #34

regexp命令

regexp命令用于判断正则表达式exp是否全部或部分匹配字符串,匹配返回1 ,否则返回0。

字符意义
.匹配任意单个字符
^表示从头到尾进行匹配
$表示从末尾进行匹配
[chars]匹配字符集合chars中给出的任意字符
*对*前门的项进行0次或多次匹配
+对+前门的项进行1次或多次匹配

文件访问

注意:在tcl中,表示文件目录结构时使用的是**“ / ”**,而不是反斜杠“\”

open命令

  • 语法: open name access
  • access方式打开name文件,返回字符串,用于标识打开的文件
  • 当调用别的命令(如:gets,puts,close)对文件进行操作时,都可以使用这个文件标识。
  • stdin.stdout,stderr,分别对应标准输入、标准输出和错误通道
access方式式作用
r默认的打开方式。只读方式打开,且文件必须已经存在。
r+读写方式,且文件已经存在
w只写方式,如果文件存在则情况文件内容,文件不存在就新建一个空文件
w+读写方式,如果文件存在则情况文件内容,文件不存在就新建一个空文件
a只写方式,文件必须存在,并把指针指向文件尾
a+读写方式,如果文件存在,把指针指向文件尾。文件不存在就新建一个空文件

gets命令

  • 语法:gets field varname
  • 读field标识的文件下一行,忽略换行符。
  • 如果命令有varName就把该行赋给它,并返回该行的字符数
  • 如果没有varname,返回文件的下一行作为命令结果
  • 如果到了文件的结尾,就返回空字符串

puts命令

  • 语法:puts nonewline field string
  • puts命令把string写到field中
  • 如果没有 nonewline开关的话,就添加换行符
proc tgrep {pattern filename} {set f [open $filename r]  #只读方式打开文件,产生文件标识fwhile {[gets $f line]} {  #获取文件中的每一行,一行一行的拿if {[regexp $pattern $line]} {  #判断这一行符不符合正则表达式,也就是我们所期望的puts stdout $line #如果符合,就把这一行输出在标准输出端stdout}}close $f
}

flush field

把缓冲区的内容写到field标识的文件中,命令返回值为空。

管理目录的指令包括:

  • pwd 返回当前目录的完整路径
  • cd 使用一个参数,把工作目录改变为参数提供的目录
  • globfile 用来操作文件或者获取文件信息

glob命令

  • 语法:glob switches pattern pattern…
  • glob命令string match命令的匹配规则
# 找到所有以.v和.sv结尾的文件
%glob *.v *.sv  

file命令

语法:file switches pattern pattern…

假如我想删除所有.sv的文件,怎么操作?

file delete *.sv   #不生效,因为file不识别*通配符
#采用一下的方式
file delete {*}[glob *.sv]
#方法二
eval file delete [glob *.sv]

{*} 的存在,是把列表元素作为独立参数提供给指令。比如你glob *.sv返回的是多个文件,文件与文件字符串之间会有空格,tcl会把glob *.sv返回的所有文件名当做一个文件,这样file delete也就无法找到对应的文件。


http://www.ppmy.cn/news/149524.html

相关文章

TCL编程语言教程

TCL编程语言教程 TCL&#xff08;Tool Command Language&#xff09;是一种解释型编程语言&#xff0c;它的主要设计目标是提供一个简单易用的脚本语言&#xff0c;而且可以方便地嵌入到其他程序中。TCL最初由约翰奥斯汀&#xff08;John Ousterhout&#xff09;在1988年开发。…

TCL基础知识

TCL基础知识 置换 TCL解释器运用规则把命令分成一个个独立的单词&#xff0c;同时进行必要的置换 TCL置换分为以下三类 变量置换 $ 命令置换 [] 反斜杠置换 \ 用 $ 表示变量置换 TCL解释器会将认为 $后面为变量名&#xff0c;将变量置换成它的值 用[]表示命令置换 []内是一…

TCL使用

tcl常用的语法 1.## tcl脚本命令 tcl有效的命令是以命令字符串的形式。例如 set a 4&#xff1b; 2。置换命令 tcl中&#xff0c;有三种置换&#xff1a;变量置换&#xff0c;命令置换和反斜杠置换。 ##2.1变量置换 以$为标记&#xff0c;例如%set $xy;就是讲x的值与y相加。 #…

初识Tcl(五):Tcl 循环

目录 Tcl循环 循环控制语句 无限循环 Tcl while循环 语法 流程图 示例 Tcl for循环 语法 流程图 示例 Tcl嵌套循环 语法 示例 Tcl break语句 语法 流程图 示例 Tcl continue语句 语法 流程图 示例 Tcl循环 可能有一种情况&#xff0c;当需要执行一个代码…

十二、TCL脚本

文章目录 引言学习核心基础语法置换(substitution)变量置换命令置换反斜杠置换双引号和花括号 变量简单变量数组其它相关命令unsetappendincr表达式 list 控制流ifwhileforforeachswitch命令break/continuesourceeval 过程proc 命令局部变量和全局变量 字符串操作formantscanre…

Tcl -- upvar

1. upvar&#xff1a;类似于C语言中的引用传参&#xff08;别名&#xff09; 这里涉及到层级&#xff08;栈级&#xff09;的概念&#xff0c;upvar 2表示向上两级&#xff0c;默认值是1. 我们知道局部变量&#xff08;函数参数&#xff09;都是存在栈中的&#xff0c;这样做…

[TCL]Tcl语言基礎教程(一)

Tcl语言参考&#xff08;一&#xff09; Tcl("Tool Command Language"&#xff0c;即工具命令语言&#xff1b;Tcl念作“踢叩” "tickle" )是一种易学易用易于扩展的脚本语言,实际上包 含了两个部分&#xff1a;一个语言和一个库。 首先&#xff0c;Tcl是…

TCL语言

目录 引言概述其他 变量、数组和列表变量数组列表 控制流过程函数正则匹配文本处理 引言 TCL&#xff08;Tool Command Language&#xff09;脚本语言是对EDA兼容性最好的语言&#xff0c;非常适合做EDA流程控制。如下图所示&#xff1a; IC设计中另一种常用语言是Perl&#…