目录
第一章 简介
编译器的实现
阶段一:语义分析
阶段二:语法树的建立
阶段三:代码生成
第二章 词法分析
一
词法分析:将字符流分割成特定关键字、字符串、符号等组成的单词流。
记号:编译器返回的单词。
LPAREN:左括号
RPAREN:右括号
enum kind{IF,LPAREN,ID,INTLIT,...};
struct token{
enum kind k; //符号类型
char *lexeme; //读取的数值
};
e.g. if(x>5)
token{k=IF,lexeme=0};
token{k=LPAREN,lexeme=0};
token{k=ID,lexeme="x"};
...
词法分析任务:字节流到记号流
字节流:与被编译语言密切相关(ASCII,Unicode……)
记号流:编译器内部定义的数据结构,编码所识别出的词法单元。
二、词法分析器
实现方法:手工编码实现法(手动敲代码)、词法分析器的生成器(自动)
1.转移图算法(> = < >= <=)
token nextToken(){
c=getchar();
switch(c){
case '<' : {
c=getchar();
switch(c){
case '=': return LE;
case '>': return NE;
case '<': rollback();return LT;
}
}
case '=': return EQ;
case '>':
//同上<
}
}
2.标识符和关键字有交集,故需要分别识别标识符和关键字
3. 关键字表算法:对给定语言的所有关键字,构造关键字构成的哈希表H,可以节约时间在O(1)内完成
三、正则表达式
自动生成:声明式的规范,词法分析器
1.正则表达式
选择
连接
闭包*:重复零次或多次
例子:C语言中的标识符用正则表达式表示
标识符:以字母或下划线开头,后面跟0个或者多个字母、数字或下划线
2.语法糖
[c1-cn] == c1|c2|...|cn(c1到cn中的任意一个选择)
e+ == 一个或多个e
e? == 零个或多个e
“a*” == a*自身,不是a的科恩闭包
e{i,j} == i到j个e的连接
. == 除了'\n'外的任意字符