![为什么某些字符不允许出现在命令序列中](https://linux22.com/image/263665/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%9F%90%E4%BA%9B%E5%AD%97%E7%AC%A6%E4%B8%8D%E5%85%81%E8%AE%B8%E5%87%BA%E7%8E%B0%E5%9C%A8%E5%91%BD%E4%BB%A4%E5%BA%8F%E5%88%97%E4%B8%AD.png)
据我所知,控制序列以任何非字母字符结束,例如\mycsA
是一个标记,但\mycs1
有两个标记。这意味着带星号的命令\mycs*
实际上是两个标记,其中*
是第一个“参数” \mycs
(即使\mycs
没有定义为接受参数。这似乎比定义一组更小的字符来结束控制序列(例如空格)更令人困惑。TeX 按照其设计的方式运行有什么好处?
编辑我从大卫的回答中意识到,我对终止字符的关注是不正确的,我更感兴趣的是只允许在命令序列中轻松使用一小部分字符的优点/缺点。
答案1
为什么?除了最初设计该系统的人之外,没有人能真正回答这些问题。但在大多数语言中(当然是那个时代的大多数语言),语言名称的语法是通过明确列出允许的字符而不是列出终止字符来定义的。在 c 或 fortran 或大多数其他编程语言中,abc+xyz*rst
将有三个变量标记由运算符标记分隔+
,*
因此这并不罕见。
但与这些语言不同的是,TeX 中的词汇规则几乎没有固定的,所以如果你想允许 在多字母命令名称中+
使用*
\catcode`\*=11 \catcode`\+=11
然后您可以将其定义\foo*+
为命令,但是\alpha+\beta
它将不再起作用,您必须这样做\alpha +\beta
。
不太准确的说法
\mycs* 实际上是两个标记,其中 * 是 \mycs 的第一个“参数”(即使 \mycs 没有定义为接受参数)。
*
一般来说,它不是一个参数,而只是\mycs
输出流中的下一个标记,考虑\alpha*\beta
一下它*
只是被排版为标记之间的中缀运算符。
答案2
观察以下事物的行为:
如果*
是宏名称的一部分,那么必然$\alpha*\beta$
导致Undefined control sequence: \alpha*
,这并不是人们所期望的。
当然,您可以使用例如代替x
,*
但我喜欢它的方式:\section
和\section*
,而不是\section
和\sectionx
。
在输入流中,如果字符序列是转义字符(\
默认情况下)后跟至少一个字母字符(a-zA-z
默认情况下,@
在某些地方_
和语法:
中expl3
;通常任何字符都可以“变成字母”),则该字符序列将转换为命令序列。您可以拥有包含非字母的宏名称,但不能直接调用它们,您必须使用\csname...\endcsname
。
答案3
在这个网站上,Andrew Stacey 有一条回答或评论,大意是 TeX 的代码语法很奇怪,因为该语言的设计目的是隐藏在文档的文本中。对于宏来说,这是真的,因为它们会扩展并消失,但对于宏来说名称同样,代码解析器也应该足够保守,不会在执行时弄乱文本。特别是因为 TeX 的设计考虑了数学,所以任何特殊符号都应该保留给作者用于语义,而不是程序员用于语法,这似乎是相当合理的。有迹象表明 Knuth 认为宏语言是一种支持功能,而不是 TeX 写作的主要活动。因此,可以理解的是,编写懒惰但正确的文本比编写懒惰但正确的 TeX 更容易。