在编译原理介绍中,我们已经对前端的工作有了大致的了解
词法分析器的任务是读入源程序,对其进行一定的切分,得到记号流
对于字符流和记号流之间的区别,下面给出一个例子来说明
if (x > 5)
y = "hello";
else
z = 1;
对面上面这段程序,在词法分析器的眼中,是这样表示的:
i, f, " ", (, x, " ",>, " ", 5, ), n, " "," ", y, " ", =, .........
可见词法分析器看到的字符流和我们眼中的字符流是不一样的。 而词法分析器的任务就是对字符进行 切分。将 i 和 f 并在一起做为一个 if 关键字,去除掉没有意义的空格等等
对于像IF,LPAREN,IDENT等的单词,我们都称为记号
在记号中,有一些记号是没有属性的,类似于 IF 之类的关键字, IDENT(x) 之类的标识符需要表明其中的元素具体是什么
记号的数据结构定义如下:
enum kind {IF, LPAREN, ID, INTLIT, ...};
struct token{
enum kind k;
char *lexname;
}
因此,对于语句 if (x > 5) 可以转变为
token {
k = IF;
lexname = 0; //0 表示没有赋任何的值
}
token {
k = LPAREN;
laxname = 0;
}
token {
k = ID;
laxname = "x";
}
....
通过上面的学习,我们可以知道词法分析器的任务是将字符流转化为记号流
- 字符流:和被编译的语言密切相关(ASCII(C), Unicode(Java, Swift), or ...)
- 记号流:编译器内部定义的数据结构,编码所识别出的词法单元