= 更多表达式的Parsing = === 简介 === 上一章节讲述并验证了Parse和Translate普通数学表达式的技术。最后以一个简单Parser作为成果而结束,该parser可以解析任意复杂的数学表达式,但有两个限制: 1. 不支持变量,只支持数字字面量 1. 数字字面量只支持单个数字 === 变量 === {{{ b * b + 4 * a * c }}} 其中a、b、c皆是变量。 要支持变量,只需要在之前的设计上扩展即可。 之前是: {{{ ::= | () }}} 现在要扩展为: {{{ ::= | () | }}} 代码改动非常小,只需要在factor解析那儿增加一种peek操作即可实现。 === 函数 === 除了现有的形式,还剩一种factor是几乎所有编程语言都会支持的:'''函数调用'''。 教程进行到这里就开始增加对函数的Parsing似乎有点太早,因为目前尚未触及到'''参数传递'''之类的问题。而且真实世界的编程语言通常都会有'''type'''机制,支持多种type如function type之类,而type也是目前尚未触及的问题。 但是作者还是决定现在就踏足对函数的Parsing,原因有: 1. 让编译器在某些事情上与最终版很相近 1. 引入一个很值得讨论的新问题 截至目前完成的Parser可以归类为一种叫“predictive parser”的概念:在需要之处通过Peek到的字符来决定动作。但对函数的处理不能如此。 原因其实是人为造成的:每一门编程语言都有所谓的'''标识符'''(identifier)的概念,并约定了一套合规法则。而变量标识符与函数标识符通常有相同的合规法则。因此,parse到标识符时,无法区分是变量还是函数。 怎么办呢?有两种方式处理这个问题: * 标识符在使用前必须前置声明。Pascal采用的这种方式 * 在函数标识符后面追加一个(可能为空的)参数列表。C采用的这种方式 由于目前尚无声明类型的机制,因此这里暂且采用C的方式来处理这个问题。也由于目前尚无参数机制,这里暂且约定只支持空参数列表。妥协之后,当下支持的函数,只是形如X()之流。 ===