LR(0)語法分析(java)

自己參考了網上的代碼寫了如下的LR0分析,斷斷續續寫了一個星期才完成的,可以直接運行,代碼的算法和主流算法不同,很有可能有錯,水平所限,望見諒。

Analyze.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class Analyze {
	public HashMap<Character, ArrayList<String>> experssionSet = new HashMap<Character, ArrayList<String>>();
	public ArrayList<Character> VnList = new ArrayList<Character>();// A S B   非終結符
    public ArrayList<Character> VtList = new ArrayList<Character>();// a b
    public ArrayList<Character>List = new ArrayList<Character>();// a b
	@SuppressWarnings("unchecked")
	public ArrayList<Item> stateClass[] = new ArrayList[20];
	public ArrayList<Item> items = new ArrayList<Item>();
	public ArrayList<Item> flag = new ArrayList<Item>();//有沒有被歸入新一隊過
	public String[][] DFA = new String[8][6];
	//public HashMap<Item, Integer> stateItem = new HashMap<Item, Integer>();
	public HashMap<Integer, ArrayList<Item>> itemClass = new HashMap<Integer, ArrayList<Item>>();
	public ArrayList<Item> stateItems = new ArrayList<Item>();
	public int totalState;

	public void closure(Item I) {
		int a;
		int b;
		ArrayList<Item> J = new ArrayList<Item>();
		ArrayList<Item> temp = new ArrayList<Item>();
		J.add(I);
		//System.out.println("\n傳入的I:");
		//I.printItem();
		flag.add(I);
		if(I.getIndex() == I.getRight().length()) {
			itemClass.put(totalState, J);
			return ;
		}
		else{
			do {
					a = J.size();
					temp.clear();
					for (Item j:J){
						for(Item i:items) {
							if(i.getIndex()==0&&!J.contains(i)) {
								if(j.getRight().charAt(j.getIndex())==i.getLeft()) {
									temp.add(i);	
									flag.add(i);
								}
							}		
						}
					}
					J.addAll(temp);
					b = J.size();
					if(b == a) {
						itemClass.put(totalState, J);
						return;
					}
			 }while(true);
		} 
	}
	public String goto_fun_vt(int state,char X) {
		ArrayList<Item> I = new ArrayList<Item>();
		I = itemClass.get(state);
		int index ;
		int r_count = 0;
		for(Item i:I) {
			index = i.getIndex();
			if(index<i.getRight().length()) {
				if(i.getRight().charAt(index)==X) {
					for(int count=0;count<totalState;count++) {
						for(Item j:itemClass.get(count)) {
							if((j.getRight().equals(i.getRight())&&j.getLeft().equals(i.getLeft()))
									&&j.getIndex()==index+1) {
								return "s"+String.valueOf(count);
							}
								
						}
					}
				}
			}
			else {
				if(i.getRight().equals("E")) {
					if( X == '$')
						return "acc";
					else 
						return "";
				}
				else {
					for(Character c:experssionSet.keySet()) {
						for(String l:experssionSet.get(c)) {
							
							if(c.equals(i.getLeft())&&l.equals(i.getRight()))
								return "r"+String.valueOf(r_count);
							else
								r_count++;
						}
						
					}
					
				}
					
			}
			
		}
		return "";
			
	}//接受一個狀態和一個輸入碼,如果有下一個狀態,返回下個狀態;如果沒有,返回"";
	public String goto_fun_vn(int state,char X) {
		ArrayList<Item> I = new ArrayList<Item>();
		I = itemClass.get(state);
		int index ;
		for(Item i:I) {
			index = i.getIndex();
			if(index<i.getRight().length()) {
				if(i.getRight().charAt(index)==X) {
					for(int count=0;count<totalState;count++) {
						for(Item j:itemClass.get(count)) {
							if((j.getRight().equals(i.getRight())&&j.getLeft().equals(i.getLeft()))
									&&j.getIndex()==index+1) {
								return String.valueOf(count);
							}
								
						}
					}
				}
			}
			else {
				return "";
			}
			
		}
		return "";
			
	}//接受一個狀態和一個輸入碼,如果有下一個狀態,返回下個狀態;如果沒有,返回-1;
	public void createDFA() {
		for(int i = 0;i<8;i++) {
			for(int j=0;j<6;j++) {
				DFA[i][j] = "";
			}
		}
		DFA[0][0] = "st";
		int count = 0;
		for(Character c: List) {
			count++;
			DFA[0][count] = c.toString();
			
		}
		for(count = 0;count<totalState;count++) {
			DFA[count+1][0] = String.valueOf(count);
		}
		int vtSize = VtList.size();
		int vnSize = VnList.size();
		for(int i=0;i< totalState;i++) {
			for(int j=0;j<vtSize;j++) {
				DFA[i+1][j+1] = goto_fun_vt(i,VtList.get(j));
			}
			for(int j=0;j<vnSize;j++) {
				DFA[i+1][vtSize+j+1] = goto_fun_vn(i,VnList.get(j));
			}
		}
		
	}
	
	public void initList(HashSet<Character> VnSet,HashSet<Character> VtSet) {
		Character ch = 'A';
		Character ch1 = '$';
        java.util.Iterator<Character> itVn=VnSet.iterator();
        java.util.Iterator<Character> itVt=VtSet.iterator();
        while(itVn.hasNext()){
            VnList.add(itVn.next());
        }
        while(itVt.hasNext()){
            VtList.add(itVt.next());
        }
        VnList.remove(ch);
        VtList.add(ch1);
        List.addAll(VtList);
        List.addAll(VnList);
	}
	public static void main(String[] args) {
		Analyze a = new Analyze();
		a.init();
		for(int state=0;state<a.totalState;state++) {
			System.out.println("state:"+state);
			for(Item i:a.itemClass.get(state)) {
				i.printItem();
			}
		}
		
	}
	public String[][] init(){
		SLR1 demo = new SLR1();
		
		totalState = 0;
		demo.Init();
		demo.getNvNt();
		initList(demo.VnSet,demo.VtSet);
		experssionSet = demo.experssionSet;
		for(Character c:demo.VnSet) {
			for(String l:demo.experssionSet.get(c)) {
				for(int i=0;i<=l.length();i++) {
					Item item = new Item(i,c,l);
					items.add(item);
				}
				
			}
		}
		
		for(Item i:items) {
			if(!flag.contains(i)) {
				closure(i);
				totalState++;
			}
		}
		createDFA();
		return DFA;
	}
	
	

}

