语法分析器的两个重要函数 FIRST和FOLLOW

一、FOLLOW的定义

在句型中紧跟在A右边的终结符号的集合

如果A是某些句型的最右符号,那么$在FOLLOW(A)中

A:非终结符

二、计算方法

循环应用下面的规则

1)将$放到FOLLOW(S)中,S是开始符号,$是输入右端的结束标记

2)如果存在一个产生式A->αBβ,那么FIRST(β)中除ε之外的所有符号都在FOLLOW(B)中

3)如果存在一个产生式A->αB,或A->αBβ且FIRST(β)包含ε,那么FOLLOW(A)中的所有符号都在FOLLOW(B)中

三、代码实现

/**
* P141 FOLLOW(A)集合
* @param symbol
* @return
*/
public Set<Terminal> follow(Nonterminal symbol) {
Set<Terminal> result = new HashSet<>(); // 将$放到FOLLOW(S)中,S是开始符号,$是输入右端的结束标记
if (symbol.equals(start)) {
result.add(Terminal.dollar);
} // 遍历所有产生式
for (Production production : this.productions) {
if (!production.getBody().contains(symbol)) {
continue;
} for (int i=0; i<production.getBody().size(); i++) {
Symbol tmp = production.getBody().get(i);
if (!tmp.equals(symbol)) {
continue;
}
if (i + 1 == production.getBody().size()) {
if (production.getHead().equals(symbol)) {
continue;
}
//如果存在一个产生式A->αB,那么FOLLOW(A)中的所有符号都在FOLLOW(B)中
Set<Terminal> headFollow = follow(production.getHead());
result.addAll(headFollow);
} else {
List<Symbol> tokens = new ArrayList<>();
for (int j=i+1; j<production.getBody().size(); j++) {
tokens.add(production.getBody().get(j));
}
Set<Terminal> afterBFirst = first(tokens); //如果存在一个产生式\A->αBβ且FIRST(β)包含ε,那么FOLLOW(A)中的所有符号都在FOLLOW(B)中
if (afterBFirst.contains(Terminal.epsilon)) {
if (!production.getHead().equals(symbol)) {
Set<Terminal> headFollow = follow(production.getHead());
result.addAll(headFollow);
}
} //如果存在一个产生式A->αBβ,那么FIRST(β)中除ε之外的所有符号都在FOLLOW(B)中
afterBFirst.remove(Terminal.epsilon);
result.addAll(afterBFirst);
}
}
} return result;
}

