LL1 first follow集

合集下载

编译原理课程设计LL(1)文法

编译原理课程设计LL(1)文法

本次课程设计主要是介绍LL(1)文法的一般原理,根据给定的一文法编制调试LL(1)文法语法分析程序,以便对任意输入的符号串进行分析。

本次课程设计的目的主要是加深对预测分析LL(1)文法语法分析的理解,加深对自顶向下语法分析方法的认识。

具体如下:1、对语法规则有明确的定义;2、编写的分析程序能够对给定文法进行正确的语法分析;3、对输入给定的文法,手工计算First、Follow集合以及各产生式的Select 集合,再根据Select集合构造出预测分析表;4、对于输入串,应能根据预测分析表判断识别该输入串是否为给定文法的句子;5、对于遇到的错误,给出简单的错误信息提示,保证能够顺利完成语法分析过程。

前言------------------------------------------------------------- Ⅰ目录------------------------------------------------------------- Ⅱ一、系统分析------------------------------------------------------ 11.1 判断LL(1)文法---------------------------------------------- 11.2 构造预测分析表---------------------------------------------- 1二、系统设计------------------------------------------------------ 22.1 基本设计---------------------------------------------------- 22.2 程序流程图-------------------------------------------------- 2三、系统实现------------------------------------------------------ 33.1 程序主要函数------------------------------------------------ 33.2 程序主要代码------------------------------------------------ 3四、系统测试------------------------------------------------------ 7五、总结---------------------------------------------------------- 8 参考文献---------------------------------------------------------- 9一、系统分析有文法G[E]:E->TG T->FSG->+TG|ε S->*FS|ε F->(E)|i 1.1 判断LL(1)文法当我们需选用自顶向下分析技术时,首先必须判别所给文法是否是LL(1)文法,分析所给文法可知文法中不含左公因子,也不存在左递归,因而再对给定文法计算First 集、Follow 集以及Select 集,对于求出的每个产生式的Select 集,看对于同一个左部非终结符是否存在交集,如果它们的交为空则表示所给文法是LL(1)文法,否则不是L(1)文法。

【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集

【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集

【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集 近来复习编译原理,语法分析中的⾃上⽽下LL(1)分析法,需要构造求出⼀个⽂法的FIRST和FOLLOW集,然后构造分析表,利⽤分析表+⼀个栈来做⾃上⽽下的语法分析(递归下降/预测分析),可是这个FIRST集合FOLLOW集看得我头⼤。

教课书上的规则如下,⽤我理解的语⾔描述的:任意符号α的FIRST集求法:1. α为终结符,则把它⾃⾝加⼊FIRSRT(α)2. α为⾮终结符,则:(1)若存在产⽣式α->a...,则把a加⼊FIRST(α),其中a可以为ε(2)若存在⼀串⾮终结符Y1,Y2, ..., Yk-1,且它们的FIRST集都含空串,且有产⽣式α->Y1Y2...Yk...,那么把FIRST(Yk)-{ε}加⼊FIRST(α)。

如果k-1抵达产⽣式末尾,那么把ε加⼊FIRST(α) 注意(2)要连续进⾏,通俗地描述就是:沿途的Yi都能推出空串,则把这⼀路遇到的Yi的FIRST集都加进来,直到遇到第⼀个不能推出空串的Yk为⽌。

重复1,2步骤直⾄每个FIRST集都不再增⼤为⽌。

任意⾮终结符A的FOLLOW集求法:1. A为开始符号,则把#加⼊FOLLOW(A)2. 对于产⽣式A-->αBβ: (1)把FIRST(β)-{ε}加到FOLLOW(B) (2)若β为ε或者ε属于FIRST(β),则把FOLLOW(A)加到FOLLOW(B)重复1,2步骤直⾄每个FOLLOW集都不再增⼤为⽌。

⽼师和同学能很敏锐地求出来,⽽我只能按照规则,像程序⼀样⼀条条执⾏。

