/////**共有三个类**①主类Op.java*②处理算法的关键类GetFL.java*③读取信息类ReadInfo.java从TXT文件中读取文法**////
/* * author:Ack訾 * Date:15/11/2012 * Attention: */package com.algorithm;import java.io.IOException;import java.util.ArrayList;import java.util.Scanner;public class OP {/** * @param args */public static void main(String[] args)throws IOException {String fileName="H:\\大三实验课\\编译原理\\实验3\\input.txt";ReadInfo ri=new ReadInfo(); String[][] ll = ri.gettext(fileName); GetFL fl=new GetFL(ll); //①读取的文法放在ll[][]二维数组中,可根据下面的注释语句进行打印 System.out.println(" 文法G"+"["+ll[0][0]+"]"+":"); System.out.println(" "+ll[0][0]+"'"+"->"+"#"+ll[0][0]+"#"); for(int i=0;i<ll[0].length;i++){ System.out.print(" "+ll[0][i]); System.out.print("->"); System.out.println(ll[1][i]); } System.out.println(" "); //②终结符放在NT[]中(not terminate)可通过下面注释语句进行打印 String[]NT = fl.getNT(); System.out.print(" 非终结符集:");System.out.print("{"); for(int i=0;i<NT.length;i++){ //if(NT[i]=="\\'"){System.out.print("亲!咱解决不了含有“‘”的文法");} if(NT.length-1==i) System.out.print(NT[i]); else System.out.print(NT[i]+","); } System.out.println("}"); //③终结符放在T[]中(teminate) 可通过下面注释语句进行打印 String[]T = fl.getT(); System.out.print(" 终结符集:");System.out.print("{"); for(int i=0;i<T.length;i++){ if(T.length-1 ==i) System.out.print(T[i]); else System.out.print(T[i]+","); } System.out.println("}"); System.out.println(" "); //④FIRSTVT求解过程 String[][] FirstVT = fl.getFirstVT(); System.out.println(" FIRSTVT集:"); System.out.println(" LASTVT("+FirstVT[0][0]+"'"+")"+"="+"{"+"#"+"}"); for(int i=0;i<FirstVT[0].length;i++){ System.out.print(" FIRSTVT("+FirstVT[0][i]+")"+"="+"{"); //System.out.println(FirstVT[1][i]); //if(NT[i]=="\\'"){System.out.print("亲!咱解决不了含有“‘”的文法");} char[] ch=FirstVT[1][i].toCharArray(); for(int j=0;j<ch.length;j++){ if(ch.length-1 ==j) System.out.print(ch[j]); else System.out.print(ch[j]+","); } System.out.println("}"); } System.out.println(" "); //⑤LASTVT求解过程 String[][] LastVT = fl.getLastVT(); System.out.println(" LASTVT集:"); System.out.println(" LASTVT("+LastVT[0][0]+"'"+")"+"="+"{"+"#"+"}"); for(int i=0;i<LastVT[0].length;i++){ System.out.print(" LASTVT("+LastVT[0][i]+")"+"="+"{"); //System.out.println(FirstVT[1][i]); //if(NT[i]=="\\'"){System.out.print("亲!咱解决不了含有“‘”的文法");} char[] ch=LastVT[1][i].toCharArray(); for(int j=0;j<ch.length;j++){ if(ch.length-1 ==j) System.out.print(ch[j]); else System.out.print(ch[j]+","); } System.out.println("}"); } System.out.println(); //⑥求解算符优先矩阵 System.out.println("算符优先关系矩阵"); System.out.println("-------------------------------------------------------------------"); System.out.print("\t"); for(int i=0;i<T.length;i++){ System.out.print(T[i]+"\t"); } System.out.println(); System.out.println("-------------------------------------------------------------------"); String[][] Op=fl.getMatrix(); for(int i=0;i<Op[0].length;i++){ System.out.print(" "+T[i]); for(int j=0;j<Op[0].length;j++){ System.out.print("\t"+Op[i][j]); } System.out.println(); System.out.println("-------------------------------------------------------------------"); } if(fl.isOP==false)System.out.print("此文发非算符优先文法"); //⑦分析句子 Scanner sc=new Scanner(System.in); String sentence =sc.next(); char[] ch=sentence.toCharArray(); //s用于存放读入的语句 ArrayList<String> s=new ArrayList<String>(); for(int i=0;i<ch.length;i++){ s.add(String.valueOf(ch[i])); } //判断输入的符号串是否是本文法的终结符 boolean isExisted=true; String NotExist=""; String stringT=""; for(int i=0;i<T.length;i++){ stringT=stringT.concat(T[i]); } for(int i=0;i<ch.length;i++){ if(!stringT.contains(String.valueOf(ch[i]))) { if(ch[i]!='#') {isExisted=false; NotExist= String.valueOf(ch[i]); } } } // s.add("#"); //System.out.print(s.toString()); //stack用于存放分析栈 if(isExisted==false){ System.out.print(NotExist+"不是此文法的的终极符"); } else{ ArrayList<String> stack=new ArrayList<String>(); stack.add("#"); String temp =s.remove(0); ArrayList<String> sentence_result=new ArrayList<String>(); String s_result=new String(); s_result=s_result.concat(stack+"\t"+temp+"\t"+s+"\t"); boolean isSuccess=false; boolean isFailed=false; for(int k=0;k<ch.length;k++){ for(int i=0;i<T.length;i++){ if(T[i].equals(stack.get(stack.size()-1))){ for(int j=0;j<T.length;j++){ if(T[j].equals(temp)){ if(Op[i][j].equals("<")){ s_result=s_result.concat("移近"); sentence_result.add(s_result);s_result=""; stack.add(temp);temp=s.remove(0); s_result=s_result.concat(stack+"\t"+temp+"\t"+s+" \t"); } else if(Op[i][j].equals(">")){ s_result=s_result.concat("规约"); sentence_result.add(s_result);s_result=""; if(stack.size()>1) stack.remove(stack.get(stack.size()-1)); s_result=s_result.concat(stack+"\t"+temp+"\t"+s+"\t"); } else if(stack.get(stack.size()-1)=="#"&&isSuccess==false){ s_result=s_result.concat("分析成功");isSuccess=true; sentence_result.add(s_result); } else if(isSuccess!=true&&isFailed==false){ s_result=s_result.concat("分析失败");isFailed=true; sentence_result.add(s_result); } } } } } } // System.out.print(sentence_result.size()); for(int i=0;i<sentence_result.size();i++){ System.out.print("("+(i+1)+")"); System.out.print("\t"); System.out.println(sentence_result.get(i)); } } }}
//**关键类GetFL.java**/////
package com.algorithm;import java.util.HashMap;public class GetFL { public String [][]str;static String FIRSRVTstring="";static String LASTVTstring=""; boolean isOP=true;//static String Tstringselect="";//构造函数对象进行初始化GetFL(String[][] ll){str=ll;}//①求FIRSTVTString [][] getFirstVT(){String[][] FirstVT = new String[2][str[0].length];for(int i=0;i<str[0].length;i++){FirstVT[0][i]=str[0][i];getFVT(str[0][i],str[1][i]);FirstVT[1][i]=FIRSRVTstring;FIRSRVTstring="";}return FirstVT;}//获取非终结符放到NT数组中String[] getNT(){//String [][] Follow=getFollow();String[] NT=new String[str[0].length];for(int i=0;i<str[0].length;i++){NT[i]=str[0][i];}return NT;}//获取终结符 放到T数组中String[] getT(){String[] NT1 = getNT();String temp=new String();for(int i=0;i<str[1].length;i++){temp=temp+str[1][i];}for(int i=0;i<NT1.length;i++){temp=temp.replaceAll(NT1[i],"");}temp=temp.replaceAll("\\|","");temp=temp.replaceAll("\\'","");//System.out.println(temp);char[] ch=new char[temp.length()];ch=temp.toCharArray();String resultString = new String();for(int i=0;i<ch.length;i++){if(!resultString.contains(String.valueOf(ch[i])))resultString=resultString.concat(String.valueOf(ch[i]));}//System.out.println(resultString);String[] T=new String[resultString.length()+1];T[resultString.length()]="#";for(int i=0;i<resultString.length();i++){T[i]=(String)String.valueOf(resultString.charAt(i));//System.out.println(T[i]);}return T;}//递归void getFVT(String str3 ,String str4){String[] s =null;if(str4.contains("|")){ s=str4.split("\\|"); for(int j=0;j<s.length;j++){getFVT(str3,s[j]); }} else{//1//*str4的长度为1 if(str4.length()==1){//*str4的长度为1且为终结符的时候直接加入 if(!('A'<=str4.charAt(0)&&str4.charAt(0)<='Z')){ if(!FIRSRVTstring.contains(String.valueOf(str4.charAt(0))))FIRSRVTstring=FIRSRVTstring.concat(String.valueOf(str4.charAt(0))); }//2//*str4的长度为1且为非终结符,此时应查找其str[2][]中str[0][i]为str4的右边表达式getFVT(str[1][i]) else{ for(int i=0;i<str[0].length;i++){ if(str[0][i].equals(String.valueOf(str4.charAt(0)))){if(!str3.equals(String.valueOf(str4.charAt(0))))getFVT(str[0][i],str[1][i]); }}} }//3//*str4的长度大于2if(str4.length()>=2){//①第一个为终结符时 if(!('A'<=str4.charAt(0)&&str4.charAt(0)<='Z')){ if(!FIRSRVTstring.contains(String.valueOf(str4.charAt(0))))FIRSRVTstring=FIRSRVTstring.concat(String.valueOf(str4.charAt(0)));}//②第一个非终结符且第二个为终结符 if('A'<=str4.charAt(0)&&str4.charAt(0)<='Z'&&!('A'<=str4.charAt(1)&&str4.charAt(1)<='Z')){ //先加入这个终结符号 if(!FIRSRVTstring.contains(String.valueOf(str4.charAt(1)))) FIRSRVTstring=FIRSRVTstring.concat(String.valueOf(str4.charAt(1))); //再循环查找这个非终极符的情况//**找到第一个为终结符 for(int i=0;i<str[0].length;i++){ //if条件用于消除自身进行循环if(str[0][i].equals(String.valueOf(str4.charAt(0))))//&&!str[0][i].equals(String.valueOf(str[1][i].charAt(0))))if(!str3.equals(String.valueOf(str4.charAt(0))))getFVT(str[0][i],str[1][i]);} }//③第一个非终结符且第二个也为非终结符 if('A'<=str4.charAt(0)&&str4.charAt(0)<='Z'&&'A'<=str4.charAt(1)&&str4.charAt(1)<='Z'){ for(int i=0;i<str[0].length;i++){ //if条件用于消除自身进行循环if(str[0][i].equals(String.valueOf(str4.charAt(0))))//&&!str[0][i].equals(String.valueOf(str[1][i].charAt(0))))if(!str3.equals(String.valueOf(str4.charAt(0))))getFVT(str[0][i],str[1][i]);if(str[0][i].equals(String.valueOf(str4.charAt(1))))//&&!str[0][i].equals(String.valueOf(str[1][i].charAt(0))))if(!str3.equals(String.valueOf(str4.charAt(1))))getFVT(str[0][i],str[1][i]);} //**第二个也为非终结符 // if('A'<=str4.charAt(0)&&str4.charAt(1)<='Z'){//第二个也非终结符/* for(int i=0;i<str[0].length;i++){if(str[0][i].equals(str4))getFVT(str[0][i],str[1][i]);}*/// } /* else{ FIRSRVTstring=FIRSRVTstring.concat(String.valueOf(str4.charAt(1))); }*/ } } } }//②求LASTVTString [][] getLastVT(){String[][] LastVT = new String[2][str[0].length];for(int i=0;i<str[0].length;i++){LastVT[0][i]=str[0][i];getLVT(str[0][i],str[1][i]);LastVT[1][i]=LASTVTstring;LASTVTstring="";}return LastVT;}//递归private void getLVT(String string1, String string2) {String[] s=null;if(string2.contains("|")){ s=string2.split("\\|"); for(int j=0;j<s.length;j++){getLVT(string1,s[j]); }}else{//1 //*string2的长度为1 if(string2.length()==1){//*string2的长度为1且为终结符的时候直接加入 if(!('A'<=string2.charAt(0)&&string2.charAt(0)<='Z')){ if(!LASTVTstring.contains(String.valueOf(string2.charAt(string2.length()-1)))) LASTVTstring=LASTVTstring.concat(String.valueOf(string2.charAt(string2.length()-1))); }//2 //*string2的长度为1且为非终结符,此时应查找其str[2][]中str[0][i]为string2的右边表达式getLVT(str[1][i]) else{ for(int i=0;i<str[0].length;i++){ if(str[0][i].equals(String.valueOf(string2.charAt(string2.length()-1)))){if(!string1.equals(String.valueOf(string2.charAt(string2.length()-1))))getLVT(str[0][i],str[1][i]); }}} }//3 //*string2的长度大2 if(string2.length()>=2){//①当string2最后一个为终结符时if(!('A'<=string2.charAt(string2.length()-1) && string2.charAt(string2.length()-1)<='Z')){if(!LASTVTstring.contains(String.valueOf(string2.charAt(string2.length()-1))))LASTVTstring=LASTVTstring.concat(String.valueOf(string2.charAt(string2.length()-1)));}//②当string2倒数第二个为终结符时且最后一个为非终结符时if(('A'<=string2.charAt(string2.length()-1) && string2.charAt(string2.length()-1)<='Z')&&(!('A'<=string2.charAt(string2.length()-2) && string2.charAt(string2.length()-2)<='Z'))){ //将终结符加入if(!LASTVTstring.contains(String.valueOf(string2.charAt(string2.length()-2))))LASTVTstring=LASTVTstring.concat(String.valueOf(string2.charAt(string2.length()-2)));//循环中后一个非终结符加入 for(int i=0;i<str[0].length;i++){ //if条件用于消除自身进行循环if(str[0][i].equals(String.valueOf(string2.charAt(string2.length()-1))))//&&!str[0][i].equals(String.valueOf(str[1][i].charAt(0))))if(!string1.equals(String.valueOf(string2.charAt(string2.length()-1))))getLVT(str[0][i],str[1][i]);}}////③当string2倒数第二个为终结符时且最后一个也为终结符时 if(('A'<=string2.charAt(string2.length()-1) && string2.charAt(string2.length()-1)<='Z')&&('A'<=string2.charAt(string2.length()-2) && string2.charAt(string2.length()-2)<='Z')){ for(int i=0;i<str[0].length;i++){ //if条件用于消除自身进行循环if(str[0][i].equals(String.valueOf(string2.charAt(string2.length()-1))))//&&!str[0][i].equals(String.valueOf(str[1][i].charAt(0))))if(!string1.equals(String.valueOf(string2.charAt(string2.length()-1))))getLVT(str[0][i],str[1][i]);if(str[0][i].equals(String.valueOf(string2.charAt(string2.length()-2))))//&&!str[0][i].equals(String.valueOf(str[1][i].charAt(0))))if(!string1.equals(String.valueOf(string2.charAt(string2.length()-2))))getLVT(str[0][i],str[1][i]);} }}}} //③求各终结符的算符优先关系//利用二维矩阵来存放算符优先关系-1表示无关系,0表示相等关系,1表示小于关系,2表示大于关系//先找到形如A—>…a…和A->…aBb… 相等关系 放入equal[][]数组中//再找到形如A->…aB… 小于关系 放入lessthan[][]数组中//最后找到形如A->…Bb… 大于关系 放入 morethan[][]数组中//将以上封装到函数中返回二维数组放到int型op_matrix中String[][] getMatrix(){ String[][] LastVT = getLastVT(); String[][] FirstVT = getFirstVT(); String[] T=getT();String[][] op_matrix=new String[T.length][T.length];//先找到形如A—>…ab…和A->…aBb… 相等关系 放入equal[][]数组中HashMap<String,String> equal= new HashMap<String,String>();equal.put("#","#");for(int i=0;i<str[0].length;i++){if(str[1][i].length()==2){for(int j=0;j<str[1][i].length()-1;j++){if(!('A'<=str[1][i].charAt(j)&&str[1][i].charAt(j)<'Z')&&(str[1][i].charAt(j)!='|'&&str[1][i].charAt(j+1)!='|')&&!('A'<=str[1][i].charAt(j+1)&&str[1][i].charAt(j+1)<'Z')){equal.put(String.valueOf(str[1][i].charAt(j)),String.valueOf(str[1][i].charAt(j+1)));}}}if(str[1][i].length()>=3){for(int j=0;j<str[1][i].length()-2;j++){if((str[1][i].charAt(j+2)!='|'&&str[1][i].charAt(j+1)!='|'&&str[1][i].charAt(j)!='|')&&!('A'<=str[1][i].charAt(j+2)&&str[1][i].charAt(j+2)<'Z')&&!('A'<=str[1][i].charAt(j)&&str[1][i].charAt(j)<'Z')&&('A'<=str[1][i].charAt(j+1)&&str[1][i].charAt(j+1)<'Z')){equal.put(String.valueOf(str[1][i].charAt(j)),String.valueOf(str[1][i].charAt(j+2)));}}} }//再找到形如A->…aB… 小于关系 放入lessthan<String><String> HashTable中HashMap<String,String> lessthan= new HashMap<String,String>();lessthan.put("#",FirstVT[1][0]);for(int i=0;i<str[0].length;i++){if(str[1][i].length()>=2){for(int j=0;j<str[1][i].length()-1;j++){if(!('A'<=str[1][i].charAt(j)&&str[1][i].charAt(j)<='Z')&&str[1][i].charAt(j)!='|'&&('A'<=str[1][i].charAt(j+1)&&str[1][i].charAt(j+1)<='Z')){for(int k=0;k<str[1].length;k++){if(str[0][k].equals(String.valueOf(str[1][i].charAt(j+1)))) lessthan.put(String.valueOf(str[1][i].charAt(j)),FirstVT[1][k]);}}} }}//最后找到形如A->…Bb… 大于关系 放入 morethan[][]数组中HashMap<String,String> morethan= new HashMap<String,String>();morethan.put("#",LastVT[1][0]);for(int i=0;i<str[0].length;i++){if(str[1][i].length()>=2){for(int j=0;j<str[1][i].length()-1;j++){if(('A'<=str[1][i].charAt(j)&&str[1][i].charAt(j)<='Z')&&!('A'<=str[1][i].charAt(j+1)&&str[1][i].charAt(j+1)<='Z')&&str[1][i].charAt(j+1)!='|'){for(int k=0;k<str[1].length;k++){if(str[0][k].equals(String.valueOf(str[1][i].charAt(j)))) morethan.put(String.valueOf(str[1][i].charAt(j+1)),LastVT[1][k]);}}} }}//将morethan转化为数组more中便于以下操作 Object[] str=morethan.keySet().toArray(); Object[] str1=morethan.values().toArray(); String[][] more=new String[2][morethan.size()]; for(int i=0;i<str.length;i++){ more[0][i]=str[i].toString(); more[1][i]=str1[i].toString(); }//给二维数组赋初值-1,尚未发生关系for(int i=0;i<T.length;i++){for(int j=0;j<T.length;j++){op_matrix[i][j]="\f";}}//进行逻辑赋值for(int i=0;i<T.length;i++){ //查找eaual中两个相等关系符号在T中的位置 // for(int k=0;k<equal.size();k++){ if(equal.containsKey(T[i])){ for(int j=0;j<T.length;j++){ if(equal.get(T[i]).contains(T[j])) if (op_matrix[i][j]!=">"&&op_matrix[i][j]!="<") op_matrix[i][j]="="; else isOP=false; } }//查找lessthan中两个小于关系符号在T中的位置 //for(int k=0;k<lessthan.size();k++){ if(lessthan.containsKey(T[i])){ for(int j=0;j<T.length;j++){ if(lessthan.get(T[i]).contains(T[j])) if (op_matrix[i][j]!=">"&&op_matrix[i][j]!="=") op_matrix[i][j]="<"; else isOP=false; } } // } //查找morethan中两个小于关系符号在T中的位置 for(int k=0;k<more[0].length;k++){String temp=more[1][k]; if(temp.contains(T[i])){ for(int j=0;j<T.length;j++){ if(more[0][k].contains(T[j])) if (op_matrix[i][j]!="<"&&op_matrix[i][j]!="=") op_matrix[i][j]=">"; else isOP=false; } }} }//返回二维数组//System.out.print(equal.toString());//System.out.print(lessthan.toString());//System.out.print(morethan.toString());return op_matrix;} //④对句子进行分析}
////*****读取信息类ReadInfo.java****////
package com.algorithm;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.util.ArrayList;class ReadInfo{//读取input.txt文件中的内容String[][] gettext(String str) throws IOException{FileReader fr=new FileReader(str);BufferedReader br=new BufferedReader(fr);String temp;ArrayList<String> list =new ArrayList<String>();while((temp=br.readLine())!=null){list.add(temp);}br.close();String arr[]=new String[list.size()];String arrNT[]=new String[list.size()];//非终结符数组String arrT[]=new String[list.size()];//终结符号数组for(int i=0;i<list.size();i++){arr[i]=(String) list.get(i);//System.out.println(arr[i]);}for(int i=0;i<arr.length;i++){String[] temp1;temp1=arr[i].split("->");arrNT[i]=temp1[0];arrT[i]=temp1[1];}String[][] ll=new String[2][list.size()];for(int i=0;i<list.size();i++){ll[0][i]=arrNT[i];ll[1][i]=arrT[i];}return ll;}}