diff --git a/dragonbook/docs/README.md b/dragonbook/docs/README.md index fc5b9f0..ccf3381 100644 --- a/dragonbook/docs/README.md +++ b/dragonbook/docs/README.md @@ -241,3 +241,49 @@ E => E + E => id + id * id ``` +### FIRST 集合 + +FIRST 集合是指一个符号串能够推导出的所有符号串中处于串首的终结符号组成的集合。对于一个非终结符号 *A*,FIRST(A) 是从 *A* 推导出的所有字符串的第一个终结符号的集合。 + +1. **直接收取**:对于形如 *U*→*a*… 的产生式(其中 *a* 是终结符),将 *a* 加入到 FIRST(U) 中。 +2. **反复传送**:对于形如 *U*→*P*… 的产生式(其中 *P* 是非终结符),将 FIRST(P) 中的所有元素传送到 FIRST(U) 中。 +3. **处理空串**:如果 *P* 能够推导出空串 *ϵ*,则继续处理 *P* 后面的符号,直到找到一个非空的终结符或到达产生式的末尾。 + +#### 示例 + +对于文法: + +``` +S → ABc +A → a | ε +B → b | ε +``` + +- FIRST(A) = {a, ε} +- FIRST(B) = {b, ε} +- FIRST(S) = {a, b, c} + +### FOLLOW 集合 + +FOLLOW 集合是指在文法的所有句子中,可能出现在由非终结符 *A* 生成的部分之后的终结符的集合。特别地,输入结束标记(通常用 # 表示)也会包含在 FOLLOW 集合中。 + +1. **初始设置**:将输入结束标记 # 加入到开始符号的 FOLLOW 集合中。 +2. **直接收取**:对于形如 …*Ua*… 的产生式(其中 *a* 是终结符),将 *a* 加入到 FOLLOW(U) 中。 +3. **传递 FOLLOW 集合**:对于形如 *P*→…*U* 的产生式(其中 *U* 是非终结符),将 FOLLOW(P) 中的所有元素传送到 FOLLOW(U) 中。 +4. **处理空串**:对于形如 *P*→…*UB*… 的产生式,如果 *B* 能够推导出空串 *ϵ*,则将 FOLLOW(P) 中的所有元素传送到 FOLLOW(U) 中,并将 FIRST(B) 中除 *ϵ* 外的所有元素加入到 FOLLOW(U) 中。 + +#### 示例 + +对于文法: + +``` +S → ABc +A → a | ε +B → b | ε +``` + +- FOLLOW(S) = {#} +- FOLLOW(A) = {b, c} +- FOLLOW(B) = {c} + +这些集合能帮助编译器构建预测分析表,从而实现高效的语法分析。 \ No newline at end of file