编译器-FOLLOW集合的更多相关文章

  1. FIRST集合、FOLLOW集合、SELECT集合以及预测分析表地构造

    FIRST集合.FOLLOW集合.SELECT集合以及预测分析表地构造 FIRST集合的简单理解就是推导出的字符串的开头终结符的集合. FOLLOW集合简单的理解就对于非终结符后面接的第一个终结符. ...

  2. FIRST集合、FOLLOW集合及LL(1)文法求法

    FIRST集合 定义 可从α推导得到的串的首符号的集合,其中α是任意的文法符号串. 规则 计算文法符号 X 的 FIRST(X),不断运用以下规则直到没有新终结符号或 ε可以被加入为止 : (1)如果 ...

  3. first集合及follow集合

    前面那片文章生成的语法分析表并不是最优的,因为有些项在遇到错误输入的时候,并不是采取报错,而是执行规约,直到不能再规约的时候才报错.这是不科学的,我们需要在得到错误输入的时候立马报错,为了实现这个功能 ...

  4. first集合follow集的求法

    FIRST集的定义 : 设G=(VT,VN,P,S)是上下文无关文法 FIRST(a)={a|a=>*ab,a∈VT, a,b∈V*} 若a=>*ε则规定ε∈FIRST (a) FIRST ...

  5. PL/0编译器(java version)–Praser.java

    1: package compiler; 2:   3: import java.io.IOException; 4: import java.util.BitSet; 5:   6: /** 7: ...

  6. atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结

    atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结 1. 建立AST 抽象语法树 Abstract Syntax Tree,AST) 1 ...

  7. 编译原理LL1文法Follow集算法实现

    import hjzgg.first.First; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set ...

  8. 简单的FOLLOW集演示程序

    /* * 该程序用于计算某个非终结符的 FOLLOW 集合 * RexfieldVon * 2013年6月30日16:02:47 */ #include <stdio.h> #includ ...

  9. 怎样求FIRST集、FOLLOW集和SELECT集

    一,要知道什么是终结符和非终结符. 终结符:通俗的说就是不能单独出现在推导式左边的符号,也就是说终结符不能再进行推导. 非终结符:不是终结符的都是非终结符.(非男即女,呵呵) 如:A-->B,则 ...

  10. 简单的C语言编译器--语法分析器

      语法分析算是最难的一部分了.总而言之,语法分析就是先设计一系列语法,然后再用设计好的语法去归约词法分析中的结果.最后将归约过程打印出来,或者生成抽象语法树. 1. 设计文法 以下是我的文法(引入的 ...

随机推荐

  1. EF Core – Table / Entity Splitting

    参考 Docs – Advanced table mapping Table Splitting Table Splitting 指的是把一个表映射到多个 Entity,或者反过来说就是把多个 Ent ...

  2. QT6跨平台开发

    QT6跨平台开发 使用AI技术辅助生成 QT界面美化视频课程 QT性能优化视频课程 QT原理与源码分析视频课程 QT QML C++扩展开发视频课程 免费QT视频课程 您可以看免费1000+个QT技术 ...

  3. 【赵渝强老师】在Hive中使用Load语句加载数据

    一.Hive中load语句的语法说明 Hive Load语句不会在加载数据的时候做任何转换工作,而是纯粹的把数据文件复制/移动到Hive表对应的地址.语法格式如下: LOAD DATA [LOCAL] ...

  4. 如何在SQL中查找某一字段在哪些表中

    在SQL中,要找出数据库中包含特定字段(列)的所有表,可以使用数据库的系统表或信息架构视图.不同的数据库系统(如MySQL, SQL Server, PostgreSQL等)有不同的系统表和查询方式. ...

  5. [rCore学习笔记 029] 动态内存分配器实现-以buddy_system_allocator源码为例

    在上一部分,我们讲了动态内存分配器的原理是维护一个堆,而且是实现各种连续内存分配方法. 但是上一部分是直接通过引用了buddy_system_allocator来解决的问题. 那么对于内存分配算法有兴 ...

  6. Windows应急响应-QQ巨盗病毒

    目录 病毒背景 样本分析 开启监控 感染病毒 分析病毒行为 C盘文件监控 D盘文件监控 进程监控排查 服务排查 启动项排查 查杀 1.杀掉进程 2.异常服务 3.映像劫持处理 4.hosts文件处理 ...

  7. JNI和HAL 的区别

    JNI (Java Native Interface) 和 HAL (Hardware Abstraction Layer) 在 Android 系统中都扮演着与本地代码交互的重要角色,但它们的功能和 ...

  8. python处理nii文件

    第一步安装nibabel,可以使用命令:pip install nibabel 之后: from nibabel.viewers import OrthoSlicer3D as osdimport n ...

  9. iOS定义常量的两种方式define和FOUNDATION_EXPORT

    FOUNDATION_EXPORT的使用方法: 1.h文件 FOUNDATION_EXPORT NSString * const kTestString; 2.m文件NSString * const ...

  10. 3. 王道OS-操作系统的运行机制,中断和异常

    1. 高级语言- 编译 - 机器指令 (二进制) 2. 内核态和用户态 :刚开机的时候CPU是内核态,当用户启动某个程序的时候CPU是用户态,如果遇到危险,操作系统会夺回CPU的控制权成为内核态,当危 ...