import hjzgg.first.First;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet; public class Follow {
private Map<String, Set<Character>> first = null;
private Map<String, Set<Character>> follow = new TreeMap<String, Set<Character>>();
private Map<String, String[]> mp = null;
public Follow(Map<String, String[]> mp, Map<String, Set<Character>> first) {
super();
this.first = first;
this.mp = mp;
} public Map<String, Set<Character>> getFollowSet(){
return follow;
} private void getFirstSet(Set<Character> st, String node, int k){
if(k >= node.length()) return;
if(node.charAt(k)=='\'') --k;
String nextNode = "" + node.charAt(k);
if(k+1<node.length() && node.charAt(k+1)=='\''){
nextNode += '\'';
++k;
}
if(!mp.containsKey(nextNode)){//终结点
st.add(nextNode.charAt(0));
} else {
st.addAll(first.get(nextNode));
if(first.get(nextNode).contains('$'))
getFirstSet(st, node, k+1);
}
} private void findFollow(String curNode){
Set<Character> st = null;
for(String leftNode : mp.keySet()){
String rightNodes[] = mp.get(leftNode);
for(int i=0; i<rightNodes.length; ++i){
int index = rightNodes[i].indexOf(curNode, 0);
while(index != -1){
int nextIndex = index + 1;
if(curNode.length()==1 && index+1<rightNodes[i].length() && rightNodes[i].charAt(index+1)=='\''){
index = rightNodes[i].indexOf(curNode, nextIndex);
continue;
}
index = index+curNode.length();
if(index == rightNodes[i].length()){//末尾的非终结点, A->@B
if(follow.get(leftNode) == null)
findFollow(leftNode);
if(follow.get(curNode) == null){
st = new TreeSet<Character>();
st.addAll(follow.get(leftNode));
follow.put(curNode, st);
}
else follow.get(curNode).addAll(follow.get(leftNode));
} else {
String nextNode = ""+rightNodes[i].charAt(index);
if(index+1 < rightNodes[i].length() && rightNodes[i].charAt(index+1)=='\''){
nextNode += '\'';
++index;
}
if(mp.containsKey(nextNode)){//非终结符
if(first.get(nextNode).contains(new Character('$'))){//A->@B&, 而 &->$
if(follow.get(leftNode) == null)
findFollow(leftNode);
if(follow.get(curNode) == null){
st = new TreeSet<Character>();
st.addAll(follow.get(leftNode));
follow.put(curNode, st);
}
else follow.get(curNode).addAll(follow.get(leftNode));
} //好特殊的情况啊....
{//A->@B&, First(&)^$ 放入follow(B)
Set<Character> tmpSt = new TreeSet<Character>();
getFirstSet(tmpSt, rightNodes[i], index);
tmpSt.remove('$');
if(follow.get(curNode) == null){
st = new TreeSet<Character>();
st.addAll(tmpSt);
follow.put(curNode, st);
}
else follow.get(curNode).addAll(tmpSt);
}
} else {//终结符
if(follow.get(curNode) == null){
st = new TreeSet<Character>();
st.add(nextNode.charAt(0));
follow.put(curNode, st);
}
else follow.get(curNode).add(nextNode.charAt(0));
}
}
index = rightNodes[i].indexOf(curNode, nextIndex);
}
}
}
} public String followKernealCode(){
String content = "";
boolean flag = true;
for(String leftNode : mp.keySet()){
if(flag){
Set<Character> st = new TreeSet<Character>();
st.add('#');
follow.put(leftNode, st);
flag = false;
}
findFollow(leftNode);
}
//打印first集合
System.out.println("Follow 集合如下:");
for(Map.Entry<String, Set<Character>> entry : follow.entrySet()){
content += entry.getKey() + " : " + entry.getValue() + "\n";
System.out.println(entry.getKey() + " : " + entry.getValue());
}
return content;
} public static void main(String[] args) {
String[] rightLinearGrammar = {
"E->TE\'",
"E\'->+TE\'|$",
"T->FT\'",
"T\'->*FT\'|$",
"F->(E)|i"
}; // String[] rightLinearGrammar = {
// "S->ABc",
// "A->a|$",
// "B->b|$"
// }; Map<String, String[]> mp = new LinkedHashMap<String, String[]>();
try{
for(int i=0; i<rightLinearGrammar.length; ++i){
String split1[] = rightLinearGrammar[i].split("->");
String split2[] = split1[1].split("\\|");
mp.put(split1[0], split2);
} } catch(Exception e){
e.printStackTrace();
System.out.println("右线性文法错误!");
}
First first = new First(mp);
first.firstKernealCode();
new Follow(mp, first.getFirstSet()).followKernealCode();
} }

