【Tcl学习笔记】第2章 Tcl语言的语法

Tcl的语法:决定如何解析命令的十多条规则。

2.1 脚本、命令和单词

  • Tcl脚本:
    包含一条或多条命令。命令通过换行符分号隔开。

  • 命令:

    • 包含由一个或多个单词。单词通过空格制表符分开。
    • 第一个单词是命令名,其他单词是命令的参数。

2.2 处理命令

  • Tcl 处理一条命令分两步:解析 和 执行。
    在这里插入图片描述

    注意:Tcl解析器在解析命令的时候,并不会为其中的单词赋予任何含义。这些单词的含义取决于具体的命令过程。

  • 常见的参数的意义

    • expr 24 / 3.2
      expr把参数连接成一个数学表达式。
    • lindex {red green blue purple} 2
      第一个参数是一个列表,值由空格隔开。
      第二个参数为索引(从0开始),命令返回blue
    • string length helloworld
      length 与 string length 组成集合命令,返回第二个参数的长度。
    • button .b -text hello -fg red
      .b(组件名)后面的参数为: -选项 值 。

2.3 替换

  • Tcl的三种替换形式:

    • 变量替换
    • 命令替换
    • 转义替换
  • 注意:

    • Tcl解释器在执行命令过程之前进行这些替换。
    • [重要]解析命令时只从左到右解析一次,进行一轮替换。
    • [重要]每一个字符只会发生一层替换,不会对替换后的结果再进行一次扫描替换。
    • 替换可以发生在命令中的任何一个单词上,包括命令名。
    • 替换不影响命令中每个单词的分隔。
  1. 变量替换
    引发:$符号。
    功能:将Tcl变量的值插入单词中。
    变量名由$符号后面所有的数字、字母和下划线组成。
    例子:用变量替换新建组件.b1,.b2,.b3,.b4,.b5

    foreach num{1 2 3 4 5} {
        button .b$num
    }
    
  2. 命令替换
    引发:[]符号
    功能:把一个单词的部分或全部替换为一个命令的结果。
    []内的字符必须构成有效的Tcl脚本。

  3. 转义替换
    引发:\符号
    功能:转义字符
    Tcl支持的转义字符:

    字符替换结果
    \a警告音(0x7)
    \b删除(0x8)
    \f换页符(0xc)
    \n换行符(0xa)
    \r回车(0xd)
    \t制表符(0x9)
    \v垂直制表符(0xb)
    \ooo八进制值为ooo(1-3位)的8位Unicode字符
    \xhh十六进制位hh(前两位有效)的8位Unicode字符
    \uhhhh十六进制值为hhhh(1-4位)的16位Unicode字符
    \newline以及新行开头的空格一个空格字符

    [注意]\newline和一般的替换不同,这种替换在Tcl解释器解析命令前就要单独进行。为了实现语句太长分行。

2.4 引用

功能:为了阻止解析器对$;等字符进行特殊处理。
除转义外的两种引用形式:

  1. ""
    功能:取消其中的单词和命令分隔符的特殊解释。
    说明:
    • 如果一个单词(字符串)的第一个字符是",那么这个单词就由另一个"标记结束。注意双引号本省不是单词的一部分,其中的空格、制表符、换行以及分号都作为普通字符处理。
    set msg "Eggs: \$2.18/dozen\nGasoliine: \$1.49/gallon"
    # 执行结果:  
    Eggs: $2.18/dozen
    Gasoliine: $1.49/gallon
    
    • 如果单词不是以"开头,那么单词中的任何"都会作为普通字符处理,而不是定界符。
    puts This"is"poor"usage
    # 执行结果: 
    This"is"poor"usage
    
    • [注意]变量替换、命令替换和转义替换在双引号中正常进行。
    set a 2.1 
    set msg "a is \"$a\": the square of a is \"[expr $a * $a]\" "
    # 执行结果:
    a is "2.1": the square of a is "4.41"
    
  2. {}
    功能:取消其中所有特殊字符的特殊意义。
    说明:
    • 如果一个单词以{开头,那么指导与它配对的}为止,所有字符都将原封不动的识别位这个单词的值。
    • 唯一会执行的替换:\newline,因为它先于解析器解析前替换。
    • 大括号可以嵌套使用。
    • 注意{与前一个单词需要用空格分隔。
    proc occur {value list} {
        set count 0 
        foreach el $list {
            if $el==$value {
                incr count
            }     
        }
        return $count
    }
    occur 18 {1 34 18 16 18 72 1994 -3}
    
    执行过程:
    在这里插入图片描述

2.5 参数展开

某些情况下,单层替换不能完成任务:

例子:删除所有txt类型的文件(1.txt、2.txt和3.txt三个文件)
file delete [glob *.txt]
1. [glob *.txt]的结果为:1.txt 2.txt 3.txt
2. 1.txt 2.txt 3.txt作为一个整体传递给file delete(因为解析命令时只从左到右解析一次,进行一轮替换。),功能变成删除名为1.txt 2.txt 3.txt的文件,发生错误。

如果一个单词以{*}开头,之后紧接着非空白字符,Tcl会移除开头的`{*},把单词的剩余部分作为含有单词分隔符的语句进行解析替换,即重新替换一次。
[注意]只有Tcl 8.5版本以上支持

    file delete {*}[glob *.txt]

等效于:

    file delete 1.txt 2.txt 3.txt

对于Tcl 8.5更早的版本,用eval将这些单词重新传给Tcl解释器:

    eval file delete [glob *.txt]

2.6注释

注释符#必须出现在Tcl将获得命令的第一个字符上,其他地方将被挡住普通字符。

# 这是一条评论
set a 100   # 这不是一条评论
set a 100;  # 这是一条评论

这将导致大括号内的注释常常会导致错误。

  • 尽量避免在注释中出现大括号,如果确实要用,确保{}是成对的。
  • 可以用if 0 {}实现大段格式正确的代码的注释

2.7 正常返回与异常返回

命令通常会返回字符串结果,但有时会返回错误,导致Tcl命令解释器放弃处理。
出现错误后,Tcl会把全局变量erroInfo设置为一个栈,保存产生错误的确切位置。可以用puts $erroInfo输出这个变量的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lu-ming.xyz

觉得有用的话点个赞吧 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值