您当前的位置: 首页 > 

lu-ming.xyz

暂无认证

  • 1浏览

    0关注

    115博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

lu-ming.xyz 发布时间:2021-04-27 15:34:36 ,浏览量:1

目录
  • 2.1 脚本、命令和单词
  • 2.2 处理命令
  • 2.3 替换
  • 2.4 引用
  • 2.5 参数展开
  • 2.6注释
  • 2.7 正常返回与异常返回

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输出这个变量的值。

关注
打赏
1655639048
查看更多评论
立即登录/注册

微信扫码登录

0.0385s