什么是在 TeX 的语法中?

什么是在 TeX 的语法中?

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>

基本上是不是语法规则中的隐式括号意味着扩展,但反过来:扩展意味着括号可能是隐式的。此外,隐式括号被定义为控制序列,它们要么是\let1\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在线的):

第 403 和 404 条

所以你的问题似乎可以归结为为什么 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 的情况:

  1. 在(由于扩展可能隐含的)左括号之前,例如在 a <general text>、 a <box specification>、之后\insert\vadjust\noalign
  2. 当分配一个<token variable>another <token variable>(或一个<general text>,如上所述)时;
  3. 在数学模式中作为<math field>或 的一部分<delim>

但是,查看 TeX §404“获取下一个非空白非放松非调用标记”被调用的情况列表(可以在ShreevatsaR 的回答),实际上还有一些,据我所知,TeXbook 中没有提到:

  1. 在任何<box>and之前<box or rule>(仅出现在 中<leaders>);
  2. 在任何\global,\long\outer前缀之后;
  3. 在或<leaders>之前。<horizontal skip><vertical skip>

通过查看语法规则,我只能发现少数情况下 a\relax实际上不会被忽略甚至被禁止:

  1. 当预期出现单个<token>,包括一个 时<control sequence>(例如在\show\afterassignment\let\def或 之后\chardef);
  2. 作为 的一部分<file name>
  3. 当预期某事可能<digit>s由(或<hex digit>s<octal digit>s)和/或 TeX 的关键字(ptatby等等)组成,其中包括<number><dimen><mudimen><glue>
  4. 当不需要任何特定内容时(例如,读取下一个命令、某种<material>参数和替换文本时)。

以下是我能想到的关于上述每个观点的充分理由:

  1. \relax在这种情况下可能是前面的命令的参数。
  2. 由于不可扩展,它只能作为文件名的分隔符。
  3. 的最重要用途之一\relax是分隔数字,例如\def\a{\count0=3\relax} \a0防止30分配的值。如果可以成为此类分配的一部分,则此功能将丢失\relax。现在关键的部分是,\relax每当数字常量可能接下来,而不仅仅是当确实有一个时。这就是为什么对于两个\toksdef标记\a\b\a=\b\a=\relax\b都是合法的(因为不需要数字),但如果它们是\countdef标记,则只允许第一个。
  4. 除其他外,这允许\relax成为宏定义的参数文本的一部分。

总而言之,在我看来,如果预期某些特定的句法量,\relax如果它不能充当有意义的分隔符,则会被忽略。

相关内容