我知道\expandafter
可以立即跳过它后面的标记,因此我尝试将它与}
、和的\toks
定义的一些组合一起使用。\def
\let
让我困惑的主要问题是为什么连续使用\toks
like\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。允许使用任意数量的前导零来表示整数(或维度的数字部分)。