调试 yacc YYDEBUG y.debug 在哪里 背景说明

问题描述

我尝试为 awk (awk.g.c) 调试 yacc 生成的组件,但是当我定义 YYDEBUG 时,它包含了我似乎没有的 y.debug。

y.debug 来自哪里?

没有它,有几个未定义的引用。

我正在编译旧的 32v 或 V7 版本的 awk,所以我不确定这是否仍然存在。

解决方法

某些版本的 yacc(特别是 AT&T 版本,仍作为 Plan 9 的一部分提供)生成了一个附加文件,后缀为 .debug,其中包含调试信息,特别是将符号编号转换回名称的表。现代的 yacc-alikes 只是将这些信息插入到生成的 C 文件中,理由是这些天的内存消耗基本上是微不足道的。

如果您不请求,可能不会生成名称表,但是您请求它的方式取决于 yacc 版本:

  1. 大多数野牛版本仅在 trace option is enabled 时生成表。 (Posix 为此要求 -t,但 bison 提供了许多替代方案,并非所有历史 yacc 都遵守。)

  2. 如上所示,一些非常老的 yacc 将名称表放入 y.debug。正如我在上面提到的,AT&T 实现总是这样做,但是使用以 #include

    为条件的预处理器保护 YY_DEBUG
  3. 但是,您在注释中指出的 yacc 实现使用条件包含的 y.debug 机制,如果您使用 {{1} } 旗帜。所以这就是你需要做的。

背景说明

我从评论中链接的 V10 源中发现了第 3 点中的信息。下载链接在this page的顶部;从评论中的链接中,这一点并不明显。 (这是完整的源代码 tarball,大约 70MB。评论中的链接链接到的各个文件已被 HTML 化,这使得它们很难使用。)我本可以通过阅读发行说明来节省一些时间(称为 y.debug 而不是 -D)。该文件中的最后一个注释描述了实现,我在此处包含了该段落,因为它包含有关调试在此特定 yacc 版本中如何工作的所有详细信息。

8/11/81 调试已更改。如果解析器以 yaccnews 开头并且 yacc 被调用为 CHANGES(用于调试),那么解析器使用名为 yydebug 的外部变量来控制调试输出。如果 %{#define YYDEBUG %},解析器在执行时打印出缩减文本。如果是 yacc -D,解析器还会打印出每次调用 yylex 返回的 token 的名称,如果是 yydebug == 1,解析器还会在每次更改状态时打印出活动项(这很无趣) .

就其价值而言,应该可以使用现代 yacc(例如 bison 或 byacc)生成一个工作的、可编译的解析器。从长远来看,这可能会更容易。 (如果您使用 bison 并且需要与旧版 yacc 兼容,则可以使用 yydebug == 2 标志。byacc 不支持该标志,它声称无论如何都与旧版兼容。)