我正在失去导致堆栈溢出的编程错误的效率。
例如,如果我在drop
分支中省略IF ELSE THEN
,在循环内部,并且我得到堆栈溢出,我通常必须重新启动我的开发环境。我在SwapForth上使用iCEstick。
是否存在静态分析器来预测编译单词的堆栈结果?
像自动化工具一样检查代码是否始终与( nnn nnn - f )文档匹配?
答案 0 :(得分:4)
我不知道这样的工具,但为什么不实施呢?
在一般情况下,问题没有解决方案(请参阅Rice's theorem和halting problem)。然而,显然可以实现一种实用的工具。它可以是您的特定Forth系统的独立工具或扩展,可在编译期间动态检查代码。
至于一些例子,见Peter Sovietov的Forth Wizard(2003)。此工具在内部评估自动生成代码的堆栈效果。 另一个例子:Rob Chapman撰写的Stack Verification论文(1997)。 以下论文也很有用:基于堆栈的语言中的类型推理,Bill Stoddart和Peter J. Knaggs,1992(PDF); 面向高阶堆栈的语言的简单类型推理,Christopher Diggins,2008(PDF)。
也许最简单的解决方案就是动态检查堆栈效果(更改深度)并在违反堆栈签名时抛出异常(仅限开发版本)。
我们的想法是重新定义:
(和可能的;
)以从堆栈注释中获取堆栈效果,并为冒号定义编译EXECUTE-BALANCED
包装器。
: EXECUTE-EFFECT ( i*x xt -- j*x n )
DEPTH 1- >R EXECUTE DEPTH R> -
;
: EXECUTE-BALANCED ( i*x xt n -- j*x ) \ j = i + n
>R EXECUTE-EFFECT R> = IF EXIT THEN
-5010 THROW \ stack is unbalanced
;
显然,这样的解决方案只会在单词之间发现错误,并且不会在循环中捕获错过的DROP
。
答案 1 :(得分:0)
分析器需要知道所有使用的词的堆栈效果,而不仅仅是标准词。在实践中,这意味着必须以某种方式为所有存在的单词记录堆栈效应。我已经代表优化器在 ciforth 中完成了此操作,因此可以完成。我没有做的是自动将它与规范进行比较。这将需要像您使用 (nnn nnn - f) 提出的那样形式化规范,以及一种指定不确定性堆栈效应的方法。
半途而废的解决方案是使用堆栈效果颜色编码,使堆栈错误突出。它在 ciforth 实现中使用存储在标志字段中的堆栈效果规范。 https://home.hccnet.nl/a.w.m.van.der.horst/forthlectureE.html
有经验的 Forthers 不会考虑太多。创建后必须立即测试单词,这会使堆栈错误短暂存在。