自己參考了網上的代碼寫了如下的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();
}
}