java ll1文法分析_编译原理LL1文法分析表算法实现

该博客详细介绍了如何使用Java实现LL1文法分析表,包括构造分析表、预测分析以及生成分析树的过程。通过First集、Follow集的计算,结合文法构建分析表,并进行预测分析,最后展示分析树的先序遍历。
摘要由CSDN通过智能技术生成

importhjzgg.first.First;importhjzgg.follow.Follow;importhjzgg.tablenode.TableNode;importhjzgg.treenode.TreeNode;importjava.util.ArrayList;importjava.util.LinkedHashMap;importjava.util.Map;importjava.util.Set;importjava.util.Stack;importjava.util.TreeMap;importjava.util.TreeSet;public classAnalysisTable {private final int noFinalCharacterCount = 100;private MapstringToInt = new TreeMap();//分析表行 列 字母映射到数字

private MaptableRow = new TreeMap();//分析表 行列 数字 映射到字母

private MaptableCol = new TreeMap();private String[][] table = new String[noFinalCharacterCount][];//分析表

private SetterminalCharacters = new TreeSet();//终结符集合

private Map> first = null;private Map> follow = null;private Map mp = null;private int nodeCntRow = 0, nodeCntCol=0;public static final int treeNodeCnt = 200;//树最多节点的个数

private int cntTreeNode = 0;private ArrayList usedProduction = new ArrayList();//预测分析中所用到的产生式

private int fatherNode;//treeGraphic搜素是的开始节点

private TreeNode[] treeGraphic = newTreeNode[treeNodeCnt];private String[] analysisStack = null;publicString[] getAnalysisStack(){returnanalysisStack;

}public MapgetStringToInt(){returnstringToInt;

}public SetgetTerminalCharacters(){returnterminalCharacters;

}public intgetFatherNode(){returnfatherNode;

}publicTreeNode[] getTreeGraphic(){returntreeGraphic;

}public AnalysisTable(Map>first,

Map> follow, Mapmp) {super();this.first =first;this.follow =follow;this.mp =mp;

init();

}private voidinit(){for(String leftNode : mp.keySet()){

stringToInt.put(leftNode,++nodeCntRow);

tableRow.put(nodeCntRow, leftNode);

String[] rightNodes=mp.get(leftNode);for(int i=0; i

for(int j=0; j

if(!stringToInt.containsKey(""+rightNodes[i].charAt(j))){

stringToInt.put(""+rightNodes[i].charAt(j), ++nodeCntCol);

terminalCharacters.add(rightNodes[i].charAt(j));

tableCol.put(nodeCntCol,""+rightNodes[i].charAt(j));

}

}

}

}

stringToInt.put("#", ++nodeCntCol);

tableCol.put(nodeCntCol,"#");

terminalCharacters.add('#');

}public ArrayListanalysisTableKernealCode(){for(String leftNode : mp.keySet()){

String[] rightNodes=mp.get(leftNode);for(int i=0; i

for(Character terminal : terminalCharacters){//每一个终结符

char finalCharacter =terminal;

Set productionFirstSet = new TreeSet();//产生式对应first集

for(int k=0; k

String node= ""+rightNodes[i].charAt(k);if(k+1 < rightNodes[i].length() && rightNodes[i].charAt(k+1)=='\''){

node+= '\'';++k;

}if(mp.containsKey(node)){//非终结符

productionFirstSet.addAll(first.get(node));if(!first.get(node).contains('$')) break;

}else {//终结符

productionFirstSet.add(node.charAt(0));break;

}

}if(productionFirstSet.contains(finalCharacter)){//A->@ 对于每一个终结符 a属于FIRST(@),加入M[A, a]

int col = stringToInt.get(""+finalCharacter);int row =stringToInt.get(leftNode);if(table[row]==null)

table[row]= new String[nodeCntCol+1];

table[row][col]= leftNode + "->" +rightNodes[i];

}/***********************************************************************/

else if(productionFirstSet.contains('$')){//A->@ 对于$属于First(@),对任何b属于Follow(A)则把A->@加入

if(follow.get(leftNode).contains(finalCharacter)){int col = stringToInt.get(""+finalCharacter);int row =stringToInt.get(leftNode);if(table[row]==null)

table[row]= new String[nodeCntCol+1];

table[row][col]= leftNode + "->" +rightNodes[i];

}

}

}

}

}returnprintTalbe();

}public ArrayListprintTalbe(){

ArrayList tableNodeAl = new ArrayList();

System.out.println("分析表如下:");for(int i=1; i<=nodeCntRow; ++i){for(int j=1; j<=nodeCntCol; ++j)if(table[i]!=null && table[i][j]!=null){

tableNodeAl.add(newTableNode(i, j, table[i][j]));

System.out.println(tableRow.get(i)+ ":" + tableCol.get(j) + " " +table[i][j]);

}

}returntableNodeAl;

}public booleanpredictiveAnalysis(String formula){

ArrayListstringStack = new ArrayList();

System.out.println("开始进行预测分析,分析栈如下:");

Stack stack = new Stack();

stack.push("#");

stack.push(tableRow.get(1));int formulaIndex = 0;char a = formula.charAt(formulaIndex++);boolean flag = false;while(true){if(stack.size() == 0){//error

break;

}

stringStack.add(stack.toString());

System.out.println(stack);

String x=stack.pop();if(!mp.containsKey(x)){//终结符

if(x.charAt(0)==a){if(a=='#'){

flag= true;break;

}

a= formula.charAt(formulaIndex++);

}else{//error

}

}else {//非终结符

if(table[stringToInt.get(x)] != null){

String production= table[stringToInt.get(x)][stringToInt.get(""+a)];if(production != null){

usedProduction.add(production);if(!production.contains("$")){//X->X1X2X3....Xk 中 Xk....X3X2X1压入栈中

for(int i=production.length()-1; i>=0; --i){if(production.charAt(i)=='>') break;if(production.charAt(i)=='\''){

stack.push(""+production.charAt(i-1)+production.charAt(i));--i;

}else{

stack.push(""+production.charAt(i));

}

}

}

}else{//error

}

}else{//error

}

}

}

analysisStack= stringStack.toArray(newString[stringStack.size()]);returnflag;

}private int produceAnalysisTree(intcurRow, String preNode){

String curProduction=usedProduction.get(curRow);

String splits[]= curProduction.split("->");if(preNode != null && !preNode.equals(splits[0]))return produceAnalysisTree(curRow+1, preNode);

TreeNode treeNode= newTreeNode();

treeNode.content= splits[0];for(int i=0; i

String node = "" + splits[1].charAt(i);if(i+1

node+= '\'';++i;

}if(!mp.containsKey(node)){//不是 非终结点

TreeNode tmpTreeNode = newTreeNode();

tmpTreeNode.content=node;

treeNode.child.add(cntTreeNode);//加入孩子节点

treeGraphic[cntTreeNode++] =tmpTreeNode;

}else {//非终结点

int childNodeCnt = produceAnalysisTree(curRow+1, node);//得到这个孩子的节点

treeNode.child.add(childNodeCnt);

}

}

treeGraphic[cntTreeNode]=treeNode;return cntTreeNode++;

}private void printAnalysisTree(intcurNode){

System.out.print(" " +treeGraphic[curNode].content);for(int i=0; i

printAnalysisTree(treeGraphic[curNode].child.get(i));

}public voidAnalysisTree(){

fatherNode= produceAnalysisTree(0, null);

System.out.println("分析树的先序遍历如下:");

printAnalysisTree(fatherNode);

}public static voidmain(String[] args) {//String[] rightLinearGrammar ={//"S->iCtSA|a",//"A->$|eS",//"C->b"//};

String[] rightLinearGrammar={"E->TE\'","E\'->+TE\'|$","T->FT\'","T\'->*FT\'|$","F->(E)|i"};//String[] rightLinearGrammar = {//"S->ABc",//"A->a|$",//"B->b|$"//};

Map mp = new LinkedHashMap();try{for(int i=0; i

String split1[]= rightLinearGrammar[i].split("->");

String split2[]= split1[1].split("\\|");

mp.put(split1[0], split2);

}

}catch(Exception e){

e.printStackTrace();

System.out.println("右线性文法错误!");

}

First first= newFirst(mp);

first.firstKernealCode();

Follow follow= newFollow(mp, first.getFirstSet());

follow.followKernealCode();

AnalysisTable analysisTable= newAnalysisTable(first.getFirstSet(), follow.getFollowSet(), mp);

analysisTable.analysisTableKernealCode();

analysisTable.predictiveAnalysis("i+i#");

analysisTable.AnalysisTree();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值