于是我把这个过程写成了程序,如下:数据元素的定义:1const int MAX_N = 20;//产⽣式体的最⼤长度2const char nullStr = '$';//空串的字⾯值3 typedef int Type;//符号类型45const Type NON = -1;//⾮法类型6const Type T = 0;//终结符7const Type N = 1;//⾮终结符8const Type NUL = 2;//空串910struct Production//产⽣式11 {12char head;13char* body;14 Production(){}15 Production(char h, char b[]){16 head = h;17 body = (char*)malloc(strlen(b)*sizeof(char));18 strcpy(body, b);19 }20bool operator<(const Production& p)const{//内部const则外部也为const21if(head == p.head) return body[0] < p.body[0];//注意此处只适⽤于LL(1)⽂法,即同⼀VN各候选的⾸符不能有相同的,否则这⾥的⼩于符号还要向前多看⼏个字符,就不是LL(1)⽂法了22return head < p.head;23 }24void print() const{//要加const25 printf("%c -- > %s\n", head, body);26 }27 };2829//以下⼏个集合可以再封装为⼀个⼤结构体--⽂法30set<Production> P;//产⽣式集31set<char> VN, VT;//⾮终结符号集,终结符号集32char S;//开始符号33 map<char, set<char> > FIRST;//FIRST集34 map<char, set<char> > FOLLOW;//FOLLOW集3536set<char>::iterator first;//全局共享的迭代器,其实觉得应该⽤局部变量37set<char>::iterator follow;38set<char>::iterator vn;39set<char>::iterator vt;40set<Production>::iterator p;4142 Type get_type(char alpha){//判读符号类型43if(alpha == '$') return NUL;//空串44else if(VT.find(alpha) != VT.end()) return T;//终结符45else if(VN.find(alpha) != VN.end()) return N;//⾮终结符46else return NON;//⾮法字符47 }主函数的流程很简单,从⽂件读⼊指定格式的⽂法,然后依次求⽂法的FIRST集、FOLLOW集1int main()2 {3 FREAD("grammar2.txt");//从⽂件读取⽂法4int numN = 0;5int numT = 0;6char c = '';7 S = getchar();//开始符号8 printf("%c", S);9 VN.insert(S);10 numN++;11while((c=getchar()) != '\n'){//读⼊⾮终结符12 printf("%c", c);13 VN.insert(c);14 numN++;15 }16 pn();17while((c=getchar()) != '\n'){//读⼊终结符18 printf("%c", c);19 VT.insert(c);20 numT++;21 }22 pn();23 REP(numN){//读⼊产⽣式24 c = getchar();25int n; RINT(n);26while(n--){27char body[MAX_N];28 scanf("%s", body);29 printf("%c --> %s\n", c, body);30 P.insert(Production(c, body));31 }32 getchar();33 }3435 get_first();//⽣成FIRST集36for(vn = VN.begin(); vn != VN.end(); vn++){//打印⾮终结符的FIRST集37 printf("FIRST(%c) = { ", *vn);38for(first = FIRST[*vn].begin(); first != FIRST[*vn].end(); first++){39 printf("%c, ", *first);40 }41 printf("}\n");42 }4344 get_follow();//⽣成⾮终结符的FOLLOW集45for(vn = VN.begin(); vn != VN.end(); vn++){//打印⾮终结符的FOLLOW集46 printf("FOLLOW(%c) = { ", *vn);47for(follow = FOLLOW[*vn].begin(); follow != FOLLOW[*vn].end(); follow++){48 printf("%c, ", *follow);49 }50 printf("}\n");51 }52return0;53 }主函数其中⽂法⽂件的数据格式为(按照平时做题的输⼊格式设计的):第⼀⾏:所有⾮终结符,⽆空格,第⼀个为开始符号;第⼆⾏:所有终结符,⽆空格;剩余⾏:每⾏描述了⼀个⾮终结符的所有产⽣式,第⼀个字符为产⽣式头(⾮终结符),后跟⼀个整数位候选式的个数n,之后是n个以空格分隔的字符串为产⽣式体。

ll1文法的三个条件

ll1文法的三个条件

ll1文法的三个条件
LL(1)文法是一种常用的上下文无关文法,它具有一些特殊的性质,可以方便地进行语法分析。

LL(1)文法需要满足以下三个条件: 1.左递归和间接左递归消除:LL(1)文法不允许存在左递归或者间接左递归的情况,因为这样会导致分析器无法正确地判断应该使用哪一个产生式来推导符号串。

2.First集不相交:对于每一个非终结符号A,任意两个以A为左部的产生式的First集必须没有交集。

如果存在交集,则在进行预测分析时无法确定使用哪一个产生式进行推导,从而导致分析失败。

3.Follow集合并:对于每一个非终结符号A,将所有以A为左部的产生式的Follow集合并起来,得到的结果就是A的Follow集。

在进行预测分析时,需要用到Follow集来确定何时结束某个非终结符的展开,以及应该采用哪个产生式进行推导。

以上三个条件都是LL(1)文法必须满足的基本要求,只有同时满足才能保证分析的准确性和可行性。

编译原理课程设计-LL1文法分析器设计C++语言实现

编译原理课程设计-LL1文法分析器设计C++语言实现

集美大学计算机工程学院编译原理课程设计报告选题名称:LL(1)文法分析院(系):计算机工程学院专业:计算机科学与技术班级:计算1412指导教师:付永刚学年学期:2016 ~ 2017 学年第 2 学期2017 年06 月29 日摘要:选题要求:根据某一文法编制调试LL(1) 文法语法分分析程序,以便对任意输入的符号串进行分析。

本次课程设计的目的主要是加深对预测分析LL(1)文法语法分析法的理解。

具体如下:1、对语法规则有明确的定义;2、编写的分析程序能够对给定文法进行正确的语法分析;3、对输入给定的文法,手工计算FIRST、FOLLOW集合和select集合,应能判断识别是否为给定文法的句子,并给出推导过程。

4、对输入给定的文法,由程序自动构造FIRST、FOLLOW集合。

5、对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程。

关键词:语法分析;FIRST集合;FOLLOW集合;分析表一、设计内容及要求(1) 基于PL/0语言,通过编程判断该文法是否为LL(1)文法;(2)计算出文法的First() Follow()(3)构造相应文法的预测分析表(4)对某个输入句子进行语法分析二、实现原理1.LL(1)文法LL(1)文法是一类可以进行确定的自顶向下语法分析的文法。

