词法分析器的简单实现方法
词法分析器的构造方法
1.手工编码实现方法
2.词法分析器的生成器
手工编码转移图
- 判断”>” , “<” , “>=” , “<=” , “=” 及 “<>”(不等于)的逻辑转移图
- 如果第一个字符为 “<” 或 “>”则需要读取第二个字符来判断返回值
- 图中的 “星号” 代表读取到的字符为”<” , “>” , “=”之外的其他字符,需要进行回滚(rollback)操作
伪代码表示方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| //定义一个函数返回值为 token 即记号流的数据结构 token nextToken() //读取第一个字符 c = getChar(); //分支判断 switch (c) case '<' : //读取第二个字符 c = getChar(); switch(c) case '>':return NE; case '=':return LE; //否则进行回滚操作 default:rollback(); return LT; case '=' : return EQ; case '>' : /读取第二个字符 c = getChar(); switch(c) case '=':return GE; //否则进行回滚操作 default:rollback(); return GT;
|
回滚操作的实现
回滚操作要求将文件流或者数组索引向前移动一个字符,因此有两种方法进行回滚操作
文件流回滚
对文件的操作在C中需要一个函数
头文件:
定义函数:
1 2 3 4 5 6 7 8 9 10 11 12
| int fseek(FILE * stream, long offset, int whence); stream: 你打开文件的索引 offset:偏移量 whence:offset基于此参数进行移动,此参数有3个值 SEEK_SET 从距文件开头offset 位移量为新的读写位置. SEEK_CUR 以目前的读写位置往后增加offset 个位移量. SEEK_END 将读写位置指向文件尾后再增加offset 个位移量. 当whence 值为SEEK_CUR 或SEEK_END 时, 参数offset 允许负值的出现.
|
因此实现代码如下
1 2 3 4 5 6
| int rollback() { int result; result = fseek(*file , -1 , SEEK_CUR); return result; }
|
优缺点
优点:不需要维护数组,节省内存
缺点:直接操作源文件不安全且直接从文件中读字符速度较慢
数组回滚
维护一个数组,将源文件读入数组中,直接对数组指针进行操作
1 2 3 4 5 6
| void rollback() { //检测数组是否越界 if(_filePositon>0) _filePositon --; }
|
优缺点
优点:直接操作数组,效率高
缺点:当源文件较大时,需要占用较大的内存空间