算符优先算法(FIRSTVT集,LASTVT集,判读是否是算符优先文法,算符优先矩阵,句子分析)

时间:2021-10-14 03:52:45
/////**共有三个类**①主类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;
	}
	//①求FIRSTVT
	String [][] 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的长度大于2
		if(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)));
				       	}*/
				   }
		   }  
	   }
  }
	
	//②求LASTVT
	String [][] 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;
	}
}