第 48 页TeXbook,有一个练习
假设纯 TEX 的分类代码有效,但字符
^^A
、^^B
、^^C
分别^^M
属于类别 0、7、10 和 11。从(相当荒谬的)输入行^^B^^BM^^A^^B^^C^^M^^@\M␣
(最后一个字符是空格)产生了什么标记?(请记住,此行后面跟着 ⟨return⟩,即^^M
;并回想一下^^@
表示 ⟨null⟩ 字符,它在INITEX
开始时属于类别 9。)
答案是
两个
^^B
' 不被识别为连续的上标字符,因为第一个^^B
被转换为代码 2,它不等于后面的字符^
。因此结果是七个标记:^^B
7^^B
7M
11|^^B|
␣
10^^M
11 。最后一个是控制字,其名称有两个字母。在 TeX 插入 ⟨return⟩ 标记之前,|M^^M|
后面的 ⟨space⟩被删除。\M
问题1.代码2是什么?
问题2. 如何理解第7类?
^^56\par
\catcode`\@=7
@@56\par
%@^10
\bye
生产
但是,为什么@^10
取消注释会导致错误@^10
?
问题 3. 控制符号后面的空格应该省略。为什么^^B
省略后的空格不^^B^^BM^^A^^B^^C^^M^^@\M
应该被标记为^^B
7 ^^B
7 M
11 ^^A
0 ^^B
7 ^^C
10 ^^M
11 ^^@
9M
控制字10
^^M
5。
由于^^A
0 ^^B
7需要转换为^^B
控制符号,所以是^^B
7 ^^B
7 M
11^^B
控制符号^^C
10 ^^M
11 ^^@
9M
控制字10
^^M
5。
由于控制符号后的空格应省略,所以是^^B
7 ^^B
7 M
11^^B
控制符号^^M
11 ^^@
9M
控制字^^M
5。
由于应省略类别 9,因此它是^^B
7 ^^B
7 M
11^^B
控制符号^^M
11M
控制字^^M
5。
问题4.为什么答案是^^B
7 ^^B
7 M
11^^B
控制符号10
^^M
11M^^M
控制字?
答案1
问题 1
B
是字符代码66,^^B
是字符代码(66 - 64)= 2,也就是代码2。
问题2
以 - 符号开头的两个连续类别代码 7 标记^^
需要具有相同的字符代码,^^B^
可能是两个连续的类别 7 标记,但第一个是字符代码 2,第二个是 94,因此它们不会被解释为^^
并更改以下标记。您的 也是如此@^10
,它们是两个连续的类别 7 标记,但具有不同的字符代码,因此它们被解释为正常的数学上标,这超出了数学模式的范围。
需要^^
有相同的字符代码可以在 TeXbook 的这段文字中找到(注意“另一个相同的字符“):
\ddanger If \TeX\ sees a superscript character (category 7) in any state,
and if that character is followed by another identical character, and if
those two equal characters are followed by a character of code
$c<128$, then they
are deleted and 64 is added~to or subtracted from the code~$c$.
\ (Thus, |^^A| is
replaced by a single character whose code is~1, etc., as explained earlier.) \
However, if the two superscript characters are immediately followed by two
of the lowercase hexadecimal digits |0123456789abcdef|, the
four-character sequence is replaced by a single character having the
specified hexadecimal code.
The replacement is carried out also if such a trio or quartet of
characters is encountered during steps (b) or~(c) of the control-sequence-name
scanning procedure described above. After the replacement is made, \TeX\
begins again as if the new character had been present all the time.
If a superscript character is not the first of such a trio or quartet, it is
handled by the following rule.
问题 3
仅在控制字(由一个或多个类别 11 标记构成的控制序列)之后才会忽略空格,而不会忽略控制符号。\^^B
是一个控制符号(^^B
属于类别 7),因此不会忽略其后的空格。例如,与 的结果进行比较a\$a\par a\$ a\par
。
答案2
您首先需要回顾一下 TeX 如何将输入(字节序列)转换为标记。让我们考虑最常见的情况,即 TeX 从文件接收输入。
操作系统将输入一个记录一次;记录是什么取决于操作系统,但在最常见的情况下,它将是一行文本。此时,将执行第一个操作:
- “记录结束”信号(如果有)与所有带有代码 32 的尾随字符一起被丢弃;
- 在修改记录的末尾
\endlinechar
附加一个带有代码的字符。
注意,类别代码尚未分配。输入处理器(眼睛)处于否(参见第 46 页)并开始逐个字符地检查记录,并将其与表格进行比较\catcode
。
状态否意味着忽略类别代码为 10 的任何字符(这就是初始空格或制表符被丢弃的方式)。当发现某个不具有类别代码 10 的字符时,处理器通常会切换到状态米(这是分配 catcode 和形成控制序列的地方)。
下一个角色将被重新检查并分配其 catcode。现在好戏开始了:
- 如果 catcode 为 5 且状态仍为否,TeX 生成一个
|par|
标记并将其发送到扩展处理器;否则 TeX 会丢弃记录中剩余的所有内容并切换到状态否; - 如果 catcode 为 9,则忽略该字符;
- 如果 catcode 是 1、2、3、4、6、8、11、12、13,则为该字符分配其 catcode 并将其作为字符标记传递给扩展处理器(嘴巴);
- 如果 catcode 为 0,则形成控制序列;
- 如果 catcode 是 7,则会更加有趣。
在第 2 至第 5 种情况下,国家成为米。
案例 5 是练习 8.6 所处理的,并且^^
惯例开始发挥作用。
看到一个角色后X类别代码为 7 时,TeX 会查看下一个字符(尚未形成标记);如果下一个字符是没有相同字符代码和类别代码为X,则将一个 catcode 为 7 的令牌传递给扩展处理器。否则,将继续进行与会议相关的业务^^
(我已在对您的另一个问题的回答中对此进行了解释)。
因此
\catcode`_=7
^^B
__B
_^B
第三个输入是不是触发约定,而前两个则会触发约定。请注意,这与您的问题 2 基本相同:
^^56\par
\catcode`\@=7
@@56\par
@^10
第一^^56
行中的 转换为V
第三^^56
行中的 ;但在第四行中字符代码为不同的,这样它们就不会触发约定。
您也可以^
按照^^5e
惯例输入。但是
^^5e^^5eB
会不是产生与 相同的结果^^B
,因为第一个组合^^5e
实际上被转换为^
字符,但这会^^^5eB
导致四字符。请参阅第 368 页字符表后面的段落:在你读完附录 C 之前,你不应该知道练习 8.6 的答案。
练习 8.6 的部分内容与上段类似。
^^B^^BM^^A^^B^^C^^M^^@\M␣
其中^^A
catcode 为 0,^^B
catcode 为 7,^^C
catcode 为 10,并且^^M
(有趣的是)catcode 为 11。
第一个^^
触发了约定(因为^
被假定为具有类别代码 7),因此形成了具有 ASCII 代码 2 的字符,并且其类别代码确实是 7。但是它后面跟着 ,其类别^
代码为 7,但这并不相同!这与您的 的情况类似@^10
。因此,扩展处理器传递了对 (2,7)(字符代码和类别代码),TeX 继续前进;它发现^
后面跟着^
,因此触发了约定并传递了另一对 (2,7)。
回答找到^^M
是错误的。以下M
是作为对 (77,11) 传递的。下一个^^A
是(按照约定),其 catcode 为 0,因此形成了一个控制序列;下一个字符是^^B
(按照约定),其 catcode 为 7,因此获得了一个控制符号并|^^B|
传递了令牌。下一个^^C
是(按照约定);它的 catcode 为 10,因此对其进行了规范化,并传递了对 (32,10);它不会被忽略,因为它跟在控制符号后面。然后你找到^^M
并传递了对 (13,11)。下一个^^@
被忽略并|M^^M|
形成。
有个窍门!尾随空格是不是其实是有的,因为在检查记录的时候已经被丢弃了,见开头的第一条规则,并且^^M
被添加。