Item.java
public class Item {
	private int index;
	private Character left;
	private String right;
	public Item(int index,Character left,String right) {
		this.index = index;
		this.left = left;
		this.right = right;
	}
	public int getIndex() {
		return index;
	}
	
	public Character getLeft() {
		return left;
	}
	
	public String getRight() {
		return right;
	}
	

	public void printItem() {
		System.out.println(this.left+"->"+this.right);
	}
}

LR0.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;



class LR0{
    public HashSet<Character> VnSet = new HashSet<Character>();
    public HashSet<Character> VtSet = new HashSet<Character>();
    public HashMap<Character, ArrayList<String>> experssionSet = new HashMap<Character, ArrayList<String>>();
    // E: TK | K: +TK $ | T : FM | M: *FM $|F :i (E)
    public String [][] table;
    public String [][] tableLR0;
    public Stack<Character> analyzeStatck = new Stack<Character>();
    public Stack<String> stackState = new Stack<String>();
    public Stack<Character> stackSymbol = new Stack<Character>();
    public String strInput = "bab$";
    public String action = "";
    public String[] LRGS = {"A->E","E->BB","B->aB","B->b"};
    int index = 0;
   
    public String [] inputExperssion = {"A->E","E->BB","B->aB","B->b"};
    public Item[] itemSet = new Item[10];
    public void Init() {
        for (String e : inputExperssion) {
            String[] str = e.split("->");//切割出數組
            char c = str[0].charAt(0);//產生式左部
            ArrayList<String> list = experssionSet.containsKey(c) ? experssionSet.get(c) : new ArrayList<String>();
            list.add(str[1]);
            experssionSet.put(c, list);//put(key,value)  
        }
        getNvNt();
    }//初始化函數
    public void setExpression() {
    	int count = 0;
    	for(Character c:experssionSet.keySet()) {
			for(String l:experssionSet.get(c)) {
				Item item = new Item(-1,c,l);
				itemSet[count] = item;
				count++;

			}
			
		}
    }
    public void getNvNt() {
        for (String e : inputExperssion) {
            String[] str = e.split("->");
            VnSet.add(str[0].charAt(0));
        }//把所有產生式的左部加入非終結符集合中
        for (String e : inputExperssion) {
            String[] str = e.split("->");
            String right = str[1];
            for (int i = 0; i < right.length(); i++) 
                if (!VnSet.contains(right.charAt(i)))
                    VtSet.add(right.charAt(i));      
        }//把右部不是非終結符的符號加入到終結符集合中
        //System.out.println("終結符:"+VtSet);
        //System.out.println("非終結符:"+VnSet);
    }//產生終結符和非終結符集合

