首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >启用宏的语言如何跟踪源代码以进行调试?

启用宏的语言如何跟踪源代码以进行调试?
EN

Stack Overflow用户
提问于 2010-07-10 00:25:29
回答 6查看 675关注 0票数 11

这是一个关于宏的更理论的问题(我认为)。我知道宏获取源代码并生成目标代码,而不需要对其求值,这使得程序员能够创建更多通用的语法结构。如果我必须对这两个宏系统进行分类,我会说有"C风格“宏和"Lisp风格”宏。

似乎调试宏可能有点棘手,因为在运行时,实际运行的代码与源代码不同。

根据预处理的源代码,调试器如何跟踪程序的执行情况?是否有一个特殊的“调试模式”必须设置为捕获有关宏的额外数据?

在C中,我可以理解您会为调试设置编译时间开关,但是解释型语言,如Lisp的某些形式,如何做到这一点呢?

很抱歉没有尝试一下,但是lisp工具链需要比我花更多的时间来弄清楚。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-07-10 02:02:36

我不认为"C风格“和"Lisp风格”的宏在编译方式上有根本的区别。两者都会在编译器看到源代码之前对其进行转换。最大的区别在于,C的宏使用C预处理器(一种较弱的辅助语言,主要用于简单的字符串替换),而Lisp的宏是用Lisp本身编写的(因此完全可以做任何事情)。

(顺便说一句:我已经有一段时间没有见过未编译的Lisp了……当然,自世纪之交以来就没有了。但如果有什么不同的话,那就是被解释似乎会使宏调试问题变得更容易,而不是更难,因为您有更多的信息。)

我同意Michael的观点:我还没有见过处理宏的C语言调试器。使用宏的代码会在任何事情发生之前进行转换。"debug" mode for compiling C code通常只表示它存储functions, types, variables, filenames, and such --我不认为它们中的任何一个存储有关宏的信息。

  • 用于调试使用宏的程序时,Lisp与C在这里几乎相同:调试器看到的是编译后的代码,而不是宏应用程序。通常宏保持简单,并在使用前独立调试,以避免这种需要,就像C.
  • 用于调试宏本身一样,在你使用它之前,Lisp确实有比C更容易的特性,例如repl和macroexpand-1 (尽管在C中显然有一种方法可以一次完全地宏解压整个文件)。在编写宏扩展时,您可以在编辑器中查看宏扩展的前后效果。

我不记得什么时候遇到过这样的情况,调试到宏定义本身会很有用。这要么是宏定义中的错误,在这种情况下macroexpand-1会立即隔离问题,要么是下面的错误,在这种情况下,正常的调试工具工作得很好,我并不关心调用堆栈的两个帧之间是否发生了宏扩展。

票数 4
EN

Stack Overflow用户

发布于 2010-07-10 05:26:35

LispWorks中,开发人员可以使用Stepper tool

LispWorks提供了一个步进器,用户可以单步执行完整的macro expansion process

票数 3
EN

Stack Overflow用户

发布于 2010-07-10 02:18:50

您真的应该研究一下Racket对使用宏调试代码的支持。正如Ken提到的那样,这种支持有两个方面。一方面是调试宏的问题:在Common Lisp中,最好的方法就是手动展开宏窗体。使用CPP的情况与此类似,但更为原始--您只需通过CPP扩展运行代码并检查结果。但是,这两个都不足以处理更复杂的宏,这就是在球拍中使用macro debugger的动机--它一个接一个地向您展示语法扩展步骤,并为绑定标识符等提供额外的基于gui的指示。

在使用宏方面,side一直比其他Scheme和Lisp实现更先进。其思想是,每个表达式(作为语法对象)都是代码加上包含其源位置的附加数据。这样,当表单是宏时,具有来自宏的部分的扩展代码将具有正确的源位置--来自宏的定义,而不是来自它的使用(表单实际上并不存在)。正如dmitry-vk所提到的,一些Scheme和Lisp实现将使用子窗体的标识来实现有限的for。

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

https://stackoverflow.com/questions/3214603

复制
相关文章

相似问题

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