enum kind {
IF, LPAREN, ID, ...
};
struct token {
enum kind k;
char *lexeme;
}
token nextToken()
c = getChar();
switch(c)
case '<': c = getChar();
switch(c)
case '=': return LE;
case '>': return NE;
default: rollback();return LT;
case '=': return EQ;
case '>': c = nextChar();
switch(c)
...
1. e -> ε
2. | c (c∈∑)
3. | e | e
4. | e e
5. | e*`
1. ε
2. a,b
3. ε|ε, ε|a,...
4. εa,εb,ab,εε,a(ε|a),a(ε|b),...
5. (a(ε|a))*,ε闭包...
if: i ε ∑, f ε ∑,i与f之间存在一个连接符,连接后依然是正则表达式
int: i ε ∑, n ε ∑,t ε ∑, 它们之间存在两个连接符,由正则表达式的归纳可知它们依然是正则表达式
DFA
和NFA
{(q0,a)->q1,(q0,b)->q0,
(q1,a)->q2,(q1,b)->q1,
(q2,a)->q2,(q2,b)->q2,
...
}
- 字母表:{a,b}
- 状态集:{0,1,}
- 初始状态:0
- 终结状态集:{1}
- 函数转移
{(q0,a)->{q0,q1},
(q0,b)->{q1},
(q1,b)->{q0,q1},
...
}
q0 <- eps_closure (n0) //求n0状态的ε_闭包 -> q0 = {n0};
Q <- {q0} // Q = {q0};
workList <- q0
while (workList != []) //当工作表不为空
remove q from workList //取出工作表一个元素
foreach (character c) // 对256个字符做循环
t <- e-closure(delta(q,c)) // 求变节点,再求节点闭包
D[q,c] <- t // (q0,c) -> q1
if (t\not\in Q)
add t to Q and workList // 如果子集合t没有包含在集合Q上,则把它加到Q
/** 深度优先时间复杂度:O(N) */
// 全局变量,集合,空集
set closure = {};
void eps_closure (x)
closure += {x} // 把x加进集合
forreach (y: x--ε--> y) // x通过边ε到达y
if (!visited(y)) // 如果y没走过,递归走y
eps_closure (y)
// 如果一开始有多个节点,则求多个节点的闭包之后求并集
// S:一个状态的集合,split:切分
split(S)
foreach (character c)
if (c can split S)
split S into T1,T2,...,Tk
hopcroft ()
split all nodes into N,A // 把所有切分为两个不可相容的状态,接受和不可接受状态,
while (set is still changes)
split(s)