算符优先-------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);
}
}