Challensys的个人空间 https://blog.eetop.cn/challensys [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

TclOK与常见开源Tcl静态检查器:实际案例对比

已有 110 次阅读| 2025-6-11 13:04 |系统分类:芯片设计| Tcl

两款 Tcl 脚本检查器简介

Nagelfar:耕耘了 26 年的开源 Tcl 静态语法检查器项目

Nagelfar 静态语法检查器项目始于 1999 年,托管在 sourceforge 开源社区,直至今年仍在活跃更新。按项目官网的描述,其项目初衷是为了解决“a synthesis script crashing due to a misspelled variable after running for 30 hours”的问题。

TclOK:Challensys EDA 推出不到 1 年的 Tcl “静态+动态” 检查器

TclOK 是由深圳轻思科技有限公司推出的 Tcl / SDC / UPF 检查器,已在 Challensys 官网开放下载。与 Nagelfar 项目初衷不谋而合的是,TclOK 的目标也是为了解决 Tcl 脚本出现低级错误时会导致 EDA 工具长时间运行后异常中止的问题。其不同点在于,Challensys EDA 是在发现已有(国外 / 开源 / 商用)Tcl 静态检查器仍存在过多的漏报与误报,不能真正有效解决上述问题后,才启动了 TclOK 产品的研发工作。


技术原理对比

开源 Nagelfar 静态语法检查器底层技术

Nagelfar 项目使用纯 Tcl 编写,可在标准 tclsh 解释器上运行。

TclOK “静态+动态”检查器底层技术

TclOK 基于 Challensys 自有的 FusionShell 解释器,通过将 FusionShell 解释器的“真实执行”步骤修改为“虚拟执行”,从而达到快速检查的目的。


测试Case 1:变量相关的检查

puts -nonewline stdout 123 ;# legal

set arg1 -nonewline
set arg2 stdout
set arg3 123

puts $arg1 $arg2 $arg3 ;# should PASS, same as above after var inline

开源 Nagelfa 检查结果:存在误报

Checking file tmp.tcl
Line   7: E Wrong number of arguments (3) to "puts"

TclOK 检查结果:通过

checking: puts -nonewline stdout 123
checking: set arg1 -nonewline
checking: set arg2 stdout
checking: set arg3 123
checking: puts -nonewline stdout 123
****************** TCL CHECK SUMMARY ******************
  Total errors              : 0
  Total unknown commands    : 0
  Possible unknown commands : 0
  Hierarchical summary      : tmp.tcl (errors:0, unknown_cmds:0)

OK

tclsh 执行结果:正常执行

% tclsh tmp.tcl 
123123%




测试Case 2:求值、判断相关的检查

set arg1 -nonewline
set arg2 stdout
set arg3 123

if $arg3 {
	puts $arg1 $arg2 $arg3 ;# should PASS, active branch
} else {
	puts this line should not be checked  ;# should IGNORE, inactive branch
}

if $arg1 {  # should FAIL, "-nonewline" is not a legal expression
	# blah blah
}

开源 Nagelfa 检查结果:存在误报、漏报、非必要的警告(Noise)

Checking file tmp.tcl
Line   5: W No braces around expression in if statement.
Line   6: E Wrong number of arguments (3) to "puts"
Line   8: E Wrong number of arguments (6) to "puts"
Line  11: W No braces around expression in if statement.

TclOK 检查结果:准确报出 1 个错误

checking: set arg1 -nonewline
checking: set arg2 stdout
checking: set arg3 123
checking: if 123 ...
( expr ): { 123 }
checking: puts -nonewline stdout 123
checking: if -nonewline ...

Error: invalid bareword "nonewline"
in expression "-nonewline";
should be "$nonewline" or "{nonewline}" or "nonewline(...)" or ...
 Line: 11
 File: tmp.tcl

****************** TCL CHECK SUMMARY ******************
  Total errors              : 1
  Total unknown commands    : 0
  Possible unknown commands : 0
  Hierarchical summary      : tmp.tcl (errors:1, unknown_cmds:0)

FAILED

tclsh 执行结果:1 个错误