就是要求描述语言的文法是无左递归的和无回溯的。

根据LL(1)文法的定义,对于同一非终结符A的任意两个产生式A:=a和A:=b,都要满足:SELECT(A:=a )∩SELECT(A:=b)=Ø。

(1)文法的左递归当一个文法是左递归文法时,采用自顶向下分析法会使分析过程进入无穷循环之中。

所以采用自顶向下语法分析需要消除文法的左递归性。

文法的左递归是指若文法中对任一非终结符A有推导AÞA…,则称该文法是左递归的。

左递归又可以分为直接左递归和间接左递归。

●直接左递归若文法中的某一产生式形如A→Aα,α∈V*,则称该文法是直接左递归的。

编译原理 FIRST集和FOLLOW集的求法

编译原理  FIRST集和FOLLOW集的求法

First集合的求法:First集合最终是对产生式右部的字符串而言的,但其关键是求出非终结符的First集合,由于终结符的First集合就是它自己,所以求出非终结符的First集合后,就可很直观地得到每个字符串的First集合。

1. 直接收取:对形如U-a…的产生式(其中a是终结符),把a收入到First(U)中2. 反复传送:对形入U-P…的产生式(其中P是非终结符),应把First(P)中的全部内容传送到First(U)中。

Follow集合的求法:Follow集合是针对非终结符而言的,Follow(U)所表达的是句型中非终结符U所有可能的后随终结符号的集合,特别地,“#”是识别符号的后随符。

1. 直接收取:注意产生式右部的每一个形如“…Ua…”的组合,把a直接收入到Follow(U)中。

2.直接收取:对形如“…UP…”(P是非终结符)的组合,把First(P)除ε直接收入到Follow(U)中。

3.反复传送:对形如P-…U的产生式(其中U是非终结符),应把Follow(P)中的全部内容传送到Follow(U)中。

(或 P-…UB且First(B)包含ε,则把First(B)除ε直接收入到Follow(U)中,并把Follow(P)中的全部内容传送到Follow(U)中)例1:判断该文法是不是LL(1)文法,说明理由 S→ABc A→a|ε B→b|ε?First集合求法就是:能由非终结符号推出的所有的开头符号或可能的ε,但要求这个开头符号是终结符号。

如此题A可以推导出a和ε,所以FIRST(A)={a,ε};同理FIRST (B)={b,ε};S可以推导出aBc,还可以推导出bc,还可以推导出c,所以FIRST(S)={a,b,c}。

Follow集合的求法是:紧跟随其后面的终结符号或#。

但文法的识别符号包含#,在求的时候还要考虑到ε。

具体做法是把所有包含你要求的符号的产生式都找出来,再看哪个有用。

编译原理第5章 LL(1)文法及其分析程序

编译原理第5章  LL(1)文法及其分析程序

}
else error( )
}
}
27
5.2 预测分析程序(Predictive
parser)无回溯的自顶向下分析程序
特征——根据下一个(几个)输入符号为当前要处理 的非终结符选择产生式
要求——文法是LL(1)的 第一个L 从左到右扫描输入串 第二个L 生成的是最左推导 1 向前看一个输入符号(lookahead)
第5章 LL(1)文法及其分析程序
5.1 自上而下的语法分析 5.2 预测分析程序
递归下降子程序 表驱动的预测分析程序 5.3 LL(1)分析程序的生成
LL(1)文法 FIRST和FOLLOW集 定义和计算 5.4 非LL(1)文法的改造
1
5.1自上而下的语法分析
1语法分析概念 2自上而下的语法分析的一般过程 3自上而下的语法分析面临的问题
到分析结束。
5
分析算法分类
分析算法可分为:
自上而下分析法:
从文法的开始符号出发,寻找与输入符号 串匹配的推导,或者说,为输入串寻找一 个最左推导。
自下而上分析法:
从输入符号串开始,逐步进行归约,直至 归约到文法的开始符号。
6
两种方法反映了语法树的两种构 造过程。
自上而下方法是从文法符号开始,将它做为语法
SaASaSbASaabASaabbaSaabbaa
SaASaSbASaSbAaaabAaaabbaa
4
语法分析
在语言的编译实现中,把句子分析的过程称
为语法分析,即完成这个任务的程序称为 语法分析程序或称为识别程序。分析算法 又称识别算法。 从左到右的分析算法,即总是从左到右地识 别输入符号串,首先识别符号串中的最左 符号,进而依次识别右边的一个符号,直

编译原理实验LL1分析

编译原理实验LL1分析
编译原理实验ll1分析基本的功能下面主要采用了ll1分析方法来进行语法分析先通过判断该文法是不是ll1文法如果不是先将其改写成ll1文法再将ll1文法改造成等价形式ll1分析表通过分析表来进行语法分析本程序的主要功能是对一个文法句子的生成过程进行分析
实验三语法分析---LL(1)分析器


