编译原理初探(四)

词法分析器的简单实现方法


welcome

词法分析器的构造方法

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
#include <stdio.h>

定义函数:

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 --;
}

优缺点

优点:直接操作数组,效率高
缺点:当源文件较大时,需要占用较大的内存空间

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 词法分析器的构造方法
  2. 2. 手工编码转移图
    1. 2.1. 回滚操作的实现
      1. 2.1.1. 文件流回滚
      2. 2.1.2. 数组回滚