【问题标题】:TCL man page: it is better to place comment section way aheadTCL 手册页:最好将评论部分放在前面
【发布时间】:2017-12-07 09:46:30
【问题描述】:

我知道我在这里真的很挑剔,但是我想把它扔掉,以防我在解释 TCL man page 时出错,实际上,我希望我在这里错了,就像你看到下面的故事一样。

所以对于每一个新的 TCL 开发者,我们推荐阅读著名的“11 条规则”(现在是 12 条规则)。

昨天有人问我这个问题:为什么下面的脚本会失败?

# puts "hello
world!"

当然失败了,我说,第一行作为注释,留下world!"作为命令。

但是,新手说,手册页表明该脚本是按特定顺序解析的:

  1. 正如#2 Evaluation 所说,命令首先被解析为单词。
  2. 正如#4 Double quotes 所说,在解析双引号时会采用换行符。这使得helloworld! 成为一个单词,中间有一个换行符。
  3. Comments at #10 确实声明了直到下一个换行符被忽略的所有内容,但经过上述处理,换行符应该是第二个换行符,即world! 之后的那个。

我知道他说的有道理。

在手册页中将注释部分向前移动更有意义,也许在第二部分。随着这个顺序的改变,它表明评论识别在词标记化过程之前。

你怎么看?

再次,我无意要求更改联机帮助页,只是想确定我在解释圣经时是否遗漏了什么。

[更新] 对于建议将此问题作为非技术问题结束的人来说,就像我的同事来到这里询问为什么该脚本失败,即使他对 TCL 手册页的理解表明它是一个很好的脚本。

同样,我并不是要更改手册页。

让我重新表述我的问题 - 当你被问到同样的问题时,你认为他的推理有什么缺陷?

[更新2] 谢谢多纳尔。我想这就是我学到的,TCL 解析器一个接一个地处理,没有前瞻。

这是另一个例子:

puts [#haha]

出于同样的原因,此类脚本在 tclsh 失败,TCL 解析器不会首先分解脚本,而只会解析嵌入匹配括号内的字符串,而是将“#”识别为注释的开头并忽略其后的所有内容。

【问题讨论】:

  • 最大的问题是#不是命令,而是开始评论。另一个例子是 # foo [bar] - bar 没有被调用。如果# 是一个命令,那么它将首先评估[bar]
  • 另外请注意,cmets 的描述说“如果哈希字符 (#) 出现在 Tcl 期望命令的第一个单词的第一个字符的位置,那么哈希字符和它后面的字符,一直到下一个换行符,都被视为注释并被忽略。” - 正如我们已经看到的,注释不是命令。我同意,第 1 点(定义 Tcl 脚本)可以包括 cmets。
  • 我投票决定将此问题作为题外话结束,因为这是更改 tcl 项目的请求,而不是一个需要技术解决方案的问题

标签: tcl


【解决方案1】:

Tcl(n) 手册页中的规则非常准确地描述了 Tcl 使用的解析器。对其进行实质性更改的请求通常会被拒绝,因为它们往往会产生深远的影响并且彼此之间会发生微妙的互动。验证规则的重新排序不是实质性的任务是一项艰巨的任务,因为它们对应于相当多的代码(我们的解析器和我们的字节码编译器的一部分)。

添加非规范部分(例如,EXAMPLES)更容易。


根据您更新的问题进行更新

推理的问题在于规则是一个整体,而不是真正分层的部分。他们确实相互影响。 (通常会让人绊倒的是大括号规则和注释规则之间的交互在大括号字符串中,例如过程体。)注释确实是真正的 cmets,并且一直延伸到末尾行(允许反斜杠换行序列)但不能超出,但它们只从命令开始的地方开始,而不是在其他带有 # 字符的地方,这是真正棘手的一点。

不幸的是,Tcl 解析器的工作方式与程序员的想法有些不同,但大多数时候它很擅长假装以“合理的方式”工作。除了处理上面提到的括号-注释交互之外,棘手的边缘情况实际上并不会经常出现。我遇到的其他情况往往是switch(只需将评论放在手臂上即可解决)或我想评论列表的某些部分的长文字列表;在后一种情况下,我实际上是在将字符串用作列表之前对其进行后处理。

set exampleList {
    a b c
    d e f
    # Not really a comment but I want to use it like one!
    g h i
    j k l
}
# Convert “comment” lines to empty lines
regsub -all -line "^\\s*#.*$" $exampleList "" exampleList

Tcl 规则的一般优势在于它实际上很容易在 Tcl 中嵌入其他语言,这正是因为 Tcl 仅将 #(和其他字符)视为在明确定义的上下文中是特殊的。只要你可以让嵌入式语言成为一种使用平衡括号的语言——实际上这几乎是所有这些——那么嵌入它就完全是微不足道的了。其他情况必须使用反斜杠和/或双引号,并且非常难看,但在所有嵌入情况中也只是很小的一部分。

您的同事的问题是他一口气查看了整个脚本,而 Tcl 解析器一次只处理一个字符,并且没有进行有意义的预读。这只是一些愚蠢的代码。

【讨论】:

  • 我想我之前可以做一个更好的答案,但是我的火车正在到达车站……
猜你喜欢
  • 1970-01-01
  • 2017-07-31
  • 2020-01-14
  • 1970-01-01
  • 2012-01-13
  • 2016-07-25
  • 1970-01-01
  • 2012-08-27
  • 1970-01-01
相关资源
最近更新 更多