1.用程序的方法实现语法分析的LL(1)方法。
}
void put_setence()
{
char ch;
int i=0;
while((ch=cin.get()) != '#') {
analyz_sentence[i] = ch;
i++;
}
analyz_sentence[i] = '#';
}
void init_stack()
{
stack[0] = '#';
return i;
}
return -1;
}
void reve()
{
strcpy(s, tp);
int i,j;
char t;
i=0;
while (s[i] != '\0')
++i;
--i;
if (s[i] == '\n')
--i;
j=0;
while (j<i)
{
t = s[j];
s[j] = s[i];
cout << "=>";
if (top == 'u')
pop();
}
void pop()
{

编译原理第三章练习题答案

编译原理第三章练习题答案

编译原理第三章练习题答案编译原理第三章练习题答案编译原理是计算机科学中的重要学科,它研究的是如何将高级语言代码转化为机器语言的过程。

在编译原理的学习过程中,练习题是不可或缺的一部分,通过完成练习题可以更好地理解和掌握编译原理的知识。

本文将为大家提供编译原理第三章练习题的答案,希望对大家的学习有所帮助。

1. 什么是语法分析?语法分析是编译器中的一个重要模块,它的主要任务是根据给定的语法规则,对输入的源代码进行分析和解释。

语法分析器会根据语法规则构建一个语法树,用于表示源代码的结构和含义。

常用的语法分析方法有递归下降法、LL(1)分析法和LR分析法等。

2. 什么是LL(1)文法?LL(1)文法是一种特殊的上下文无关文法,它具有以下两个特点:(1) 对于任何一个句子,最左推导和最右推导是唯一的。

(2) 在预测分析过程中,只需要向前看一个输入符号就可以确定所采用的产生式。

LL(1)文法是一种常用的文法形式,它适用于递归下降法和LL(1)分析法。

3. 什么是FIRST集合和FOLLOW集合?FIRST集合是指对于一个文法符号,它能够推导出的终结符号的集合。

FOLLOW 集合是指在一个句型中,某个非终结符号的后继终结符号的集合。

计算FIRST集合和FOLLOW集合可以帮助我们进行语法分析,特别是LL(1)分析。

4. 什么是递归下降语法分析法?递归下降语法分析法是一种基于产生式的自顶向下的语法分析方法。

它的基本思想是从文法的开始符号开始,递归地根据产生式进行分析,直到推导出输入符号串或发现错误。

递归下降语法分析法的实现比较简单,但对于某些文法可能会出现回溯现象,影响分析效率。

5. 什么是LR分析法?LR分析法是一种自底向上的语法分析方法,它的基本思想是从输入符号串开始,逐步构建语法树,直到推导出文法的开始符号。

LR分析法具有较好的分析效率和广泛的适用性,常用的LR分析方法有LR(0)、SLR(1)、LR(1)和LALR(1)等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程名称: LL1文法的判别年级/专业/班: 11级计算机类(二)班姓名: 徐勇兵学号: E01114278import java.util.Vector;import javax.swing.JOptionPane;class Tools{public Vector<String> protection(Vector<String> vs){Vector<String> newvector=new Vector<String>();for(int i=0;i<vs.size();i++)newvector.add(vs.get(i));return newvector;}public Vector<Vector<String>> doubleprotection(Vector<Vector<String>> vs){ Vector<Vector<String>> newvector=new Vector<Vector<String>>();for(int i=0;i<vs.size();i++){Vector<String> produce=(Vector<String>)vs.get(i);Vector<String> temp=new V ector<String>();for(int j=0;j<produce.size();j++){temp.add((String)produce.get(j));}//for jnewvector.add(temp);}//for ireturn newvector;}}class Elements{Vector<String> end=new V ector<String>();//表示终结符Vector<String> noend=new Vector<String>();//表示非终结符Vector<Vector<String>> produce=new Vector<Vector<String>>();//产生式public void setend(){//终结符元素添加while(true){String s=JOptionPane.showInputDialog(null,"请输入终结符");if(s==null){ return;}//ifend.add(s);}//while}//public void addend(){//元素添加public void setnoend(){//非终结符元素添加while(true){String s=JOptionPane.showInputDialog(null,"非请输入终结符");if(s==null){ return;}//ifnoend.add(s);}//while}//public void addnoend(){//public void setproduce(){while(true){String s=JOptionPane.showInputDialog(null,"请输入产生式,->隔开");if(s==null)return;Vector<String> temp=new Vector<String>();temp.add(s.split("->")[0]);temp.add(s.split("->")[1]);produce.add(temp);}//while}//public void addproduce()public Vector<String> getend(){return end;}public Vector<String> getnoend(){return noend;}public Vector<Vector<String>> getproduce(){return this.produce;}public void run(){/*************************TEST********************************/ end.add("a");end.add("b");end.add("c");end.add("e");noend.add("S");noend.add("A");noend.add("B");noend.add("C");noend.add("D");Vector<String> temp=new Vector<String>();temp.add("S");temp.add("AB");produce.add(temp);/*************************/Vector<String> temp1=new Vector<String>();temp1.add("S");temp1.add("bC");produce.add(temp1);/*************************/Vector<String> temp2=new Vector<String>();temp2.add("A");temp2.add("e");produce.add(temp2);/*************************/Vector<String> temp3=new Vector<String>();temp3.add("A");temp3.add("b");produce.add(temp3);/*************************/Vector<String> temp4=new Vector<String>();temp4.add("B");temp4.add("e");produce.add(temp4);/*************************/Vector<String> temp5=new Vector<String>();temp5.add("B");temp5.add("aD");produce.add(temp5);/*************************/Vector<String> temp6=new Vector<String>();temp6.add("C");temp6.add("AD");produce.add(temp6);/*************************/Vector<String> temp7=new Vector<String>();temp7.add("C");temp7.add("b");produce.add(temp7);/*************************/Vector<String> temp8=new Vector<String>();temp8.add("D");temp8.add("aS");produce.add(temp8);/*************************/Vector<String> temp9=new Vector<String>();temp9.add("D");temp9.add("c");produce.add(temp9);/*************************/// System.out.println("produce.size()="+produce.size());/***********************TEST**********************************///this.setend();//this.setnoend();//this.setproduce();}public boolean Iscontainend(String s)//正则表达式判断s1是否在END的闭包里面正则忘了怎么写了{int length=s.length();for(int i=0;i<length;i++){String a=""+s.charAt(i);if(end.contains(a))return true;else continue;}//forreturn false;}//public boolean isRGPcontain(String s)public boolean IsNoENd(String s){String ss=""+s.charAt(0);if(! Iscontainend(ss))//如果不含有终结符,则为非终结符return true;return false;}// public boolean}//class Elementsclass Follow{Vector<String> end=new V ector<String>();//表示终结符Vector<String> noend=new Vector<String>();//表示非终结符Vector<Vector<String>> produce=new Vector<Vector<String>>();//产生式Vector<Vector<String>> emptytable=new Vector<V ector<String>>();Elements elements;First first;Vector<Vector<String>> flagtable=new Vector<Vector<String>>();Vector<Vector<String>> followtable=new Vector<Vector<String>>();public void showfollowtable(){for(int i=0;i<followtable.size();i++){System.out.println();Vector<String> temp=followtable.get(i);System.out.print(temp.get(0)+"的Follow集:");for(int j=1;j<temp.size();j++){System.out.print(temp.get(j)+",");}}}//public void showfollowtable(){public Vector<String> getAppointfollow(String s){Vector<String> temp=new V ector<String>();for(int i=0;i<followtable.size();i++){temp=followtable.get(i);if(temp.get(0).equals(s))return temp;}//forreturn temp;}// public Vector<String> getAppointfollow(String s)public void init_flagtableAndfollowtable(){for(int i=0;i<noend.size();i++){Vector<String> temp=new V ector<String>();temp.add(noend.get(i));temp.add("no");flagtable.add(temp);}//forfor(int i=0;i<noend.size();i++){Vector<String> temp=new V ector<String>();temp.add(noend.get(i));followtable.add(temp);}//for}//public void init_flagtableAndfollowtablepublic void show_flagtableAndfollowtable(){System.out.println();System.out.println("flagtable is shown as follows:");for(int i=0;i<flagtable.size();i++){Vector<String> temp=flagtable.get(i);System.out.print(temp.get(0)+":"+temp.get(1));System.out.println();}//forSystem.out.println("followtable is shown as follows:");for(int i=0;i<followtable.size();i++){System.out.println();Vector<String> temp=followtable.get(i);System.out.print(temp.get(0)+":");for(int j=1;j<temp.size();j++){System.out.print(temp.get(j));}}//for}public String getFlagTable(String s){for(int i=0;i<flagtable.size();i++){Vector<String> temp=flagtable.get(i);if(temp.get(0).equals(s)){return temp.get(1);}}//forreturn "no";}// public String getFlagTable(String s)public void setFlagTable(String s){for(int i=0;i<flagtable.size();i++){Vector<String> temp=flagtable.get(i);if(temp.get(0).equals(s)){temp.set(1,"yes");}}//for}// public String setFlagTable(String s)public boolean Isindicateempty(String s){for(int i=0;i<emptytable.size();i++){Vector<String> temp=emptytable.get(i);if(temp.get(0).equals(s)){if(temp.get(1).equals("yes"))return true;elsereturn false;}//if 外层}//forreturn false;}// public boolean Isindicatefull(String s)public Vector<Vector<String>> getFirsrtandFollow(String s){//获得非终结符s的要加入的Follw(A)和First(a)的a和A//System.out.println("欲求"+s+"的相关信息");Vector<Vector<String>>vs=new Vector<Vector<String>>();Vector<String> first=new Vector<String>();Vector<String> follow=new Vector<String>();for(int i=0;i<produce.size();i++){Vector<String> temp=produce.get(i);String left=temp.get(0);String right=temp.get(1);//获取产生式的右部int index=right.indexOf(s);if(index!=(-1)){//如果右部含有次非终结符的话if(right.length()==(index+1)){//D->aS型(S为所求)follow.add(left);}else{String nextchar=""+right.charAt(index+1);first.add(nextchar);if(Isindicateempty(nextchar)){//如果此非终结符可以产生空的话follow.add(left);}}}//if(index!=(-1))}//for/*if(first.isEmpty()==false){//如果不空System.out.println(s+"firsr为:");for(int i=0;i<first.size();i++){System.out.println();String sb=(String)first.get(i);System.out.print(sb);}//for}else{//System.out.println(s+"的first为空");}if(follow.isEmpty()==false){//如果不空System.out.println();System.out.print(s+"的follow为:");for(int i=0;i<follow.size();i++){String sb=(String)follow.get(i);System.out.print(sb);}//for}else{//System.out.println(s+"的follow为空");}*/vs.add(first);vs.add(follow);return vs;}public Vector<String> addElements(Vector<String> vs,Vector<String>temp){ for(int i=0;i<temp.size();i++){if(!vs.contains(temp.get(i)))vs.add(temp.get(i));}//forreturn vs;}//public Vector<String> addElements(Vector<String> vs,Vector<String>temp){ public Vector<String> getFollow(String s){Vector<String> follow=getAppointfollow(s);//System.out.println(s+"的flagtable对应的是"+getFlagTable(s));if(getFlagTable(s).equals("yes")){/*System.out.println("返回follow集,防止死循环");System.out.println("返回follow集签先输出查看");for(int i=0;i<follow.size();i++){System.out.print(follow.get(i)+",");}System.out.println();*/Vector<String> kk=new V ector<String>();for(int i=1;i<follow.size();i++){kk.add(follow.get(i));}return kk;}setFlagTable(s);//将flagtable的对应表项置为yesString Start_Characrter="S";if(s.equals(Start_Characrter)){//System.out.println("follow加入了#");follow.add("#");}Vector<Vector<String>> vs=getFirsrtandFollow(s);//show_flagtableAndfollowtable();Vector<String> firstcharacter=vs.get(0);Vector<String> followcharacter=vs.get(1);System.out.println();//System.out.println("111111111111111111");if(firstcharacter.isEmpty()==false){//如果不空for(int i=0;i<firstcharacter.size();i++){String sb=(String)firstcharacter.get(i);Vector<String> vv= first.getFirst(sb);follow=addElements(follow,vv);}//for}if(followcharacter.isEmpty()==false){//如果不空for(int i=0;i<followcharacter.size();i++){String sb=(String)followcharacter.get(i);Vector<String> vv= getFollow(sb);follow=addElements(follow,vv);}//for}follow.remove("e");Vector<String> kk=new V ector<String>();for(int i=1;i<follow.size();i++){kk.add(follow.get(i));}//return follow;return kk;}public Follow(Elements _elements,Vector<Vector<String>> _emptytable,First _first){ this.elements=_elements;this.emptytable=_emptytable;this.first=_first;this.end=elements.getend();this.noend=elements.getnoend();this.produce=elements.getproduce();init_flagtableAndfollowtable();}}//class followclass First{Vector<String> end=new V ector<String>();//表示终结符Vector<String> noend=new Vector<String>();//表示非终结符Vector<Vector<String>> produce=new Vector<Vector<String>>();//产生式Vector<Vector<String>> emptytable=new Vector<V ector<String>>();Elements elements;public First(Elements _elements,Vector<Vector<String>> _emptytable){ this.elements=_elements;this.emptytable=_emptytable;this.end=elements.getend();this.noend=elements.getnoend();this.produce=elements.getproduce();}public Vector<String> getRight(String left){Vector<String> right=new Vector<String>();for(int i=0;i<produce.size();i++){Vector<String>temp=produce.get(i);if(temp.get(0).equals(left)){right.add(temp.get(1));}}//forreturn right;}//public String[] getRight(String left)public Vector<String> addElements(Vector<String> vs,Vector<String>temp){ for(int i=0;i<temp.size();i++){if(!vs.contains(temp.get(i)))vs.add(temp.get(i));}//forreturn vs;}//public Vector<String> addElements(Vector<String> vs,Vector<String>temp){ public boolean Isindicateempty(String s){for(int i=0;i<emptytable.size();i++){Vector<String> temp=emptytable.get(i);if(temp.get(0).equals(s)){if(temp.get(1).equals("yes"))return true;elsereturn false;}//if 外层}//forreturn false;}// public boolean Isindicatefull(String s)public boolean IsNoENd(String s){String ss=""+s.charAt(0);if(! elements.Iscontainend(ss))//如果不含有终结符,则为非终结符return true;return false;}// public booleanpublic boolean IsStartWithEnd(String s){//判断是否以终结符开头String ss=""+s.charAt(0);if( elements.Iscontainend(ss))return true;return false;}public Vector<String> getFirst(String s){Vector<String> vs=new Vector<String>();int ii=0;if(IsStartWithEnd(s)){vs.add(""+s.charAt(0));}if(s.length()==1&&IsNoENd(s)){//形如Fisst(A)Vector<String> temp=getRight(s);for(int i=0;i<temp.size();i++){vs=addElements(vs,getFirst(temp.get(i)));}//for}//ifif(s.length()!=1){//形如First(AB)或者First(AaB)for(ii=0;ii<s.length();ii++){String ss=""+s.charAt(ii);if(Isindicateempty(ss)){//如果能退出空Vector<String> temp=getFirst(ss);if(temp.contains("e")){//如果有空则删除temp.remove("e");}vs=addElements(vs,temp);}//ifelse{vs=addElements(vs,getFirst(ss));break;}} //forif(ii==s.length()){//如果所有的非终结符都能退出空,则将e加入vs.add("e");}}//if if(s.length()!=1){//形如First(AB)或者First(AaB)return vs;}}//class Firstclass Select{Elements elements;First first;Follow follow;Emptytable emptytable;Vector<String> end;Vector<String> noend;Vector<Vector<String>> produce;Vector<Vector<String>> flagtable=new Vector<Vector<String>>();Vector<Vector<String>> followtable=new Vector<Vector<String>>();public Select(Elements _elements,Emptytable _emptytable,First _first,Follow _follow){ this.elements=_elements;this.emptytable=_emptytable;this.end=elements.getend();this.noend=elements.getnoend();this.produce=elements.getproduce();this.first=_first;this.follow=_follow;init_flagtable();}public void showselecttable(){for(int i=0;i<produce.size();i++){Vector<String> temp=produce.get(i);System.out.println();System.out.print("产生式"+temp.get(0)+"->"+temp.get(1)+"的select集是:");Vector<String> select=getselect(temp);for(int j=0;j<select.size();j++){System.out.print(select.get(j)+",");}}}public Vector<String> addElements(Vector<String> vs,Vector<String>temp){for(int i=0;i<temp.size();i++){if(!vs.contains(temp.get(i)))vs.add(temp.get(i));}//forreturn vs;}//public Vector<String> addElements(Vector<String> vs,Vector<String>temp){public Vector<Vector<String>> getallproduces(String left){//返回以left为左部的所有产生式Vector<Vector<String>> vs=new Vector<Vector<String>>();for(int i=0;i<produce.size();i++){Vector<String> temp=produce.get(i);if(temp.get(0).equals(left))vs.add(temp);}return vs;}public void init_flagtable(){for(int i=0;i<noend.size();i++){Vector<String> temp=new V ector<String>();temp.add(noend.get(i));temp.add("no");flagtable.add(temp);}//for}//public void init_flagtablepublic String getFlagTable(String s){for(int i=0;i<flagtable.size();i++){Vector<String> temp=flagtable.get(i);if(temp.get(0).equals(s)){return temp.get(1);}}//forreturn "no";}// public String getFlagTable(String s)public void setFlagTable(String s){for(int i=0;i<flagtable.size();i++){Vector<String> temp=flagtable.get(i);if(temp.get(0).equals(s)){temp.set(1,"yes");}}//for}// public String setFlagTable(String s)public boolean IsIndicateEmpty(String right){//判断产生式右部是否可以推出空for(int i=0;i<right.length();i++){String vv=""+right.charAt(i);if(vv.equals("e"))//如A->econtinue;if(elements.Iscontainend(vv)){//如果含有除e以外的终结符//System.out.println();return false;}if(elements.IsNoENd(vv)){//如果是个非终结符if(emptytable.whattag(vv).equals("yes"))continue;if(emptytable.whattag(vv).equals("no"))return false;}}return true;}// IsIndicateEmpty(String right){public Vector<String> getselect(Vector<String> temp){//返回某条产生式的select集合Vector<String> combination=new Vector<String>();String left=temp.get(0);String right=temp.get(1);if( IsIndicateEmpty(right)){//如果右部可以推出空的话Vector<String> firstcollection=first.getFirst(right);Vector<String> followcollection=follow.getFollow(left);combination=addElements(firstcollection,followcollection);combination.remove("e");return combination;}//ifelse{Vector<String> firstcollection=first.getFirst(right);return firstcollection;}//return combination;}// public Vector<String> getselect(Vector<String> temp)public Vector<Vector<String>> getcollectionOfselect(Vector<Vector<String>> allproduce){//返回有相同左部的产生式的select集的集合Vector<Vector<String>> selectcollection=new Vector<Vector<String>>();for(int i=0;i<allproduce.size();i++){Vector<String> temp=allproduce.get(i);selectcollection.add( getselect(temp));}return selectcollection;}// public Vector<Vector<String>> getcollectionOfselect(Vector<Vector<String>> allproduce)public boolean IsIntersection( Vector<V ector<String>> selectcollection){for(int i=0;i<selectcollection.size();i++){Vector<String> temp=selectcollection.get(i);for(int j=0;j<temp.size();j++){String s=temp.get(i);for(int m=i+1;m<selectcollection.size();m++){Vector<String> vv=selectcollection.get(m);if(vv.contains(s));System.out.println();System.out.println("产生交集"+s+"不是LL1,程序即将结束");return true;}//for m}// for j}// for ireturn false;}// public boolean IsIntersectionpublic boolean Judge(){for(int i=0;i<produce.size();i++){Vector<String> temp=produce.get(i);String left=temp.get(0);String right=temp.get(1);if(getFlagTable(left).equals("yes"))continue;setFlagTable(left);Vector<Vector<String>> allproduce=getallproduces(left);Vector<Vector<String>> selectcollection= getcollectionOfselect( allproduce);if(IsIntersection( selectcollection)==true){System.out.println("以"+left+"为左部的产生式有交集,所以不是LL1");return false;}}//forreturn true;}}//class Selectclass Emptytable{Tools tools=new Tools();Elements elements;Vector<String> end;Vector<String> noend;Vector<Vector<String>> produce;Vector<String> newend;Vector<String> newnoend;Vector<Vector<String>> newproduce;Vector<Vector<String>> emptytable=new Vector<V ector<String>>();public Vector<Vector<String>> getemptytable(){return emptytable;}public void shownewinforamtion(){System.out.print("emptytable产生式输出如下:");for(int i=0;i<produce.size();i++){System.out.println(" ");Vector<String> temp=(Vector<String>)produce.get(i);System.out.print((String)temp.get(0)+"->"+(String)temp.get(1));}System.out.println();System.out.println("****************");if(newproduce.isEmpty()){System.out.println("newproduce has been cleared");return;}System.out.print("新的产生式输出如下:");for(int i=0;i<newproduce.size();i++){System.out.println(" ");Vector<String> temp=(Vector<String>)newproduce.get(i);System.out.print((String)temp.get(0)+"->"+(String)temp.get(1));}System.out.println(" ");}public String whattag(String noendcharacter ){//判断某个非终结符在表中的状态,只有yes,no unsure三种for(int i=0;i<emptytable.size();i++){Vector<String> temp=( Vector<String>)emptytable.get(i);if(temp.get(0).equals(noendcharacter)){return (String)temp.get(1);}//if}//forreturn "error";}public void initial_table(){for(int i=0;i<noend.size();i++){Vector<String> temp=new V ector<String>();temp.add((String)noend.get(i));temp.add("unsure");emptytable.add(temp);}//for}//public void initial_table(){public void updatetable(String left,String tag){for(int i=0;i<emptytable.size();i++){Vector<String> temp=(Vector<String>)emptytable.get(i);if(temp.get(0).equals(left)){temp.set(1,tag);//System.out.println("表格已被更新为:"+temp.get(0)+" "+temp.get(1));}}//for}//public void updatetable(String left,String tag)public void delete(String left,String right){//删除某条特定的产生式//System.out.println("欲删除产生式:"+left+"->"+right);Vector<String> temp=new V ector<String>();temp.add(left);temp.add(right);if(newproduce.remove(temp)){//System.out.println(left+"->"+right+" produce has deleted successfuly");}else{System.out.println("fail to remove this produce:"+left+"->"+right);}}//public void delete(String left,String right)public void deleteall(String left){//删除以某个字符为左部的所有产生式boolean flag=true;BlockB:while(flag){flag=false;for(int i=0;i<newproduce.size();i++){Vector<String> temp=newproduce.get(i);if(temp.get(0).equals(left)){if(newproduce.remove(temp)){//System.out.println("以"+left+"为左部的产生式被删除");}else{//System.out.println("fail to remove this produce:"+"以"+left+"为左部的产生式");}flag=true;continue BlockB;}//if}//for}//while()}//public void deleteall(String left)public boolean Isleftempty(String left){//判断以某个左部为产生式是否为空for(int i=0;i<newproduce.size();i++){Vector<String> temp=(Vector<String>)newproduce.get(i);if(temp.get(0).equals(left)){return false;}}//forreturn true;}//public boolean Isleftempty(String left)public void firststep(){//第一步(删除某条产生式之后向量的长度会变短,再用get(i)会取不到数据,所以要用到BLOCK)Boolean flag=true;BlockA:while(flag==true){flag=false;for(int i=0;i<newproduce.size();i++){Vector<String> temp=newproduce.get(i);String left=temp.get(0);String right=temp.get(1);if(elements.Iscontainend(right)){//如果产生式的右部含有终结符则删除//System.out.println("产生式的右部为:"+right);delete(left,right);if(Isleftempty(left)){//如果以此为左部的产生式都被删除了,则将表格对应的修改为noupdatetable(left,"no");}//内层ifflag=true;continue BlockA;}//if 外层} //for}//while()}//public void firststep()public void secondstep(){//第二步Boolean flag=true;BlockC:while(flag==true){flag=false;for(int i=0;i<newproduce.size();i++){Vector<String> temp=newproduce.get(i);String left=temp.get(0);String right=temp.get(1);String kong=""+"e";if(right.equals(kong)){//如果右部是空updatetable(left,"yes");deleteall(left);flag=true;continue BlockC;}}//for}//while()}//public void secondstep()public void thirdstep(){boolean flag=true;BlockD:while(flag==true){flag=false;for(int i=0;i<newproduce.size();i++){Vector<String> temp=(Vector<String>)newproduce.get(i);String left=temp.get(0);String _right=temp.get(1);StringBuffer right=new StringBuffer(_right);for(int j=0;j<right.length();j++){String s=""+right.charAt(j);//System.out.println("终结符S为"+s);StringBuffer tag=new StringBuffer(whattag(s));String _tag=tag.toString();//System.out.println(s+"的tag="+tag);if(_tag.equals("yes")){//如果该非终结符是yes的话,删除该非终结符int index=right.indexOf(s);if(index!=-1){//System.out.println("index="+index);right.deleteCharAt(index);if(right.length()==0){//如果该产生式的右部为空的话//System.out.println("第三步。

相关文档
最新文档