什么是编程语言?

编程语言和自然语言非常相似,也有它背后固有的结构和规则来界定语句的正确性。当我们读写自然语言时,语言的规则就在无意中学会了。学习编程语言也是一样,需要长久的读写练习才能掌握。一旦掌握,我们就可以利用这些规则去理解其他人的代码,并写出自己的代码。

在 19 世纪 50 年代,语言学家 Noam Chomsky 定义了一系列关于语言的重要理论。这些理论支撑了我们今天对于语言结构的基本理解。其中重要的一条结论就是:自然语言都是建立在递归和重复的子结构之上的。

举例来说:

The cat walked on the carpet.

根据英语的规则,名词 cat 可以被两个由 and 连接的名词代替:

The cat and dog walked on the carpet.

我们可以像之前一样再次使用这个规则,将 cat 替换为两个使用 and 符号连接的新名词。我们还可以使用另外一个规则,将一个名词替换为一个形容词加一个名词,其中形容词作为对名词的修饰:

The cat and mouse and dog walked on the carpet.

The white cat and black dog walked on the carpet.

以上,我们只是简单的举两个例子。英语的语法规则远不止于此,汉语的语法规则就更复杂了,呵呵。

我们注意到,在编程语言中也有相似的规则。在 C 语言中,if 语句可以包含多条的新语句,新语句当然也可以是另一个 if语句。这些递归和重复的规则在语言的其他部分也同样是适用的。

if (x > 5) { return x; }

if (x > 5) { if (x > 10) { return x; } }

Chomsky 提出的理论是非常重要的。它意味着,虽然一门语言可以表达无限的内容,我们仍然可以使用有限的规则去解析所有用该门语言写就的东西。这些有限的规则就叫语法(grammar)。

对于语法,我们有多种表达方式。最容易想到的方式就是使用白话文。譬如,我们可以这样说:“句子必须是动词短语”“动词词组可以是动词,也可以是副词加动词” 等等 ( 译注:事实上,这也是我们最初学习英语语法的主要方式 )。这种形式对于人类来说是非常容易理解的,但是对于计算机却太模糊的、难以理解的。所以在写程序时,我们需要对语法有一个更标准化的描述。

为了定义一门编程语言(例如我们将要编写的 Lisp),我们首先需要能够正确解析用户按照语法规则写就的程序。为此需要编写一个语法解析器,用来判断用户的输入是否合法,并产生解析后的内部表示。内部表示是一种计算机更容易理解的表示形式,有了它,我们后面的解析、求值等工作会变得更加的简单可行。

但是这一部分往往是枯燥繁琐的体力活,我们显然不希望在这上面浪费时间。所以我们就采用了一个叫做 mpc 的库来帮助我们完成工作。