表达式的分解
为了计算表达式的值,解析器需要分解出表达式的独立元素。例如表达式:
A * B – (W + 10)
包括下面这些独立元素:A、*、B、–、(、W、+、10和)。在解析术语中,这样的表达式元素被称为标识符(token),表示表达式中一个不可再分的独立单元。在详细介绍解析器之前,先看看表达式的标识方法,因为它是解析的基础。
为了将表达式分离为单个标识符,需要设计一个过程,从头到尾地扫描表达式,并顺序地返回表达式的每个标识符。该方法必须确定每个标识符的类型,而且必须识别表达式的结尾。在本节介绍的解析器中,实现这些功能的方法名为getToken()。
本章介绍的两个解析器都封装在Parser类中。尽管下文对这个类进行了详细描述,但是现在必须提前说明它的第一部分,以便读者理解getToken()方法的工作过程。Parser类首先定义了一些final变量和域,如下:
class Parser {
// These are the token types.
final int NONE = 0;
final int DELIMITER = 1;
final int VARIABLE = 2;
final int NUMBER = 3;
// These are the types of syntax errors.
final int SYNTAX = 0;
final int UNBALPARENS = 1;
final int NOEXP = 2;
final int DIVBYZERO = 3;
// This token indicates end-of-expression.
final String EOE = "\0";
private String exp; // refers to expression string
private int expIdx; // current index into the expression
private String token; // holds current token
private int tokType; // holds token's type
在表达式解析的过程中,每个标识符必须有一个与之相关的类型。因此Parser类首先定义了几个常数,表明标识符的各个不同类型。本章中所介绍的解析器只用到3种类型:变量、数值和分隔符,它们分别由常量VARIABLE、NUMBER和DELIMITER表示。DELIMITER既可以是运算符,也可以是括号。此外,NONE类型仅仅作为未定义标识符的一个占位符。
接下来,Parser定义了另外几个错误常量,它们代表解析和计算表达式的过程中可能发生的不同类型的错误。SYNTAX代表所有导致非正则表达式的错误;UNBALPARENS表示括号不对称的错误;如果解析器执行时没有表达式被提交,就会报告一个NOEXP错误;DIVBYZERO则表示除数为零的错误。
final变量EOE标志解析器已达到表达式的结尾。
被解析的表达式保存在一个字符串中,exp变量则存储对该字符串的一个引用。这样,exp就可以指向一个形如“10+4”的字符串。而此字符串中的下一个标识符的索引保存在expIdx变量中,初始索引值为0。当前获得的标识符存储在token变量中,其类型则存储在tokType变量中。这些域的属性都是private类型,因为它们只允许由解析器使用并且不能被外部代码修改。
|