在参数中使用 `\catcode` 会报告“失控参数”错误

在参数中使用 `\catcode` 会报告“失控参数”错误

这么简单的文字让我困惑

\def\say#1{The argument is #1, I see it}
\say{\catcode`{=12 \bf Hello}
\bye

当 TeX 编译失败并报告

Runaway argument?
{\catcode `{=12 \bf Hello}
! Forbidden control sequence found while scanning use of \say.
<inserted text>
                \par
<to be read again>
                   \bye
l.3 \bye

我猜 TeX{在读取时会将 catcode 1 放入标记列表中,\catcode`{因此会产生不平衡的参数。为此,我稍微更改了命令,只是}在末尾添加了一个额外的命令:

\say{\catcode`{=12 \bf Hello}}

现在出现了一个新错误:

! Too many }'s.
<argument> \catcode `{=12 \bf Hello}

\say #1->The argument is #1
                           , I see it
l.2 \say{\catcode`{=12 \bf Hello}}

如您所见,它也不起作用。但如果考虑 token 列表,后面有两个{catcode 1 的左括号和两个}catcode 2 的右括号,因此列表似乎是平衡的(可能)。显然 TeX 不这么认为。

最后,当我匹配时\catcode`{=12\catcode`}=12它成功运行:

\say{\catcode`{=12 \bf Hello\catcode`}=12}

这可能意味着 TeX 首先收集\catcode`{=12 \bf Hello\catcode`}=12作为参数\say,然后分析标记列表。

{那么会发生什么?在这里扮演什么角色\catcode`{? TeX 如何判断参数是否平衡?

答案1

\def\say#1{The argument is #1, I see it}

代码

\say{\catcode`{=12 \bf Hello}
\bye

是非法的,因为{尚未收到类别代码 12,因此 TeX 寻找匹配}但未找到。当遇到 时\bye,这在宏参数中是非法的,TeX 会停止并显示有关“禁止控制序列”的错误。

如果你添加一个右括号

\say{\catcode`{=12 \bf Hello}}

那么参数就被正确平衡了。现在 TeX 将进行宏替换,输入流将变成

The argument is \catcode`{=12 \bf Hello}, I see it

在哪里不平衡的}

正如 Ulrike 所建议的,

\say{\catcode`\{=12 \bf Hello}

不会产生任何错误。字母常量由一个反引号(类别代码 12)和一个字符或一个字符控制序列组成。

例如,为了更改%您的类别代码必须

\catcode`\%=12

以避免 TeX 将其%视为注释字符。一些字符必须在此上下文中始终可以进行转义:

  1. 类别代码为 0 的字符
  2. 类别代码为 5 的字符
  3. 类别代码为 9 的字符
  4. 类别代码为 14 的字符
  5. 类别代码为 15 的字符

所有其他人逃脱,一些必须取决于您所在的位置。例如,#如果您正在编写定义,则应该进行转义

\def\foo{\catcode`#=12 }

行不通,但是

\def\foo{\catcode`\#=12 }

会。⟨平衡文本⟩ 中的括号也类似。

练习:猜猜你会从中得到什么

\edef\foo{\catcode`\^^M=12 }
\foo
\showthe\catcode`\^^M

相关内容