算符优先

算符优先-------Java实现

实验题目
在这里插入图片描述
实验结果
在这里插入图片描述
在这里插入图片描述
1、读取文本

package by02;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class by02file {

	private ArrayList<ArrayList<String>> G = new ArrayList<ArrayList<String>>();

	private String str = "";

	public by02file() throws IOException {
		File file = new File("D://byfile02.txt");
		try {
			BufferedReader bu = new BufferedReader(new FileReader(file));
			String s = null;
			while ((s = bu.readLine()) != null) {
				str += s;
				str += '\n';
			}
			bu.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public void getStr() {
		System.out.println(str);
	}

	public ArrayList<ArrayList<String>> PG() {
		ArrayList<String> A = new ArrayList<String>();
		//A中以字符串形式保存产生式的左部和右部候选式
		int i = 0;
		String s0 = "";
		//集合不是将对象克隆存储,而是对对象的引用,为不改之前信息,需重新定义

		while ((i < str.length())) {
			if (str.charAt(i) == '-' && str.charAt(i + 1) == '>') {
				A.add(s0);
				s0 = "";
				i += 2;
			}else if(str.charAt(i)=='|') {
				A.add(s0);
				s0="";
				i++;		
			}else if(str.charAt(i)=='\n') {
				A.add(s0);
				G.add(A);
				s0="";
				A=new ArrayList<String>();
				i++;
			}
			else {
				s0+=str.charAt(i);
				i++;
			}


		}
		return G;	
	}

}

2、FirstVt集、LastVt集及归约分析过程

package by02;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

public class by02main {

	static ArrayList<ArrayList<String>> G = new ArrayList<ArrayList<String>>();
	static ArrayList<String> Vn = new ArrayList<String>();
	static ArrayList Vt = new ArrayList();
	static ArrayList<ArrayList> VnFirstVT = new ArrayList<ArrayList>();
	static ArrayList<ArrayList> VnLastVT = new ArrayList<ArrayList>();
	static int N = 3;

	public static void removeDuplicate(ArrayList<ArrayList> list) {// 清楚集中的重复元素
		int i = 0;
		while (i < G.size()) {
			HashSet h = new HashSet(list.get(i));
			list.get(i).clear();
			list.get(i).addAll(h);
			i++;
		}

	}

	public static void FirstVT() {
		int i = 0;
		while (i < G.size()) {// 第一遍扫描
			ArrayList A = new ArrayList();
			int j = 1;
			while (j < G.get(i).size()) {
				int t = 0;
				for (; t < 2 && t < G.get(i).get(j).length(); t++) {
					char c = G.get(i).get(j).charAt(t);
					if (Vt.contains(c)) {
						A.add(c);
						break;
					}
				}

				j++;
			}
			VnFirstVT.add(A);
			i++;
		}
//		System.out.println(VnFirstVT);
		i = 0;
		while (i < G.size()) {// 第二遍扫描
			int j = 1;
			ArrayList<String> L = new ArrayList<String>();
			int count = 0;
			while (j < G.get(i).size()) {
				String s = "";
				s += G.get(i).get(j).charAt(0);
				if (Vn.contains(s) && !s.equals(Vn.get(i))) {// 后者條件是避免自身first加入自身,無終止進行
					L.add(s);
//					System.out.println(s);
				}
				j++;
			}
			while (count < L.size()) {
				int t = Vn.indexOf(L.get(count));
				int m = 1;
				while (m < G.get(t).size()) {
					String s = "";
					s += G.get(t).get(m).charAt(0);
					if (Vn.contains(s) && !L.contains(s)) {
						L.add(s);
					}
					m++;
				}
				count++;
			}
//			System.out.println(L);
			int m = 0;
			while (m < L.size()) {
				int t = Vn.indexOf(L.get(m));
				VnFirstVT.get(i).addAll(VnFirstVT.get(t));
				m++;
			}
			i++;
		}
		removeDuplicate(VnFirstVT);// 清重复元素
		System.out.println("各非终结符的FIRSTVT集为:" + VnFirstVT);

	}

	public static void LastVT() {
		int i = 0;
		while (i < G.size()) {// 第一遍扫描
			ArrayList A = new ArrayList();
			int j = 1;
			while (j < G.get(i).size()) {
				int t = G.get(i).get(j).length() - 1;
				for (; t >= 0 && t >= G.get(i).get(j).length() - 2; t--) {
					char c = G.get(i).get(j).charAt(t);
					if (Vt.contains(c)) {
						A.add(c);
						break;
					}
				}

				j++;
			}
			VnLastVT.add(A);
			i++;
		}

		i = 0;
		while (i < G.size()) {// 第二遍扫描
			int j = 1;
			ArrayList<String> L = new ArrayList<String>();
			int count = 0;
			while (j < G.get(i).size()) {
				String s = "";
				s += G.get(i).get(j).charAt(G.get(i).get(j).length() - 1);
				if (Vn.contains(s) && !s.equals(Vn.get(i))) {// 后者條件是避免自身first加入自身,無終止進行
					L.add(s);
					// System.out.println(s);
				}
				j++;
			}
			while (count < L.size()) {
				int t = Vn.indexOf(L.get(count));
				int m = 1;
				while (m < G.get(t).size()) {
					String s = "";
					s += G.get(t).get(m).charAt(G.get(t).get(m).length() - 1);
					if (Vn.contains(s) && !L.contains(s)) {
						L.add(s);
					}
					m++;
				}
				count++;
			}
			// System.out.println(L);
			int m = 0;
			while (m < L.size()) {
				int t = Vn.indexOf(L.get(m));
				VnLastVT.get(i).addAll(VnLastVT.get(t));
				m++;
			}
			i++;
		}
		removeDuplicate(VnLastVT);// 清重复元素
		System.out.println("各非终结符的LASTVT集为:" + VnLastVT);

	}

	public static void VnAndVt(by02file bf) {// 整理文法中非终结符和终结符,由于扩展开始符E',所以非终结符采用字符串存储
		String s0 = "";
		G = bf.PG();
		int i = 0;
		while (i < G.size()) {
			Vn.add(G.get(i).get(0));
			i++;
		}
		i = 0;
		while (i < G.size()) {
			int j = 1;
			while (j < G.get(i).size()) {
				int t = 0;
				while (t < G.get(i).get(j).length()) {
					s0 = "";
					s0 += G.get(i).get(j).charAt(t);
					if (!Vn.contains(s0) && !Vt.contains(G.get(i).get(j).charAt(t))) {
						Vt.add(G.get(i).get(j).charAt(t));
					}
					t++;
				}
				j++;
			}
			i++;
		}

	}

	public static char[][] Table() {
		N = Vt.size() + 1;
		char[][] c = new char[N][N];
		for (int i = 1; i < N; i++) {
			c[i][0] = (char) Vt.get(i - 1);
			c[0][i] = (char) Vt.get(i - 1);
		}
		int i = 0;
		int j;
		while (i < G.size()) {
			j = 1;
			while (j < G.get(i).size()) {
				for (int t = 0; t < G.get(i).get(j).length(); t++) {
					if (Vt.contains(G.get(i).get(j).charAt(t))) {// 遍历到终结符
						if (t - 1 >= 0 && !Vt.contains(G.get(i).get(j).charAt(t - 1))) {
							// 判其前是否有非终结符,若有将其LastVT集中元素>此终结符,L中元素>此元素
							String s = "";
							s += G.get(i).get(j).charAt(t - 1);
							int x = Vn.indexOf(s);
							for (int y = 0; y < VnLastVT.get(x).size(); y++) {
								c[Vt.indexOf(VnLastVT.get(x).get(y)) + 1][Vt.indexOf(G.get(i).get(j).charAt(t))
										+ 1] = '>';
							}
						}
						if (t + 1 < G.get(i).get(j).length() && !Vt.contains(G.get(i).get(j).charAt(t + 1))) {
							// 判其后是否有非终结符,若有将其FirstVT集中元素<此终结符,此元素<F中元素
							String s = "";
							s += G.get(i).get(j).charAt(t + 1);
							int x = Vn.indexOf(s);
							for (int y = 0; y < VnFirstVT.get(x).size(); y++) {
								c[Vt.indexOf(G.get(i).get(j).charAt(t)) + 1][Vt.indexOf(VnFirstVT.get(x).get(y))
										+ 1] = '<';
							}
							if (t + 2 < G.get(i).get(j).length() && Vt.contains(G.get(i).get(j).charAt(t + 2))) {
								c[Vt.indexOf(G.get(i).get(j).charAt(t)) + 1][Vt.indexOf(G.get(i).get(j).charAt(t + 2))
										+ 1] = '=';
							}
						} else if (t + 1 < G.get(i).get(j).length() && Vt.contains(G.get(i).get(j).charAt(t + 1))) {
							c[Vt.indexOf(G.get(i).get(j).charAt(t)) + 1][Vt.indexOf(G.get(i).get(j).charAt(t + 1))
									+ 1] = '=';
						}

					}
				}
				j++;
			}
			i++;
		}
		for (i = 0; i < N; i++) {
			for (j = 0; j < N; j++) {
				System.out.print(c[i][j]);
				System.out.print('\t');
			}
			System.out.println();
			System.out.println();
		}

		return c;
	}

	public static String DataReduction(String s, String s0) {
		int i = 0;
		while (i < s.length()) {
			if (Vt.contains(s.charAt(i))) {
				String ss = "";
				ss += s.charAt(i);
				int x = 0;
				while (x < G.size()) {
					int j = 1;
					while (j < G.get(x).size()) {
						if (G.get(x).get(j).contains(ss)) {
							s0 = s0.replace(s, G.get(x).get(0));
							return s0;
						}
						j++;
					}
					x++;
				}
			}
			i++;
		}
		return s0;

	}

	public static void analysis(char[][] c, String s) {
		String s0 = "#";// 入栈字符
		String s1 = "";// 临时字符串
		int j = 0;// j最后一个终结符在栈中位置,i为输入串当前扫描位置
		int i = 1;
		do {
			if (Vt.contains(s.charAt(i))) {
				if (c[Vt.indexOf(s0.charAt(j)) + 1][Vt.indexOf(s.charAt(i)) + 1] == '>') {
					s1 = "";
					// 从当前位置往前找<
					if (j != s0.length() - 1) {
						s1 = s0.charAt(s0.length() - 1) + s1;
					}
					s1 = s0.charAt(j) + s1;

					while (j > 0) {

						if (Vt.contains(s0.charAt(j - 1))) {

							if (c[Vt.indexOf(s0.charAt(j - 1)) + 1][Vt.indexOf(s0.charAt(j)) + 1] == '<') {
								// s1为将要归约的字符串

								s0 = DataReduction(s1, s0);
								if (s0 == "") {
									return;
								}
								j = s0.length() - 1;
								while (!Vt.contains(s0.charAt(j))) {
									j--;

								}
								System.out.println("规约\t栈中\t" + s0);

								i--;
								break;
							} else {
								s1 = s0.charAt(j - 1) + s1;
								j--;
								continue;
							}
						} else {
							s1 = s0.charAt(j - 1) + s1;
							if (j - 2 >= 0 && Vt.contains(s0.charAt(j - 2))) {
								if (c[Vt.indexOf(s0.charAt(j - 2)) + 1][Vt.indexOf(s0.charAt(j)) + 1] == '<') {
									// s1为将要归约的字符串
									s0 = DataReduction(s1, s0);
									if (s0 == "") {
										return;
									}
									j = s0.length() - 1;
									while (!Vt.contains(s0.charAt(j))) {
										j--;
									}
									System.out.println("规约\t栈中\t" + s0);
									i--;
									break;
								} else {
									s1 = s0.charAt(j - 2) + s1;
									j -= 2;
									continue;
								}
							} else
								System.out.println("error!");
						}

					}
				} else if (c[Vt.indexOf(s0.charAt(j)) + 1][Vt.indexOf(s.charAt(i)) + 1] == '<'
						|| c[Vt.indexOf(s0.charAt(j)) + 1][Vt.indexOf(s.charAt(i)) + 1] == '=') {
					s0 += s.charAt(i);
					System.out.println("移进\t栈中:\t" + s0);
					j = s0.length() - 1;
				} else {
					System.out.println("error!");
					return;
				}

			} else {
				s0 += s.charAt(i);
				System.out.println("移进\t栈中:\t" + s0);

			}
			i++;
		} while (s.charAt(i - 1) != '#');
		if (s0.length() == 3) {
			System.out.println("接受");
		}

	}

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		by02file bf = new by02file();
		bf.getStr();
		VnAndVt(bf);
		System.out.println("文法非终结符:" + Vn);

		System.out.println("文法终结符:" + Vt);
		FirstVT();
		LastVT();
		N = Vt.size() + 1;
		char[][] c = new char[N][N];
		c = Table();
		
		Scanner sc = new Scanner(System.in);
		String s = sc.nextLine();
		s = "#" + s + "#";
		analysis(c, s);

//		System.out.println(Vn);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值