编译原理LL1文法Follow集算法实现
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集算法实现的更多相关文章
- 编译原理 LL1文法First集算法实现
import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap ...
- 编译原理LL1文法分析表算法实现
import hjzgg.first.First; import hjzgg.follow.Follow; import hjzgg.tablenode.TableNode; import hjzgg ...
- 编译原理-First集和Follow集
刚学first集和follow集的时候,如果上课老师没有讲明白或者自己没听明白,自己看的时候还真是有点难理解,不过结合着具体的题目可以理解的更快. 先看一下两种集合的求法: First集合的求法: ...
- 编译原理 First集和Follow集的求法
转载地址 https://blog.csdn.net/Alexander_Frank/article/details/51280798 自上而下分析: FIRST集求法 First集合最终是对产生式右 ...
- 编译原理LL1文法分析树(绘图过程)算法实现
import hjzgg.analysistable.AnalysisTable; import hjzgg.first.First; import hjzgg.follow.Follow; impo ...
- 编译原理LR(0)项目集规范族的构造详解
转载于https://blog.csdn.net/johan_joe_king/article/details/79051993#comments 学编译原理的时候,感觉什么LL(1).LR(0).S ...
- 编译原理: 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 ...
- 编译原理 First,Follow,select集求法
参考:https://blog.csdn.net/CooperNiu/article/details/78524688
- 《编译原理》-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法
<编译原理>-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法 此编译原理确定某高级程序设计语言编译原理,理论基础,学习笔记 本笔记是对教材< ...
随机推荐
- java-类加载器
类加载器 用来加载Java类到Java虚拟机中.一般来说,Java虚拟机使用Java类的方式如下:Java 源程序(.java 文件)在经过Java编译器编译之后就被转换成字节码(.class 文件) ...
- Keeping Async Methods Alive
Consider a type that will print out a message when it’s finalized, and that has a Dispose method whi ...
- Await, and UI, and deadlocks! Oh my!
It’s been awesome seeing the level of interest developers have had for the Async CTP and how much us ...
- php模拟登陆的两种实现方法分析
php模拟登陆的实现方法分析 本文实例分析了php模拟登陆的实现方法.分享给大家供大家参考.具体分析如下: php模拟登陆的实现方法,这里分别列举两种方法实现模拟登陆人人网.具体实例代码如下: 1)使 ...
- bzoj 3714
题意:n<=2000的盒子,有一些里面有球,再给你所有c[i][j](1<=i<=j<=n),即告诉你[i,j]里面球的总数的奇偶性需要花费c[i][j],现在求知道所有的盒子 ...
- ActionBar的使用
ActionBar的使用很普遍,可以充当工具栏使用.本文介绍如何使用ActionBar. 1.ActionBar一般包含有多个工具按钮.所以,需要新建一个xml文件来存放ActionBar中的内容.在 ...
- C++混合编程之idlcpp教程Lua篇(7)
上一篇在这 C++混合编程之idlcpp教程Lua篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件: ...
- 黑马程序员+Winform基础(下)
---------------<a href="http://edu.csdn.net"target="blank">ASP.Net+Android ...
- asp.net linux 环境部署, jexus
cd /tmpwget linuxdot.net/down/jexus-5.8.1-x64.tar.gztar -zxvf jexus-5.8.1-x64.tar.gzsudo mv jexus /u ...
- 一、ASP.NET MVC 路由(一)--- ASP.NET WebForm路由模拟
ASP.NET WebForm 应用,用户请求的是物理文件,其中包括静态页面和动态页面,在Url中的显示都是服务器中一个物理文件的相对路径.但是ASP.NET MVC就不同了,用户请求的是Contro ...