首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >例外的“支撑您的expr表达式”规则。到底怎么回事?

例外的“支撑您的expr表达式”规则。到底怎么回事?
EN

Stack Overflow用户
提问于 2016-07-09 21:43:40
回答 1查看 285关注 0票数 0

我在一个变量中有一个数字,比如10,在另一个变量中有一个字符串,比如+1或-2。在上述情况下,我需要评估10+1或10-2。

所以,我有

代码语言:javascript
复制
set foo 10
set garp -1

如果我做了

代码语言:javascript
复制
expr $foo $garp

一切都很好(我得到9)。

阿!但是通常,您应该将大括号放在expr表达式的周围。

代码语言:javascript
复制
expr {$foo $garp}

missing operator at _@_ in expression $foo _@_$garp失败。

类似地,

代码语言:javascript
复制
expr [concat $foo $garp]

效果很好,但是

代码语言:javascript
复制
expr {[concat $foo $garp]}

返回10 -1

我不想让这个表达式没有真正的理解,因为我担心,否则我,或者其他人,会把大括号放在表达式上,代码就会停止工作。

做这件事的“正确”方法是什么?

EN

回答 1

Stack Overflow用户

发布于 2016-07-09 23:46:21

一般来说,expr涉及两轮替换。

第一轮替换由命令解析器对不包含在大括号中的expr命令的参数执行。生成的字符串被连接(通过在它们之间添加分隔符空间)到单个表达式字符串中,然后由表达式处理器解析(然后计算)。

在解析过程中,表达式被分解为运算符和操作数。操作数必须用运算符分隔。假设关注数学表达式(即丢弃字符串操作),操作数可以是下列之一:

  1. 数值
  2. 使用标准$表示法的Tcl变量。变量的值将用作操作数.
  3. 包含在括号中的Tcl命令。命令将被执行,其结果将用作操作数.
  4. 带括号的子表达式,它使用相同的规则进行解析。
  5. 一种数学函数,其参数是子表达式,使用相同的规则进行解析。

项2和3对应于由表达式处理器在评估期间执行的第二轮替换。在这一步中执行的每一个替换都将产生一个可以直接用于进一步计算的数值,而不需要重新解析和重新评估它。

说了这些之后,让我们看看您的例子:

代码语言:javascript
复制
expr $foo $garp

在第一轮替换到expr 10 -1期间,命令处理器将其展开,参数连接后的表达式字符串为{10 -1},表达式处理器将其解析为有效的表达式10 subtract 1

代码语言:javascript
复制
expr [concat $foo $garp]

在第一轮替换过程中,命令处理器将其扩展到expr {10 -1},有效地产生与前一种情况相同的表达式字符串。

代码语言:javascript
复制
expr {$foo $garp}

命令处理器保持原样,表达式处理器看到两个连续的操作数(对应于上面的第2条),它们之间没有任何操作符。

代码语言:javascript
复制
expr {[concat $foo $garp]}

同样,第一轮替代没有执行。解析该表达式将提取与第3条对应的单个操作数[concat $foo $garp]。表达式处理器计算命令,并将其结果(即字符串"10 -1")替换为完整表达式的结果。

因此,表达式的正确大括号版本必须读到:

代码语言:javascript
复制
expr {$foo + $garp}

它将被解析为$foo add $garp

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38286619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档