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. [转]c++中vector的使用

    C++中的vector使用范例 一.概述 vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector是一个容器,它能够存放各种类型的对象,简 ...

  2. PYTHON学习之路_PYTHON基础(6)

    学习内容: Python模块介绍 1.time &datetime模块 2.random 3.shutil 4.shelve 5.xml处理 6.configparser 7.hashlib ...

  3. Hyper-V初涉_虚拟磁盘链错误的解决方案

    当Hyper-V管理器对虚拟机创建了快照,在Hyper-V虚拟机设置中会看到如下图提示.简单的说,就是创建了快照的虚拟机将不能继续进行编辑. 如果,在对虚拟机的主虚拟磁盘进行了编辑,哪怕仅仅是在Win ...

  4. 关于winform中*.exe.config中的appSettings的节点的读取与修改

    //读取到这个节点 string file = System.Windows.Forms.Application.ExecutablePath; Configuration config = Conf ...

  5. Eclipse - Failed to load the JNI shared Library (JDK)

    When I try opening Eclipse, a pop-up dialog states: Failed to load the JNI shared library "C:/J ...

  6. 编译PHP5缺t1lib包安装

    t1lib_doc.dvi Error解决: 1. 下载t1lib-5.1.2.tar.gz2. 解决依赖关系:sudo apt-get build-dep t1lib 3. 安装:./configu ...

  7. Jquery,javascript 的处理机制

    $(document).ready(function () {    function get() {//        $.ajax({//            type: "Post& ...

  8. ie7,8常见bug,共计257个bug汇总?如何解决ie的历史bug

    ie7.8常见bug,共计257个bug汇总 针对web开发者来说,浏览器的bug,特备是ie的bug是很多人的噩梦,因为ie的更新换代没有ff,chrome,safari,opera那么快,而且ie ...

  9. 我的第一篇Markdown语法博客

    这是我的第一篇使用markdown语法编写的博客 使用的编辑器为Sublime Text2 并且使用了sublog插件, sublog是一个开源项目 sublog 并且参考了作者的博客 AmongOt ...

  10. 在.net中使用aquiles访问Cassandra(三)

    之前我们实现了如何修改数据,还需要相应的删除动作.删除方式会有几种情况,以下分别一一介绍.   1.批量删除,适应于多行多列的情况. public void Remove(string columnF ...