元字体语言是上下文无关语法吗?
我是词法分析器/解析器/编译器编写的新手,我试图大致了解编写元字体编译器有多难。
它不是。Metafont 语言基本上是一个在令牌流上运行的宏扩展器。这是一个巧妙但非常复杂的设计,允许在运行时更改语法。标记不是固定的,就像在大多数语言中一样,但它们是可变的,它们的含义可以在运行时改变。
Metafont 区分了用作变量名称一部分的标记(命名为tags)和用作句法元素(命名为sparks)。当解析器遇到一个标签时,它首先查找标签的含义,然后再进行任何评估。其结果是,在元字体程序执行期间,令牌流的含义可能会完全改变!
以 mf 中的以下示例为例:
$ mf
This is METAFONT, Version 2.718281 (TeX Live 2013/Debian)
**expr
(/usr/share/texlive/texmf-dist/metafont/base/expr.mf
gimme an expr: 1plus5
>> plus5
gimme an expr: begingroup let plus=+ endgroup
>> vacuous
gimme an expr: 1plus5
>> 6
令牌流1plus2
解析为1*plus2
,其中
plus2
是一个变量,因为plus
被定义为一个标签。在第二个表达式中,我们重新定义plus
为与 具有相同含义的火花+
。(begingroup
需要在表达式中包含命令)。当我们再次解析1plus5
时,它代表1 + 5
,所以评估为6
!
metafont中的宏扩展很复杂,可以扩展变量,但是sparks也可以包含宏,扩展规则不同。还有用于不同固定性的中缀函数的扩展器。了解这一点的最好方法是阅读metafontbook。