正规文法转换成正规式
课程名称: 正规文法转换成正规式
年级/专业/班: 11级计算机类(二)班
姓名: 徐勇兵
学号: E01114278
实验名称:正规文法转换成正规式
实验目的:
1.了解并熟悉词法分析中单词的描述工具正规文法和正规式表示单词
的方式及其之间的差异性和等价性。
2.利用计算机编程实现正规文法转换成等价的正规式。
实验要求:
1.正规文法的输入应简便。
2.输出的正规式以利用3条转换规则得出为标准。
输入:一组产生式所构成的正规文法。
输出:对应的等价的正规式。
实验原理:
1.多数程序设计语言的单词的语法都能用正规文法或3型文法来描述。
2.3型文法的特征是P中的每一条规则都有下述形式:A->aB或A->a。
正规文法所描述的是VT上的正规集。
3.正规式也称正则表达式,也是表示正规集的工具。也是我们用以描
述单词符号的有效工具。
4.正规文法和正规式的等价性:一个正规语言可以由正规文法定义,
也可以由正规式定义,对任意一个正规文法,存在一个定义同一个
语言的正规式;反之,对每个正规式,存在一个生成同一语言的正
规文法,有些语言很容易用文法描述,有些语言更容易用正规式定
义。
5.将正规文法转换成正规式的转换规则有三:
(1)A->xB,B->y对应A=xy
(2)A->xA,A->y对应A=x*y
(3)A->x,A->y对应A=x|y
实验算法:
实验算法定义一个函数实现转换正规文法为正规式。函数根据三个转换规则,首先合并形如B->aA,B->bA的产生式为B->aA|bA的形
式,其中又包括B=A的形式。然后根据转换规则合并形如S->a,S->b
的产生式为S->a|b的形式。再根据转换规则2 的A->xA,A->y对应
A=x*y和规则3的A->x,A->y对应A=x|y将文法产生式变换为等价
的正规式。
在规则以外还需要另外一个处理,这个处理可以从书本上的例子中看到,即将公因子提取出来,如A=aA|dA变换为A=(a|d)A。
算法默认开始符号为S且放在第一个产生式,这样就能根据第一条产生式最终得到等价的一个开始符号定义的正规式。
实验结果:
import java.util.Vector;
import javax.swing.JOptionPane;
class Tools{
public Vector //if(!vs.contains(temp.get(i))) vs.add(temp.get(i)); }//for return vs; }//public Vector Vector for(int i=0;i newvector.add(vs.get(i)); return newvector; } public Vector for(int i=0;i Vector Vector for(int j=0;j temp.add((String)produce.get(j)); }//for j newvector.add(temp); }//for i return newvector; } }//class tools class Elements{ Vector Vector Vector public void setend(){//终结符元素添加 while(true) { String s=JOptionPane.showInputDialog(null,"请输入终结符"); if(s==null) { return; }//if end.add(s); }//while }//public void addend(){//元素添加 public void setnoend(){//非终结符元素添加 while(true) { String s=JOptionPane.showInputDialog(null,"非请输入终结符"); if(s==null) { return; }//if noend.add(s); }//while }//public void addnoend(){// public void setproduce(){ while(true) { String s=JOptionPane.showInputDialog(null,"请输入产生式,->隔开"); if(s==null) return; Vector temp.add(s.split("->")[0]); temp.add(s.split("->")[1]); produce.add(temp); }//while }//public void addproduce() public Vector return end; } public Vector return noend; } public Vector return this.produce; } public void run(){ /*************************TEST********************************/ end.add("a"); end.add("d"); noend.add("S"); noend.add("A"); Vector temp.add("S"); temp.add("aA"); produce.add(temp); /*************************/ /*************************/ Vector temp4.add("S"); temp4.add("a"); produce.add(temp4); // System.out.println("produce.size()="+produce.size()); /***********************TEST**********************************/ /*************************/ Vector temp7.add("A"); temp7.add("aA"); produce.add(temp7); // System.out.println("produce.size()="+produce.size()); /***********************TEST**********************************/ Vector temp1.add("A"); temp1.add("dA"); produce.add(temp1); /*************************/ Vector temp2.add("A"); temp2.add("a"); produce.add(temp2); /*************************/ Vector temp3.add("A"); temp3.add("d"); produce.add(temp3); // System.out.println("produce.size()="+produce.size()); /***********************TEST**********************************/ /* noend.add("B"); Vector temp6.add("A"); temp6.add("aB"); produce.add(temp6); Vector temp5.add("B"); temp5.add("d"); produce.add(temp5);*/ //this.setend(); //this.setnoend(); //this.setproduce(); } public boolean Iscontainend(String s)//判断某个符号是否是终结符可以是一个字符也可是字符串 { /*System.out.print("输出终结符"); for(int i=0;i System.out.print(end.get(i)); System.out.println(); System.out.println("传送过来的需要判断的是"+s);*/ int length=s.length(); for(int i=0;i { String a=""+s.charAt(i); if(end.contains(a)) { continue;} else return false; }//for return true; }//public boolean isRGPcontain(String s) public boolean IsNoENd(String s){//判断某个符号是否是非终结符 String ss=""+s.charAt(0); if(! Iscontainend(ss))//如果不含有终结符,则为非终结符 return true; return false; }// public boolean public void show(){ System.out.print("终结符输出如下:"); for(int i=0;i System.out.print((String)end.get(i)+", "); } System.out.println(" "); System.out.print("非终结符输出如下:"); for(int i=0;i System.out.print((String)noend.get(i)+", "); } System.out.println(" "); System.out.print("产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector System.out.print((String)temp.get(0)+"->"+(String)temp.get(1)); } System.out.println(" "); } }//class Elements class Compression { Tools tools=new Tools(); Elements elements; Vector Vector Vector Vector Vector Vector public void showdelete(Vector if(harm.isEmpty()){ System.out.println("没有有害规则被删除"); } else{ System.out.print("被删除的有害产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector System.out.print((String)temp.get(0)+"->"+(String)temp.get(1)); } System.out.println(); System.out.println("***********************************************"); } if(unreach.isEmpty()){ System.out.println("没有不可到达规则被删除"); } else{ System.out.print("被删除的不可到达产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector System.out.print((String)temp.get(0)+"->"+(String)temp.get(1)); } System.out.println(); System.out.println("***********************************************"); } if(unend.isEmpty()){ System.out.println("没有不可终止规则被删除"); } else{ System.out.print("被删除的不可终止产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector System.out.print((String)temp.get(0)+"->"+(String)temp.get(1)); } System.out.println(); System.out.println("***********************************************"); } } public Vector Vector for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); if(left.equals(right)){//形如A->A newproduce.remove(temp); delete.add(temp); } } return delete; }//public Vector public Vector boolean tag=true; Vector Vector String start_character="S"; flag.add(start_character); while(tag){ flag.clear(); flag.add(start_character); tag=false; for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); for(int j=0;j String s=""+right.charAt(j); if(elements.IsNoENd(s)) flag.add(s); }//for j }//for i for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); if(flag.contains(left)) continue; else{ tag=true; delete.add(temp); newproduce.remove(temp); } }// for }//while return delete; }//public public void shownewproduce(){ System.out.print("压缩后的产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector System.out.print((String)temp.get(0)+"->"+(String)temp.get(1)); } System.out.println(); } public Vector return this.newproduce; } public Vector return this.noend; } public Vector return this.end; } class UnEndable{ Vector Vector public UnEndable(){ thenewproduce=tools.doubleprotection(newproduce); //showthenewproduce(); initial_table(); firststep(); secondstep(); thirdstep(); showflagtable(); } public void showthenewproduce(){ System.out.print("最新的产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector 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 Vector if(temp.get(0).equals(noendcharacter)){ return (String)temp.get(1); }//if }//for return "error"; }//public String whattag public void initial_table(){ for(int i=0;i Vector temp.add((String)noend.get(i)); temp.add("unsure"); flagtable.add(temp); }//for }//public void initial_table(){ public void updatetable(String left,String tag){ for(int i=0;i Vector 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 deleteall(String left){//删除以某个字符为左部的所有产生式 boolean flag=true; BlockB: while(flag){ flag=false; for(int i=0;i Vector if(temp.get(0).equals(left)){ if(thenewproduce.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 Vector left){//删除以某个字符为左部的所有产生式 Vector boolean flag=true; BlockB: while(flag){ flag=false; for(int i=0;i Vector if(temp.get(0).equals(left)){ delete.add(temp); if(produce.remove(temp)){ //System.out.println("以"+left+"为左部的产生式被删除"); } else{ //System.out.println("fail to remove this produce:"+"以"+left+"为左部的产生式"); } flag=true; continue BlockB; }//if }//for }//while() return delete; }//public void deleteAppointall(String left) public void delete(String left,String right){//删除某条特定的产生式 //System.out.println("欲删除产生式:"+left+"->"+right); Vector temp.add(left); temp.add(right); if(thenewproduce.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 boolean Isleftempty(String left){//判断以某个左部为产生式是否为空 for(int i=0;i Vector if(temp.get(0).equals(left)){ return false; } }//for return true; }//public boolean Isleftempty(String left) public void deleteAppoint(Vector //System.out.println("欲删除产生式:"+left+"->"+right); Vector temp.add(left); temp.add(right); if(produce.remove(temp)){ //System.out.println(left+"->"+right+" produce has deleted successfuly"); } else{ System.out.println("fail to remove this produce:"+left+"->"+right); } }//public void deleteAppoint public void firststep(){ Boolean flag=true; BlockA: while(flag){ flag=false; for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); //System.out.println("firststep 产生式:"+left+"->"+right); if((right.length()==1)&&elements.Iscontainend(right)){//r如果长度为1且是终结符 //System.out.println("产生式:"+left+"->"+right+"满足条件"); updatetable(left,"yes"); deleteall(left); flag=true; continue BlockA; } }//for }//while }//public void firststep() public void secondstep(){ boolean flag=true; BlockD: while(flag==true){ flag=false; for(int i=0;i Vector String left=temp.get(0); String _right=temp.get(1); StringBuffer right=new StringBuffer(_right); for(int j=0;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")||elements.Iscontainend(s)){//如果该字符是终结符或者是可终止的非终结符话,删除该非终结符 //System.out.println("欲删除字符"+s); int index=right.indexOf(s); if(index!=-1){ //System.out.println("index="+index); right.deleteCharAt(index); if(right.length()==0){//如果该产生式的右部为空的话 //System.out.println("第三步。左部为空删除以"+left+"为左部的所有产生式"); deleteall(left);//删除以某个字符为左部的所有产生式 updatetable(left,"yes"); } String ss=right.toString(); temp.set(1,ss); flag=true; continue BlockD; }//内层if }//外层if if(_tag.equals("no")){ delete(left,_right); //System.out.println("get in tag= no step"); if(Isleftempty(left)){//判断以某个左部为产生式是否为空 //System.out.println("非终结符为否,所有产生式删除完毕,更新表格"); updatetable(left,"no"); } flag=true; continue BlockD; }//if }//for j }// for i }//while() }// public void secondstep() public void thirdstep(){ for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); if(right.equals("unsure")) updatetable(left,"no"); }//for }// public void thirdstep() public void showflagtable(){ System.out.println("flagtable is shown as follows"); for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); System.out.println(left+":"+right); }//for }// public void showflagtable() public Vector boolean flag=true; BlockE: while(flag){ flag=false; for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); if(whattag(left).equals("no")){ Vector for(int m=0;m Vector delete.add(vv); } flag=true; continue BlockE; } for(int j=0;j String s=""+right.charAt(j); if(elements.IsNoENd(s)){ if(whattag(s).equals("no")){ delete.add(temp); deleteAppoint(produce,left,right); flag=true; continue BlockE; } } } }//for }//while return delete; } }//class UnEndable public Compression(){ elements=new Elements(); elements.run(); this.end=elements.getend(); this.noend=elements.getnoend(); this.produce=elements.getproduce(); newend=tools.protection(end); newnoend=tools.protection(noend); newproduce=tools.doubleprotection(produce); elements.show(); Vector Vector UnEndable un=new UnEndable(); Vector showdelete(harm,unreach,unend); shownewproduce(); } } public class Convert { Elements elements=new Elements(); Tools tools=new Tools(); Vector Vector Vector public String toString(Vector String s=""; if(vv.isEmpty()) return s; for(int i=0;i s=s+vv.get(i); } return s; } public Vector Vector for(int i=0;i String ss=""+s.charAt(i); temp.add(ss); } return temp; } public void show(){ System.out.print("终结符输出如下:"); for(int i=0;i System.out.print((String)end.get(i)+", "); } System.out.println(" "); System.out.print("非终结符输出如下:"); for(int i=0;i System.out.print((String)noend.get(i)+", "); } System.out.println(" "); System.out.print("产生式输出如下:"); for(int i=0;i System.out.println(" "); Vector System.out.print((String)temp.get(0)+"->"+(String)temp.get(1)); } System.out.println(" "); } public String firststep(String _left){ Vector for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); if(left.equals(_left)){ //System.out.println("第一步右部是"+right); if(elements.Iscontainend(right)){ //System.out.println("第一步产生式是"+left+"->"+right); if(result.isEmpty()){//如果返回结果是空,直接加进来,不需要加上“|”或 result.add(right); } else{ result.add("|"); result.add(right); } }// if(result.isEmpty() }//if extener }//for result.insertElementAt("(",0); result.add(")"); String s=toString(result); if(s=="") System.out.println("求"+_left+"的第一步结果是kong"); System.out.println("求"+_left+"的第一步结果是"+s); return s; }//public Vector public Vector Vector Vector Vector for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); int length=right.length(); if(left.equals(_left)){ int index=right.indexOf(_left); if(index==(length-1)){//A->xA形式 if(vv1.isEmpty()){//如果返回结果是空,直接加进来,不需要加上“|”或 vv1.add(right.substring(0, index)); //System.out.println("剪切后是"+right.substring(0, index)); } else{ vv1.add("|"); vv1.add(right.substring(0, index)); //System.out.println("剪切后是"+right.substring(0, index)); } }//if(index==right.length()) if(index==0){//A->Ax形式 if(vv2.isEmpty()){//如果返回结果是空,直接加进来,不需要加上“|”或 vv2.add(right.substring(1, length)); } else{ vv2.add("|"); vv2.add(right.substring(1, length)); } }//if(index==right.length()) }//if(left.equals(_left)) }//for if(vv1.isEmpty()==false){//变成(x|y)* result.add("("); for(int i=0;i result.add(vv1.get(i)); } result.add(")"); result.add("*"); } result.add(_left); if(vv2.isEmpty()==false){ result.add("("); for(int i=0;i result.add(vv2.get(i)); } result.add(")"); result.add("*"); } if(result.size()==1)//如果里面只有一个S的话 result.clear(); //System.out.println("求"+_left+"的第二步结果是"+toString(result)); return result;//变成(x|y)*A(e|f)*形式返回但是程序没有对abAcd形式作出判断 }//public Vector public Vector Vector for(int i=0;i Vector String left=temp.get(0); String right=temp.get(1); if(left.equals(_left)){ boolean flag=false; Vector int length=right.length(); for(int j=0;j String ss=""+right.charAt(j); if(elements.IsNoENd(ss)&&(ss.equals(_left)==false)){//如S->*A*B System.out.println("欲求"+ss+"的getresult"); String sb=getresult(ss);//求出A的可推倒串出来 System.out.println(ss+"的结果是"+sb); vs.set(j, sb); flag=true;//如果做了S->*A*B的推导 } }//for j if(flag==true){ String alsosb=toString(vs); System.out.println("对于"+_left+"分布求出结果是"+alsosb); result.add(alsosb); } }//if(left.equals(_left)) }//for i System.out.println("求"+_left+"的第3步结果是"+toString(result)); return result; }//public void thirdsetp(String _left){ public String getresult(String left){ Vector Vector String first=""; first=firststep(left); temp=secondstep(left); if(temp.isEmpty()==false){ int index=temp.indexOf(left); if(index==-1) System.out.println("异常"); else{ temp.set(index,first); String ss=toString(temp); result.add(ss); } }// if(temp.isEmpty()==false) else{ result.add(first); } Vector if(third.isEmpty()==false){ for(int i=0;i