正常 \relax 与冻结 \relax

正常 \relax 与冻结 \relax

\edef\x{\ifnum0=0\else\fi}

存在\relax和与

\def\y{\relax}

我们发现这\ifx\x\y是错误的。为什么?

也可以看看\ifcsname x\endcsname 当 \x 不明显时 \relax

答案1

让我们看一下与 TeX 交互会话的记录。

> tex
This is TeX, Version 3.1415926 (TeX Live 2011)
**\relax

*\def\x{\relax}

*\edef\y{\ifnum0=0\fi}

*\show\x
> \x=macro:
->\relax .
<*> \show\x

?      

*\show\y
> \y=macro:
->\relax .
<*> \show\y

? 

*\ifx\x\y\message{EQUAL}\else\message{UNEQUAL}\fi
UNEQUAL

*\edef\z{\ifnum0=0 \fi}

*\show\z
> \z=macro:
->.
<*> \show\z

? 

*\bye
No pages of output.
Transcript written on texput.log.

\x为什么和不等价?而且为什么和首先\y就不等价?\y\z

条件语句

\ifnum0=0\fi

或者

\ifnum0=0\else\fi

几乎是相同的,并且\y变为非空的事实源于 TeX 针对过早扩展采取的另一项预防措施。

当 TeX 寻找 a 时,<number>它会在过程中扩展 token。但在这种情况下,它会找到 a\fi或 an\else与 the 匹配,\ifnum而搜索要测试的第二个数字仍然是未完成。如果它扩大了,\fi否则\else一切都可能不好。因此,在这种情况下,TeX 会插入一个“安全”标记,它在终端上表示为\relax但实际上不是我们知道并被允许使用的相同\relax。例如,您不能重新定义此标记:

This is TeX, Version 3.1415926 (TeX Live 2011)
**\relax

*\edef\x{\ifnum0=0\fi}

*\expandafter\def\x{Something}
! Missing control sequence inserted.
<inserted text> 
                \inaccessible 
<*> \expandafter\def\x
                      {Something}

\def从上面的交互式会话中可以明显看出,不允许将“冻结放松”令牌喂给。

问题没有显示

\edef\z{\ifnum0=0 \fi}

因为查找以<number>空格标记终止(然后被忽略)。因此,这只是一种复杂的说法

\def\z{}

注意。使用\edef\Z{\ifnum0=1\else\fi}\edef\Z{\ifnum0=1\fi}的扩展\Z将为空,因为“冻结放松”标记成为“真实分支”的一部分,因此它消失了。

TeX 何时插入“冻结放松”?

TeX 会跟踪条件的嵌套,当在与正在评估的条件相同的级别遇到\else或时,就会插入冻结的松弛\fi本次评估的扩展过程尚未完成。

例如,TeX 在

\ifnum0=1\else\fi

因为 a<number>是通过扩展以下 token 来收集的。另一种情况是

\if\fi

这会导致空扩展,因为插入冻结的放松令牌,就其而言,它们是相等的\if。此外

\if\relax\fi

插入冻结的放松,但再次与冻结的放松标记\if进行比较\relax并且测试返回真相。

答案2

用更简单的语言来说,有两个 TeX 扫描规则需要牢记:

1) 的展开式\ifnum...\fi空的 a如果测试为假,\relax (frozen)否则。

   true condtion -> \relax (frozen)
   false condition -> empty 

2) TeX 在读取整数时会一直读取,直到发现不可扩展的内容(例如空格)。

考虑以下 MWE:

\tracingall
\count0=5
\count13=5
\count0=2\ifnum\count0=\count1 3 some words\fi9\par%false->empty 
\the\count0 %29
\bye

在这里,我们看到两个规则都在运行,TeX 试图将一个值放入\count0=2,但继续扫描,直到找到一个不可扩展的标记。它遇到了条件。它评估条件(为假),并根据规则 1)ifnum..\fi将其清空。然后扫描完成,count0=2{empty}9,因此为 29。

修改 MWE 以完成讨论(\ifnum\count0=\count13)

\tracingall
\count0=5
\count13=5
\count0=2\ifnum\count0=\count13 some words\fi9\par% true>\relax  prints some words 9
\the\count0 % has the value of 2
\bye

如果在 中有一个条件\edef,它的行为与扩展其内容的方式完全相同edef。问题的第二部分源于 TeX 插入的松弛是“冻结的”松弛,并且硬编码到引擎中。(参见https://tex.stackexchange.com/a/57404/963)。

a看来 egreg 和 David Kastrup 称此为空虚,而\relax an未完成的条件

相关内容