版权声明:本文为博主原创文章,未经博主允许不得转载。如果你非要转载,麻烦加上我的原网址,谢谢。http://blog.csdn.net/qinglingLS https://blog.csdn.net/qinglingLS/article/details/89819958
接上面的几篇博文:
【HIT哈工大编译原理实验】词法分析程序java
【编译原理】求first集合的代码实现java
【编译原理】求GOTO图的代码实现java
【编译原理】LL(1)分析法代码
以及一些关于编译的说明博客……自己按照日期找一下把~!
接下来就要做一些比较激动的事情了~!
目标文法:
S' -> S
S -> C C
C -> c C|d
为了构造一个如图中4-40的表,代码实现如下:
先展示一下效果:
action表
goto表:
构造完这两个表之后,就只需要读字符,然后解析就可以了,读取词流已经在词法分析器里面做好了:
算法如下:
代码如下:
ActionTable.java
package parse2;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class ActionTable {
int line;// 列
int row;// 行
String[][] aStrings;
List<Production> proList;
Map<GoTo, String> gotoMap;
Map<String, LRClosure> lrMap;
List<String> victs;
public ActionTable(List<Production> productionList, Map<GoTo, String> gotoMap,
Map<String, LRClosure> lrMap) {
proList = productionList;
this.gotoMap = gotoMap;
this.lrMap = lrMap;
row = lrMap.size() + 1;
victs = getVicts();
line = victs.size() + 1;
aStrings = new String[row][line];
for (int i = 0; i < row; i++) {
for (int j = 0; j < line; j++) {
aStrings[i][j] = ".";
}
}
for (int i = 1; i < victs.size() + 1; i++) {
aStrings[0][i] = victs.get(i - 1);
}
int i = 1;
for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
.hasNext();) {
String setName = (String) iterator.next();
aStrings[i][0] = setName;
i++;
}
}
/**
* 获取全部终结符
* @return
*/
public List<String> getVicts() {
List<String> victs = new ArrayList<>();
victs.add("$");
for (Iterator<Production> iterator = proList.iterator(); iterator
.hasNext();) {
Production production = (Production) iterator.next();
for (int i = 0; i < production.getRight().length; i++) {
if (!isVariable(production.getRight()[i])
&& !victs.contains(production.getRight()[i])) {
victs.add(production.getRight()[i]);
}
}
}
return victs;
}
/**
* 判断是不是终结符,如果左边没这个作为开头的,那就是终结符了。
* @param str
* @param proList
* @return
*/
public boolean isVariable(String str) {
for (Iterator<Production> iterator = proList.iterator(); iterator
.hasNext();) {
Production production = (Production) iterator.next();
if (production.getLeft().equals(str)) {
// 一旦找到左边有等于str的字符,就说明str不算终结符,返回真:是变量
return true;
}
}
return false;
}
/**
* 设置动作表
* @param gotoMap
* @param lrMap
*/
public void setActionTable() {
System.out.println(gotoMap);
System.out.println(lrMap);
for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
.hasNext();) {
String setName = (String) iterator.next();
LRClosure tmp = lrMap.get(setName);
System.out.println(setName);
for (Iterator<Item> iterator2 = tmp.items.iterator(); iterator2
.hasNext();) {
System.out.println("ActionTable.setActionTable()");
Item item = (Item) iterator2.next();
System.out.println(item);
System.out.println("----------------------------------------");
System.out.println(item.getB());
if (item.getB().equals("") && !item.getLeft().equals("S'")) {
// 如果[A->alpha·,a]在Ii里,而且A!=S’,那么将Action[i,a]设置为规约A->alpha
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < item.getAlpha().length; i++) {
stringBuffer.append(item.getAlpha()[i]);
}
for (int i = 0; i < item.getA().length; i++) {
if (!setTable(setName, item.getA()[i],
"r" + item.getLeft() + "->" + stringBuffer.toString())) {
throw new Error("规约表设置出现了错误!!产生了语义冲突!!!!");
}
}
} else if (item.getLeft().equals("S'") && item.getB().equals("")
&& item.setCheckAcc()) {
setTable(setName, "$", "ACC");
} else if (victs.contains(item.getB())) {// 如果不是变量,就去找goto表
// 查找有没有GoTo(Ii,a)=Ij,有的话就把action[i,a]设置为移入j,sj
String result = findGotoTable(setName, item.getB());
System.out.println("????????????????????");
System.out.println(result);
if (!result.equals("")) {
// 把action[i,a]设置为移入j,sj
if (!setTable(setName, item.getB(), "s" + result)) {
throw new Error("移入表设置出现了错误!!产生了语义冲突!!!!");
}
}
}
}
}
}
/**
* 选定i,a对table进行赋值
* @param i
* @param a
* @param sj
* @return
*/
public boolean setTable(String i, String a, String sj) {
// System.out.println(i);
// System.out.println(a);
// System.out.println(sj);
int y = 0;
int x = 0;
for (int j = 0; j < line; j++) {
if (a.equals(aStrings[0][j])) {
y = j;
}
}
for (int j = 0; j < row; j++) {
if (i.equals(aStrings[j][0])) {
x = j;
}
}
// System.out.println(y);
// System.out.println(x);
if (aStrings[x][y].equals(".")) {
aStrings[x][y] = sj;
return true;
}
return false;
}
/**
* 查找goto表有没有这个关系,有返回true,没有返回false;
* @param Ii
* @param a
* @param Ij
* @return
*/
public String findGotoTable(String Ii, String a) {
for (Iterator<GoTo> iterator = gotoMap.keySet().iterator(); iterator
.hasNext();) {
GoTo goto_tmp = (GoTo) iterator.next();
if (goto_tmp.closureID.equals(Ii) && goto_tmp.path.equals(a)) {
return new String(gotoMap.get(goto_tmp));
}
}
return "";
}
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < row; i++) {
for (int j = 0; j < line; j++) {
stringBuffer.append(aStrings[i][j] + " ");
}
stringBuffer.append("\n");
}
return stringBuffer.toString();
}
public static void main(String[] args) {
ProductionList productionList = new ProductionList();
ItemTable itemTable = new ItemTable(productionList);
itemTable.setItemSet(itemTable.lrClosure, "I0");
ActionTable actionTable = new ActionTable(productionList.getProductions(),
itemTable.gotoMap, itemTable.map);
System.out.println(actionTable.toString());
actionTable.setActionTable();
System.out.println(actionTable.toString());
}
}
GoToTable.java
package parse2;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class GoToTable {
int line;// 列
int row;// 行
String[][] aStrings;
List<Production> proList;
Map<GoTo, String> gotoMap;
Map<String, LRClosure> lrMap;
List<String> variables;
public GoToTable(List<Production> productionList, Map<GoTo, String> gotoMap,
Map<String, LRClosure> lrMap) {
proList = productionList;
this.gotoMap = gotoMap;
this.lrMap = lrMap;
row = lrMap.size() + 1;
variables = getVariables();
line = variables.size() + 1;
aStrings = new String[row][line];
for (int i = 0; i < row; i++) {
for (int j = 0; j < line; j++) {
aStrings[i][j] = ".";
}
}
for (int i = 1; i < variables.size() + 1; i++) {
aStrings[0][i] = variables.get(i - 1);
}
int i = 1;
for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
.hasNext();) {
String setName = (String) iterator.next();
aStrings[i][0] = setName;
i++;
}
}
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < row; i++) {
for (int j = 0; j < line; j++) {
stringBuffer.append(aStrings[i][j] + " ");
}
stringBuffer.append("\n");
}
return stringBuffer.toString();
}
/**
* 获取全部变量
* @return
*/
public List<String> getVariables() {
List<String> victs = new ArrayList<>();
for (Iterator<Production> iterator = proList.iterator(); iterator
.hasNext();) {
Production production = (Production) iterator.next();
for (int i = 0; i < production.getRight().length; i++) {
if (isVariable(production.getRight()[i])
&& !victs.contains(production.getRight()[i])) {
victs.add(production.getRight()[i]);
}
}
}
return victs;
}
/**
* 判断是不是终结符,如果左边没这个作为开头的,那就是终结符了。
* @param str
* @param proList
* @return
*/
public boolean isVariable(String str) {
for (Iterator<Production> iterator = proList.iterator(); iterator
.hasNext();) {
Production production = (Production) iterator.next();
if (production.getLeft().equals(str)) {
// 一旦找到左边有等于str的字符,就说明str不算终结符,返回真:是变量
return true;
}
}
return false;
}
/**
* 如果GOTO(Ii,A)=Ij,那么GOTO[i,A]=j
*/
public void setGotoTable() {
for (Iterator<GoTo> iterator = gotoMap.keySet().iterator(); iterator
.hasNext();) {
GoTo goTo = (GoTo) iterator.next();
if (variables.contains(goTo.getPath())) {
// 如果是变量的话
if (!setTable(goTo.getClosureID(), goTo.getPath(), gotoMap.get(goTo))) {
throw new Error("goto设置出现了错误!!产生了冲突!!!!");
} ;
}
}
}
/**
* 选定i,a对table进行赋值
* @param i
* @param a
* @param sj
* @return
*/
public boolean setTable(String i, String a, String sj) {
// System.out.println(i);
// System.out.println(a);
// System.out.println(sj);
int y = 0;
int x = 0;
for (int j = 0; j < line; j++) {
if (a.equals(aStrings[0][j])) {
y = j;
}
}
for (int j = 0; j < row; j++) {
if (i.equals(aStrings[j][0])) {
x = j;
}
}
// System.out.println(y);
// System.out.println(x);
if (aStrings[x][y].equals(".")) {
aStrings[x][y] = sj;
return true;
}
return false;
}
public static void main(String[] args) {
ProductionList productionList = new ProductionList();
ItemTable itemTable = new ItemTable(productionList);
itemTable.setItemSet(itemTable.lrClosure, "I0");
GoToTable goToTable = new GoToTable(productionList.getProductions(),
itemTable.gotoMap, itemTable.map);
System.out.println(goToTable.toString());
goToTable.setGotoTable();
System.out.println(goToTable.toString());
}
}