    public void analyzeLR0() {
        action = "";
        index = 0;
        stackState.push("0");
        char a = strInput.charAt(index);
        System.out.println("****************LR0分析過程**********");
        System.out.println("                    狀態         Symbol        Input         Action");
        this.displayLR0();
        while (true) {
            String s = stackState.peek();
            // 查表爲移進
            if (Action(s, a).charAt(0) == 's') {
                stackState.push(Action(s, a).substring(1));
                stackSymbol.push(a);
                a = strInput.charAt(++index);
                action = "shift ";
                displayLR0();
            }
            // 查表爲歸約
            else if (Action(s, a).charAt(0) == 'r') {
                // 獲取文法串
            	int ex = Action(s, a).charAt(1)-48;
            	String str_r = itemSet[ex].getRight();
            	char str_l = itemSet[ex].getLeft();
       
            	for(int i = 0;i<str_r.length();i++) {
            		stackSymbol.pop();
                    stackState.pop();
            	}
                // goto的值進棧
                String t = stackState.peek();
                stackState.push(Action(t, str_l));
                stackSymbol.push(str_l);
                action = "reduce:" + str_r;
                displayLR0();
            } 
            else if (Action(s, a) == "acc")
                break;
            else
                return;
        }
        System.out.println("analyze LR0 successfully");
        System.out.println("****************LR0分析過程**********");
    }

    public String Action(String s, char a) {
    	//System.out.println("s:"+s+"a:"+a);
    	
        for (int i = 1; i < 15; i++)
            if (tableLR0[i][0].equals(s)) {
            	for (int j = 1; j < 10; j++)
                    if (tableLR0[0][j].charAt(0) == a)
                        return tableLR0[i][j];
            }
                
        return "";
    }

    public String find(char X, char a) {
        for (int i = 0; i < VnSet.size() + 1; i++) {
            if (table[i][0].charAt(0) == X)
                for (int j = 0; j < VtSet.size() + 1; j++) {
                    if (table[0][j].charAt(0) == a)
                        return table[i][j];
                }
        }
        return "";
    }
    public void insert(char X, char a,String s) {
        if(a == '~') a = '$';
        for (int i = 0; i < VnSet.size() + 1; i++) {
            if (table[i][0].charAt(0) == X)
                for (int j = 0; j < VtSet.size() + 1; j++) {
                    if (table[0][j].charAt(0) == a){
                        table[i][j] = s;
                        return;
                    }
                }
        }
    }


    public void displayLR0() {
        // 輸出 LR0
        System.out.printf("%25s", stackState);
        System.out.printf("%12s", stackSymbol);
        System.out.printf("%14s", strInput.substring(index));
        System.out.printf("%16s", action);
        System.out.println();
    }

    public void ouput() {
        System.out.println("**********LR語法分析表********");

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 6; j++) {
                System.out.printf("%6s", tableLR0[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("**********LR語法分析表********");

    }
    public static void main(String[] args) {
        LR0 test = new LR0();
        test.getNvNt();
        test.Init();
        test.setExpression();
        Analyze a = new Analyze();
        a.init();
        test.tableLR0 = a.DFA;
        test.ouput();
        for(int i=0;i<4;i++) {
        	System.out.print("\n文法"+String.valueOf(i)+":");
        	test.itemSet[i].printItem();
        }
        test.analyzeLR0();
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章