编译器的前端可以分成如下过程:
=》前端=》词法分析器=》记号=》语法分析器=》抽象语法树=》语义分析器=》中间表示=》
词法分析的任务是将程序员所写的程序切分成记号流。
if (x > 5)
y = "hello";
else
z = 1;
经过词法分析器分析之后,会被字符切分为如下内容
IF LPAREN IDENT(x) GT INT(5) RPAREN
IDENT(y) ASSIGN STRING("hello") SEMICOLON
ELSE
IDENT(z) ASSIGN INT(1) SEMICOLON EOF
记号的数据结构定义,类似如下代码
enum kind {IF, LPAREM, ID, INTLIT, ...}
struct token
{
enum kind k;
char *lexeme;
}
词法分析器的任务:字符流到记号流的转换
至少两种的实现方案:
如果我们有<=、<>、<、=、>、>=、>符号,如下图,我们的提取步骤,根据第一个字符,我们可以按照下图步骤读取对应的符号。
其他的标识符转移图和上述的类似。
在标识符识别的时候,单独加上标识符的识别
关键字表算法
如何使用正则表达式?
参见正则表达式文章连接:正则表达式-CSDN博客
输入的字符串=》FA=》{YES, NO}
可以看成一个有边和节点的有向图;
Thompson算法:正则表达式=》NFA
子集构造算法:NFA=>DFA
Hopcroft最小化算法:DFA=>词法分析器代码
nextToken()
state = 0
stack = []
while (state != ERROR)
c = getChar()
if (state is ACCEPT)
clear(stack)
push(state)
state = table[state][c]
while (state is not ACCEPT)
state = pop()
rollback()
上述伪代码中的stack 是为了 最长匹配
netxToken()
state = 0
stack = []
goto q0
q0:
c = getChar()
if (state is ACCEPT)
clear(stack)
push (state)
if (c == 'a')
goto q1
q1:
c = getChar()
if (state is ACCEPT)
clear(stack)
push(state)
if (c == 'b' || c == 'c')
goto q1