为什么以下 TeX 手稿在使用 TeX 版本 3.14159265(TeX Live 2017)编译时会出现错误?
\catcode`}=12}\bye
错误是:
! Too many }'s.
<recently read> }
l.1 \catcode`}=12}
\bye
我期望的是编译能够成功完成,并且结果dvi
文件将由单个字符组成}(右括号)。
这个问题与这个但不同的是,我对如何打印出右括号不感兴趣,而是对为什么所描述的方法会失败感兴趣。
答案1
您的输入失败,原因已在上一个问题中解释,您需要
\catcode`}=12 }\bye
因此该数字}
在标记之前就已经完成了。
答案2
当 TeX 寻找数字时,它会继续扫描标记并扩展它们,直到找到无法解释为数字的不可扩展标记(在已设置的基数中,默认为十进制)。
如果这个不可扩展的标记是空格标记,它将被忽略(但只有一个)。
这意味着
\catcode`}=12}
当数字完成时,分配还未执行,并且}
已用其当前类别代码(即 2)进行标记。
总是用空格结束常量。引用 TeXbook:
为了获得最佳效果,总是在数字常量后面加一个空格;这个空格告诉 TeX 常量已完成,这样的空格永远不会“到达”输出。事实上,当常量后没有空格时,TeX 实际上必须做更多的工作,因为每个常量都会继续,直到读取了一个非数字;如果这个非数字不是空格,TeX 会获取您已有的标记并将其备份,以备再次读取。(另一方面,当常量后面紧跟着其他字符时,作者通常会省略空格,因为额外的空格在文件中看起来确实很有趣;美观比效率更重要。)
这与其他作业不同:
\def\foo{1} % just for an example
\chardef\foo=12\foo
不会等同于\chardef\foo=121
,因为在这些情况下,TeX 会暂时将 设置\foo
为等同于\relax
,直到它能够执行赋值。因此,第二个\foo
停止搜索数字,并且不会\foo
进行 的扩展。另一方面
\chardef\foo=12 \foo
工作原理相同,并且更清晰。