3.4 中缀表达式

    在 FORTH 语言中,我们用 1 2 + 来表达 1 加 2,运算符放在运算对象的后面。在 LISP 语言中,1 加 2 表达为 (+ 1 2),运算符放在运算对象的前面。而数学表达式中用 1+2 来表达,运算符放在运算对象的中间。像这样把运算符放在运算对象之后、之前和之中的表示法分别称为后缀 表达式、前缀表达式、中缀表达式 11。

    11前缀表达式和后缀表达式也被称为波兰表示法和逆波兰表示法,得名于最先研究它们的波兰人 Jan Lukasiewicz。前缀表达式中的括号并不是必需的,因为只要知道 + 和 取的是两个运算对象,即使省略了括号,表达式 + 1 2 3 的含义也是可以理解的。LISP 语言中,有三个以上运算对象的情况也可以写成 (+ 1 2 3 4)。因为有了括号不会导致误解,省略括号是不行的。

    这三种表达式只是表达方法上的约定事项而已。在程序设计语言出现以前,人们仅习惯于用中缀表达式来书写数学表达式。

    FORTRAN 语言就是旨在用已经习惯了的方式编写程序。这就是为什么 FORTRAN 语言的全称为 Formula Translating System(表达式翻译系统)。FORTRAN 语言导入了运算符优先级和结合性等复杂的语法,但程序员可以用习惯的方式来编写数学表达式。

    语法分析器

    语法分析器是把源代码作为字符串读入、解析,并建立语法树的程序。FORTRAN 语言在编译程序时,语法分析器会将源代码的字符串转换为语法树。

    语法的设计和语法分析器的实现是决定语言外在表现的重要因素。语言设计者在设计语法时,会考虑使哪些部分变得编写简便,哪些变得不容易出错,哪些能给用户带来价值等问题。

    但是,从这些角度出发设计的语法在语法分析器中能否实现却是另一个问题。语法的解析方法不同,实现清晰明确的解析的规则也不同。此外,在现有的语言中引入新的功能时,有可能因为和既有的规则发生冲突而产生问题。

    规则的竞争

    在 C++ 语言中增加模块功能时,引入了 vector<int> 这样用不等号括起来的表达方法。这种方法在二重表达时,一侧的符号 >> 就会被解析为既有的移位运算符 >>。语法分析器要解决这个问题并不容易,所以程序员通过增加空白符的方法来避免其变成移位运算符。

    专栏
    当你不知道该学习什么时
    应该学习什么?我们经常听到这样的问题。在回答之前,笔者想先问这样一个问题:你学习的目的是什么?这个如果不明确,提建议就无从下手。我们生活在一个信息爆炸的时代。不管三七二十一统统都学,这样的学习策略已经不再适用。必然要有所学,有所不学。这时,我们就要事先明确
    自己到底想做什么,然后再去学习能够达成这一目标的知识。不知道自己要做什么?或许你从一开始就在苦思,想做一件完美的事情。一件从没有人想到过的,能获得别人赞誉的事情。如果最初的设想太过宏大导致无从下手,那么这一设想就永远不可能实现。还不如从小事做起,从简单的事情做起。在这个过程中,你可以逐渐明白自己哪些已经能做、哪些还不能做,如果要做还要学习哪些知识。长此以往,就能培养出完成更复杂的任务的能力。
    C++
    // OK
    vector<vector<int> > x;
    // NG
    vector<vector<int>> y;

    当然,理想的情况是把语法分析器改良到能同时照顾好两方又不出错的程度。然而现实与理想总是有差距的。由既有规则的羁绊导致不自然的规则产生,这种现象不仅限于 C++ 语言,在其他语言中同样存在。