% tclsh tmp.tcl
invalid bareword "nonewline"
in expression "-nonewline";
should be "$nonewline" or "{nonewline}" or "nonewline(...)" or ...
    (parsing expression "-nonewline")
    invoked from within
"if $arg1 {  # should FAIL, "-nonewline" is not a legal expression
	# blah blah
}"
    (file "tmp.tcl" line 11)
123%




测试Case 3:循环内部的检查

set i -3

while { 3 / $i } { # should FAIL after 3 iterations
	puts $i
	incr i
}

开源 Nagelfa 检查结果:通过(漏报)

Checking file tmp.tcl

TclOK 检查结果:准确报出循环中的 1 个错误(并打印出每次循环的过程,以供调试)

checking: set i -3
checking: while { 3 / $i } ...
( expr ): { 3 / $i }
( expr ): <internal> return -1
checking: while...puts -3
checking: while...incr i
( expr ): { 3 / $i }
( expr ): <internal> return -2
checking: while...puts -2
checking: while...incr i
( expr ): { 3 / $i }
( expr ): <internal> return -3
checking: while...puts -1
checking: while...incr i
( expr ): { 3 / $i }

Error: divide by zero
 Line: 3
 File: tmp.tcl

****************** TCL CHECK SUMMARY ******************
  Total errors              : 1
  Total unknown commands    : 0
  Possible unknown commands : 0
  Hierarchical summary      : tmp.tcl (errors:1, unknown_cmds:0)

FAILED

tclsh 执行结果:1 个错误

% tclsh tmp.tcl
-3
-2
-1
divide by zero
    while executing
"while { 3 / $i } { # should FAIL after 3 iterations
	puts $i
	incr i
}"
    (file "tmp.tcl" line 3)




测试Case 4:子脚本内部的检查

source good_filepath.tcl ;# should PASS
source bad_filepath.tcl  ;# should FAIL, file does not exist

开源 Nagelfa 检查结果:通过(漏报)

Checking file tmp.tcl

TclOK 检查结果:可深入子脚本内部检查,并准确报出 1 个错误

checking: source good_filepath.tcl
<info> line 1: sourcing script 'good_filepath.tcl' <---- current script
checking: puts {I'm good}
<info> line 1: source script done, returning back to 'tmp.tcl' <---- current script
checking: source bad_filepath.tcl

Error: couldn't read file "bad_filepath.tcl": no such file or directory
 Line: 2
 File: tmp.tcl

****************** TCL CHECK SUMMARY ******************
  Total errors              : 1
  Total unknown commands    : 0
  Possible unknown commands : 0
  Hierarchical summary      : tmp.tcl (errors:1, unknown_cmds:0)
                               ├─good_filepath.tcl (errors:0, unknown_cmds:0)
                               └─bad_filepath.tcl (Error: file not found)

FAILED

tclsh 执行结果:1 个错误

% tclsh tmp.tcl
I'm good
couldn't read file "bad_filepath.tcl": no such file or directory
    while executing
"source bad_filepath.tcl  "
    (file "tmp.tcl" line 2)



小结

从上述几个简单例子可见,开源 Tcl 静态语法检查器普遍存在很大的局限性,对非常简单的 Case 也存在大量的漏报、误报和非必要的警告。我们猜测其局限性主要来源于它们是基于标准的 tclsh 解释器之上开发的,既无法真正去“执行”Tcl 语句(这样就起不到加速检查的效果),而只能进行一些浅显的“表面”检查(这会造成与tclsh实际执行存在诸多差异)。而 Challensys 本身拥有 FusionShell 解释器,而 TclOK 是直接对 FusionShell 解释器底层进行了修改,从而既实现了加速检查,又做到了与解释器实际执行脚本高度一致的报错行为,具有更高的项目实用价值。



点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 11

    周排名
  • 0

    月排名
  • 0

    总排名
  • 2

    关注
  • 0

    粉丝
  • 7

    好友
  • 0

    获赞
  • 0

    评论
  • 59

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-6-14 22:46 , Processed in 0.023016 second(s), 15 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部