编译原理LL1文法Follow集算法实现的更多相关文章

  1. 编译原理 LL1文法First集算法实现

    import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap ...

  2. 编译原理LL1文法分析表算法实现

    import hjzgg.first.First; import hjzgg.follow.Follow; import hjzgg.tablenode.TableNode; import hjzgg ...

  3. 编译原理-First集和Follow集

    刚学first集和follow集的时候,如果上课老师没有讲明白或者自己没听明白,自己看的时候还真是有点难理解,不过结合着具体的题目可以理解的更快. 先看一下两种集合的求法: First集合的求法:   ...

  4. 编译原理 First集和Follow集的求法

    转载地址 https://blog.csdn.net/Alexander_Frank/article/details/51280798 自上而下分析: FIRST集求法 First集合最终是对产生式右 ...

  5. 编译原理LL1文法分析树(绘图过程)算法实现

    import hjzgg.analysistable.AnalysisTable; import hjzgg.first.First; import hjzgg.follow.Follow; impo ...

  6. 编译原理LR(0)项目集规范族的构造详解

    转载于https://blog.csdn.net/johan_joe_king/article/details/79051993#comments 学编译原理的时候,感觉什么LL(1).LR(0).S ...

  7. 编译原理: FIRST(x) FOLLOW(x) SELECT(x)的计算

    目录 First计算 Follow计算 Select计算 已知文法G[S]: S→MH|a H→LSo|ε K→dML|ε L→eHf M→K|bLM 判断G是否是LL(1)文法. First计算 F ...

  8. 编译原理 First,Follow,select集求法

    参考:https://blog.csdn.net/CooperNiu/article/details/78524688

  9. 《编译原理》-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法

    <编译原理>-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法 此编译原理确定某高级程序设计语言编译原理,理论基础,学习笔记 本笔记是对教材< ...

随机推荐

  1. jQqery EasyUI dategrid行中多列数据的可编辑操作

    最近的项目中需要在前台dategrid列表中直接修改某些列的数据,并且修改后的数据需要不通过后台而自动更新在列表中. 带着这一问题开始寻找实现的思路,首先想到的就是去jQqery EasyUI官网找例 ...

  2. Hyper-V初涉_Hyper-V虚拟机文件交换

    使用虚拟机时,文件交互就显得十分重要.如果能实现物理机与虚拟机之间的文件交互,将会节省大量的时间.比较可惜的是,Hyper-V虚拟机并不支持USB存储设备,所以在文件交换上略显麻烦. 与Hyper-V ...

  3. XAF 官方问题笔记

    1.How to print report direct, and print preview via an simple action? 如何通过一个按钮直接打印报表或者打印预览报表 https:/ ...

  4. android开发中监控android软件网络请求的软件Charles使用入门

    1.下载并安状软件,官网在此: http://www.charlesproxy.com/ 2.前题条件,电脑和手机必须在同一网段 3.在Charles界面选择菜单 proxy->proxy se ...

  5. 甲乙(数理逻辑)转自http://www.cnblogs.com/devymex/p/3329635.html

    这是一道历史悠久,又很困难的面试题. 你在旁观主持人和甲.乙两个天才数学家玩猜数字游戏.主持人准备了两个数,告知甲乙:这两个数不同,且大于等于1,小于等于30.然后主持人将两数之积告诉甲,把两数之和告 ...

  6. Web服务器常用设置

    1.Tomcat浏览目录 找到安装目录下的文件/conf/web.xml,  找到以下配置节,将parame-value设置为true即可 <init-param>             ...

  7. ASP.NET 5 入门 (2) – 自定义配置

    ASP.NET 5 入门 (2) – 自定义配置 ASP.NET 5 理解和入门 建立和开发ASP.NET 5 项目 初步理解ASP.NET5的配置 正如我的第一篇文章ASP.NET 5 (vNext ...

  8. MySQL1:MySQL函数汇总

    前言 MySQL提供了众多功能强大.方便易用的函数,使用这些函数,可以极大地提高用户对于数据库的管理效率,从而更加灵活地满足不同用户的需求.本文将MySQL的函数分类并汇总,以便以后用到的时候可以随时 ...

  9. Java设计模式3:工厂方法模式

    工厂方法模式 工厂方法模式是类的创建模式.工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工厂推迟到子类中. 工厂方法模式 工厂方法模式是对简单工厂模式进一步抽象的结果. 假如是不使用反 ...

  10. 从3D Touch 看 原生快速开发

    全新的按压方式苹果继续为我们带来革命性的交互:Peek和Pop,Peek 和 Pop 让你能够预览所有类型的内容,甚至可对内容进行操作,却不必真的打开它们.例如,轻按屏幕,可用 Peek 预览收件箱中 ...