TeX 的许多原语都需要<general text>
作为其参数(例如\uppercase
),其定义为(TeXbook p.276)
<general text> -> <filler>{<balanced text><right brace>
其中<filler>
是任意的空格和命令序列\relax
。现在我想知道<filler>
插入这样的 有什么用。
有人能否举一个例子,说明 a 的存在与否<filler>
会产生什么影响,或者,如果这种情况不应该存在,那么解释一下<filler>
插入 a 为何有利?
编辑:在这个问题的原始版本中,我声称
[...] 结构如
\uppercase\expandafter{\romannumeral ...
由于左括号可能是隐式的,因此已经成为可能,因此 TeX 正在扩展以找到一个。
感谢与 frougon 的讨论,我意识到这是一个误解。以下是我目前认为的事实:
- 实际上,只要扩展不受抑制,TeX 总是会扩展可扩展标记(即,TeXbook p.215 中的情况除外)
\expandafter
是可扩展的,并且之后的扩展(立即)\uppercase
等不受抑制(仅在找到开括号后),这是满的在这种情况下发生扩张的原因- 语法规则不是语言的固有属性,无法在 中明确找到
tex.web
;事实上,语法正确性(\relax
之前只允许有空格和标记{
)只有在发现不可扩展的东西时才重要
作为结果:
- 事实上,语法需要一个(可能为空)
<filler>
和一个(可能隐式的)左括号,这与内容是否扩展无关 <general text>
相反,a允许隐式括号而\def
要求显式括号,这一事实仅仅源于这样的现象:在 a 之后扩展受到抑制\def
,而在<balanced text>
a之前则不受抑制<general text>
基本上是不是语法规则中的隐式括号意味着扩展,但反过来:扩展意味着括号可能是隐式的。此外,隐式括号被定义为控制序列,它们要么是\let
1\futurelet
类标记,要么是扩展为 1 类标记,因此说 TeX 完全扩展标记是没有意义的为了正如我最初想的那样,找到一个支架。
但这并不影响问题本身;它只是说明了我误解了描述性的语法规则的性质规范的一。
答案1
空格可能更容易证明,因为它使一些采用括号参数的 tex 基元更像宏,其中\frac {1} {2}
第二个括号之前的空格标记被忽略。这也是为什么=
in之后的空格\count0 = 2
被忽略的原因,然而在这两种情况下,语法中可能都有更自然的地方可以吸收空格。
\relax
很难证明,但我猜是因为
\insert <8 bit number> <filler> {...}
这意味着如果你有一个习惯或一个宏总是以数字结尾,那么\relax
你可以
\insert 250\relax {...}
但老实说,它看起来更像是 TeX 设计之初的早期语法理念,与 TeX 最终的推出方式相比,它并没有什么实际意义。
对于这类事情,tex 源 ( ) 往往tex.web
比教科书提供的信息更丰富,但这个词filler
并没有出现,我所能看到的只是
@ The |scan_left_brace| routine is called when a left brace is supposed to be
the next non-blank token. (The term ``left brace'' means, more precisely,
a character whose catcode is |left_brace|.) \TeX\ allows \.{\\relax} to
appear before the |left_brace|.
\relax
这并没有提供太多关于为什么被允许的线索。
答案2
给出的语法TeXbook记录程序(TeX)的功能,而不是记录程序是如何编写以匹配特定语法的。(虽然我无法明确证明这一点,但从两者来看,这一点相当清楚(在我看来);还请考虑这些故事)因此,正如 David Carlisle 的回答所指出的那样,相关部分似乎scan_left_brace
在 TeX 程序的源代码中(可以作为一本书,texdoc tex
或在线的):
所以你的问题似乎可以归结为为什么 scan_left_brace
(如 from 所调用的scan_toks
,它在执行等操作时被调用\uppercase
)忽略空格和\relax
标记。TeX 的更改日志中提供了一些线索(可通过texdoc errorlog
或获取)在线的)(要理解它,另请参阅TeX 错误注释和论文TeX 的错误,重印并附加了补充和更正,作为第 10 章和第 11 章文学编程)。如果你查找相关的 403 和 404 部分,你会看到:
[1978年5月19日] 变更 251 [算法异常]。跳过
scan_math
过程中的空白。[此空白跳过最终将进入scan_left_brace
。][影响 §403.][1981年3月5日] 变更 498 [清理一致性]。在必需的左括号前允许可选空格,例如
\if AA {...}
。[参见变更 251。][影响 §403.][1983 年 5 月 28 日] 变更 699 [清理一致性]。在数学模式中以及其他一些可能出现错误的
\relax
地方,将“ ”当作空格忽略。\relax
[影响 §404.]
(FWIW,TeXbook序言的日期为 1983 年 6 月;该书首次出版于 1984 年。
我认为这可能会为这个问题提供一些线索(如果我理解的话)。至少对于空间来说,有很多例子是有意义的。当谈到时\relax
,请注意,就像§404“获取下一个非空白非放松非调用标记”一样,还有另一个§406“获取下一个非空白非调用标记”,其中\relax
不会被忽略,并且它在另一个地方使用(如scan_optional_equals
)。所以你可能会问为什么每个地方都选择忽略\relax
而不是不忽略,而且可能很难(对我来说)解释每一个选择(尽管这一定是有意识的选择,因为选择其他方式会很容易)。
答案3
根据 David Carlisle 和 ShreevatsaR 的有益回答,我提出一个初步建议:
如果 TeX 需要特定的句法数量,它会忽略\relax
标记,除非有充分的理由不忽略它们。
让我通过评估在哪些情况下 a\relax
会被忽略(在可能的扩展之后)以及在哪些情况下不会忽略来证明这一点。首先,以下是 TeXbook 中提到的<filler>
可能出现 a 的情况:
- 在(由于扩展可能隐含的)左括号之前,例如在 a
<general text>
、 a<box specification>
、之后\insert
和\vadjust
中\noalign
; - 当分配一个
<token variable>
another<token variable>
(或一个<general text>
,如上所述)时; - 在数学模式中作为
<math field>
或 的一部分<delim>
。
但是,查看 TeX §404“获取下一个非空白非放松非调用标记”被调用的情况列表(可以在ShreevatsaR 的回答),实际上还有一些,据我所知,TeXbook 中没有提到:
- 在任何
<box>
and之前<box or rule>
(仅出现在 中<leaders>
); - 在任何
\global
,\long
和\outer
前缀之后; - 在或
<leaders>
之前。<horizontal skip>
<vertical skip>
通过查看语法规则,我只能发现少数情况下 a\relax
实际上不会被忽略甚至被禁止:
- 当预期出现单个
<token>
,包括一个 时<control sequence>
(例如在\show
、\afterassignment
、\let
、\def
或 之后\chardef
); - 作为 的一部分
<file name>
; - 当预期某事可能
<digit>s
由(或<hex digit>s
或<octal digit>s
)和/或 TeX 的关键字(pt
、at
、by
等等)组成,其中包括<number>
、<dimen>
、<mudimen>
、<glue>
; - 当不需要任何特定内容时(例如,读取下一个命令、某种
<material>
参数和替换文本时)。
以下是我能想到的关于上述每个观点的充分理由:
\relax
在这种情况下可能是前面的命令的参数。- 由于不可扩展,它只能作为文件名的分隔符。
- 的最重要用途之一
\relax
是分隔数字,例如\def\a{\count0=3\relax} \a0
防止30
分配的值。如果可以成为此类分配的一部分,则此功能将丢失\relax
。现在关键的部分是,\relax
每当数字常量可能接下来,而不仅仅是当确实有一个时。这就是为什么对于两个\toksdef
标记\a
和\b
,\a=\b
和\a=\relax\b
都是合法的(因为不需要数字),但如果它们是\countdef
标记,则只允许第一个。 - 除其他外,这允许
\relax
成为宏定义的参数文本的一部分。
总而言之,在我看来,如果预期某些特定的句法量,\relax
如果它不能充当有意义的分隔符,则会被忽略。