\expandafter 如何与 } 和 \toks 交互?

\expandafter 如何与 } 和 \toks 交互?

我知道\expandafter可以立即跳过它后面的标记,因此我尝试将它与}、和的\toks定义的一些组合一起使用。\def\let

让我困惑的主要问题是为什么连续使用\tokslike\the\toks0\the\toks0会延长\expandafter效果?理论上它不应该只从最后一个到第一个吗\the\toks0

我尝试过这个:

\toks0{()}
\def\asd{()}
%
1{\def\asd{\TeX}}\asd \par
2{\let\asd\TeX}\asd\par
3{\toks0{\TeX}}\the\toks0\par
4{\toks0{\TeX}}\the\toks0\relax\par
5{\toks0{\TeX}}\the\toks0\the\toks0\relax\par
6{\toks0{\TeX}}\the\toks0\the\toks0\the\toks0\relax\par
7{\toks0{\TeX}}\the\toks0\relax\the\toks0\par
8{\def\asd{\TeX}\expandafter}\asd\par
9{\def\asd{\TeX}\expandafter}\asd\asd\par
10{\let\asd\TeX\expandafter}\asd\par
11{\let\asd\TeX\expandafter}\asd\asd\par
12{\toks0{\TeX}\expandafter}\the\toks0\par
13{\toks0{\TeX}\expandafter}\the\toks0\relax\par
14{\toks0{\TeX}\expandafter}\the\toks0\the\toks0\par
15{\toks0{\TeX}\expandafter}\the\toks0\the\toks0\the\toks0\par
16{\toks0{\TeX}\expandafter}\the\toks0\relax\the\toks0\par
17{\toks0{\TeX}\expandafter}\the\toks0 \the\toks0\par
%
\bye

输出如下:

代码输出

答案1

TeX 会扩展以下\toks标记,寻找<number>确定要使用哪个标记寄存器,因此

\the\toks0\the\toks0 

将首先扩展第二个\the(同时寻找更多数字来结束由第一个0标记开始的数字)。

正如您所展示的,如果您有一个不可扩展的令牌终止此令牌,则<number>第二个令牌\the\toks直到过程的稍后才会扩展,例如您的测试

\the\toks0\relax\the\toks0\par

请注意,避免意外地因文字数字而导致过早扩展是使用数字标记(例如)的一个原因(速度除外)\z@。与 不同0\z@是完整的<number>,因此不会强制扩展以下寻找更多数字的标记。请参阅\z@ 起什么作用?

答案2

我们来看看第 14 行

{\toks0{\TeX}\expandafter}\the\toks0\the\toks0\par

预期的输出确实与 相同\TeX\TeX

你正在设置\toks0一个组,但\expandafter之前}导致的扩展\the 该组结束。现在\the通过查看其后的内容来扩展(参见\命令),在本例中\toks为 ,因此 TeX 知道它必须扫描一个数字才能使用所需的寄存器。这仍然是 的扩展的一部分\the,因此 TeX 找到 0,并且按照一般规则,它会寻找进一步的数字扩展令牌就这样。由于0后面跟着\the,因此将其展开;下一个标记是\toks,但由于扩展可能会显示其他数字,因此再次进行;数字肯定终止,因为下一个标记是\par。所以现在你得到了当前的的内容\toks0;现在 TeX 会扩展\TeX,但这不是以数字开头的,因此 TeX 能够确定第一的数字实际上是0,它提供了当前的的内容\toks0(仍然是\TeX)。只有经过这个过程,扩展才会\expandafter结束,组才会关闭,输入流才会

\TeX T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\par

在第 17 行中,后面的空格0会停止搜索其他数字(并被忽略),因此你会得到

\TeX\the\toks0

其中\toks0具有初始值,因为设置它的组已经结束。

现在让我们看看其他几行。在 1–7 中,重新定义的范围以 结束,因此您获得的或 的}值在组开始之前有效。\asd\toks0

在第 8 行中,在扫描\asd之前扩展},因此使用扩展时的当前值,因此得到。在第 9 行中\TeX,第一个在组结束之前扩展,但第二个仅在组结束后扩展,因此得到。\asd}\TeX()

第 8 行和第 10 行的区别在于,}\TeX\par在第一种情况下,输入流将包含

}T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\par

在第二种情况下,但最终的输出将是相同的。

0后面跟着时\relax,对后续数字的扫描就结束,因此第 14 行的行为不会发生。

为什么 TeX 会扫描更多数字?毕竟0已经是数字了,通常不允许再添加数字。但在 TeX 语言中,01是整数表示,其值为 1。允许使用任意数量的前导零来表示整数(或维度的数字部分)。

相关内容