public int threeaddresscount = 1;//三地址行标 public void symboltable(Node n) { switch (n.type) { case "program": symboltable(n.getChilds()[0]); break; case "compoundstmt": symboltable(n.getChilds()[1]); break; case "stmts": if (n.hasChild()) { if (n.getChilds().Count == 2) { symboltable(n.getChilds()[0]); symboltable(n.getChilds()[1]); } else if (n.getChilds().Count == 1) { symboltable(n.getChilds()[0]); } } break; case "stmt": symboltable(n.getChilds()[0]); break; case "decl": symboltable(n.getChilds()[0]); n.symboltype = n.getChilds()[0].getChilds()[0].symboltype; n.getChilds()[1].symboltype = n.symboltype; symboltable(n.getChilds()[1]); break; case "list": if (n.getChilds().Count == 2) { n.getChilds()[0].symboltype = n.symboltype; n.getChilds()[1].symboltype = n.symboltype; } else { n.getChilds()[0].symboltype = n.symboltype; } if (n.getChilds()[0].type == "ID") { bool redesign = false;//判断重复声明,重复为true for (int m = 0; m < symbolTableCount; m++) { if (n.getChilds()[0].symbolname == symbolTableName[m]) { redesign = true; symbolTableType[m] = "重复声明"; symbolTableValue[m] = ""; symbolTableLineNo[m] = ""; symbolTableColumnNo[m] = ""; } } if (!redesign) { symbolTableName[symbolTableCount] = n.getChilds()[0].symbolname; symbolTableType[symbolTableCount] = n.getChilds()[0].symboltype; symbolTableValue[symbolTableCount] = "未赋值"; symbolTableLineNo[symbolTableCount] = n.getChilds()[0].lineNo; symbolTableColumnNo[symbolTableCount] = n.getChilds()[0].columnNo; symbolTableCount++; } } symboltable(n.getChilds()[1]); break; case "list1": if (n.getChilds().Count == 2) { n.getChilds()[0].symboltype = n.symboltype; n.getChilds()[1].symboltype = n.symboltype; symboltable(n.getChilds()[1]); } else { n.getChilds()[0].symboltype = n.symboltype; symboltable(n.getChilds()[0]); } if (n.getChilds()[0].type == "ID") { bool redesign = false; //判断重复声明,重复为true for (int m = 0; m < symbolTableCount; m++) { if (n.getChilds()[0].symbolname == symbolTableName[m]) { redesign = true; symbolTableType[m] = "重复声明"; symbolTableValue[m] = ""; symbolTableLineNo[m] = ""; symbolTableColumnNo[m] = ""; } } if (!redesign) { symbolTableName[symbolTableCount] = n.getChilds()[0].symbolname; symbolTableType[symbolTableCount] = n.getChilds()[0].symboltype; symbolTableValue[symbolTableCount] = "未赋值"; symbolTableLineNo[symbolTableCount] = n.getChilds()[0].lineNo; symbolTableColumnNo[symbolTableCount] = n.getChilds()[0].columnNo; symbolTableCount++; } } break; case "assgstmt": symboltable(n.getChilds()[2]); n.getChilds()[0].symbolvalue = n.getChilds()[2].symbolvalue; bool occur = false; //判断是否为赋值但没声明 for (int m = 0; m < symbolTableCount; m++) { if (n.getChilds()[0].symbolname == symbolTableName[m]) occur = true; } if (!occur) { symbolTableName[symbolTableCount] = n.getChilds()[0].symbolname; symbolTableType[symbolTableCount] = "未声明"; symbolTableValue[symbolTableCount] = ""; symbolTableLineNo[symbolTableCount] = ""; symbolTableColumnNo[symbolTableCount] = ""; symbolTableCount++; } else { //判断赋值类型是否一致 bool judge = false;//判断是否值为小数,小数为true for (int l = 0; l < n.getChilds()[0].symbolvalue.Length; l++) if (n.getChilds()[0].symbolvalue[l] == '.') judge = true; if (n.getChilds()[2].symboltype == "real") judge = true; if (judge) { for (int m = 0; m < symbolTableCount; m++) { if (n.getChilds()[0].symbolname == symbolTableName[m] && symbolTableType[m] == "int") { symbolTableType[m] = "类型不匹配"; symbolTableValue[m] = ""; symbolTableLineNo[m] = ""; symbolTableColumnNo[m] = ""; } if (n.getChilds()[0].symbolname == symbolTableName[m] && symbolTableType[m] == "real") { symbolTableValue[m] = n.getChilds()[0].symbolvalue; } } } else { for (int m = 0; m < symbolTableCount; m++) { if (n.getChilds()[0].symbolname == symbolTableName[m]) { symbolTableValue[m] = n.getChilds()[0].symbolvalue; } } } } break; case "arithexpr": //对直接赋值和运算赋值分别讨论 symboltable(n.getChilds()[0]); symboltable(n.getChilds()[1]); if (n.hasChild()) { if (n.getChilds()[1].getChilds().Count == 1) { n.symboltype = n.getChilds()[0].symboltype; n.symbolvalue = n.getChilds()[0].symbolvalue; } else if (n.getChilds()[1].getChilds().Count == 3) { bool occurleft=false; bool occurright=false; for (int m = 0; m < symbolTableCount; m++) { if (n.getChilds()[0].symbolname == symbolTableName[m]) { n.getChilds()[0].symboltype = symbolTableType[m]; occurleft=true; } if (n.getChilds()[1].symbolname == symbolTableName[m]) { n.getChilds()[1].symboltype = symbolTableType[m]; occurright=true; } } if( occurleft&&occurright) { if (n.getChilds()[0].symboltype == "int" && n.getChilds()[1].symboltype == "int") n.symboltype = "int"; if (n.getChilds()[0].symboltype == "int" && n.getChilds()[1].symboltype == "real") n.symboltype = "real"; if (n.getChilds()[0].symboltype == "real" && n.getChilds()[1].symboltype == "int") n.symboltype = "real"; if (n.getChilds()[0].symboltype == "real" && n.getChilds()[1].symboltype == "real") n.symboltype = "real"; } } } break; case "multexpr": symboltable(n.getChilds()[0]); n.symbolname = n.getChilds()[0].symbolname; n.symboltype = n.getChilds()[0].symboltype; n.symbolvalue = n.getChilds()[0].symbolvalue; break; case "simpleexpr": symboltable(n.getChilds()[0]); n.symbolname = n.getChilds()[0].symbolname; n.symboltype = n.getChilds()[0].symboltype; n.symbolvalue = n.getChilds()[0].symbolvalue; break; case "arithexprprime": if (n.getChilds().Count == 3) { symboltable(n.getChilds()[1]); symboltable(n.getChilds()[2]); n.symbolname = n.getChilds()[1].symbolname; } break; default: break; } }
public void threeaddress(Node n) { switch (n.type) { case "program": threeaddress(n.getChilds()[0]); threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":"; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; break; case "compoundstmt": threeaddress(n.getChilds()[1]); break; case "stmts": if (n.getChilds().Count == 2) { threeaddress(n.getChilds()[0]); threeaddress(n.getChilds()[1]); } else { threeaddress(n.getChilds()[0]); } break; case "stmt": threeaddress(n.getChilds()[0]); tempcount = 0; break; case "assgstmt": threeaddress(n.getChilds()[2]); threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "MOV" + " " + n.getChilds()[0].name + "," + "," + n.getChilds()[2].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; break; case "arithexpr": threeaddress(n.getChilds()[0]); threeaddress(n.getChilds()[1]); if (n.getChilds()[1].getChilds()[0].type=="empty") { n.value = n.getChilds()[0].value; } else { n.value = temppro(); tempcount++; } if (n.getChilds()[1].getChilds()[0].name == "+") { threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "ADD" + " " + n.value + "," + n.getChilds()[0].name + "," + n.getChilds()[1].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } else if (n.getChilds()[1].getChilds()[0].name == "-") { threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "SUB" + " " + n.value + "," + n.getChilds()[0].name + "," + n.getChilds()[1].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } break; case "multexpr": threeaddress(n.getChilds()[0]); threeaddress(n.getChilds()[1]); if (n.getChilds()[1].getChilds().Count == 1) { n.value = n.getChilds()[0].value; n.name = n.getChilds()[0].name; } if (n.getChilds()[1].getChilds().Count == 3) { n.value = temppro(); tempcount++; if (n.getChilds()[1].getChilds()[0].name == "/") { threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "DIV" + " " + n.value + "," + n.getChilds()[0].name + "," + n.getChilds()[1].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } else if (n.getChilds()[1].getChilds()[0].name == "*") { threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "MUL" + " " + n.value + "," + n.getChilds()[0].name + "," + n.getChilds()[1].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } } break; case "arithexprprime": if (n.getChilds().Count == 3) { threeaddress(n.getChilds()[1]); threeaddress(n.getChilds()[2]); n.value = n.getChilds()[1].value; n.name = n.getChilds()[1].name; } else { threeaddress(n.getChilds()[0]); } break; case "simpleexpr": if (n.getChilds().Count == 3) { threeaddress(n.getChilds()[1]); n.value = n.getChilds()[1].value; } else { threeaddress(n.getChilds()[0]); n.value = n.getChilds()[0].name; n.name = n.getChilds()[0].name; } break; case "multexprprime": if (n.getChilds().Count == 3) { threeaddress(n.getChilds()[1]); threeaddress(n.getChilds()[2]); n.name = n.getChilds()[1].name; n.value = n.getChilds()[1].value; } else { threeaddress(n.getChilds()[0]); } break; case "ifstmt": threeaddress(n.getChilds()[2]); threeaddress(n.getChilds()[5]); threeaddress(n.getChilds()[6]); threeaddress(n.getChilds()[7]); elseend = threeaddresscount; threeaddressshow[elsestart] = threeaddressshow[elsestart] + Convert.ToString(elseend); break; case "whilestmt": threeaddress(n.getChilds()[2]); threeaddress(n.getChilds()[4]); threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMP" + " " + "," + ","+Convert.ToString(whilestart); n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; threeaddressshow[(whilestart + 1)] = threeaddressshow[whilestart + 1] + Convert.ToString(threeaddresscount); break; case "decl": threeaddress(n.getChilds()[0]); threeaddress(n.getChilds()[1]); break; case "type": threeaddress(n.getChilds()[0]); break; case "list": threeaddress(n.getChilds()[1]); break; case "list1": if (n.getChilds().Count == 2) { threeaddress(n.getChilds()[1]); } else { threeaddress(n.getChilds()[0]); } break; case "boolexpr": threeaddress(n.getChilds()[0]); threeaddress(n.getChilds()[1]); threeaddress(n.getChilds()[2]); if(n.getChilds()[1].getChilds()[0].type=="<") { n.value = temppro(); tempcount++; whilestart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "LES" + " " + n.value + "," + n.getChilds()[0].value + "," + n.getChilds()[2].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; thenstart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMPF" + " " + n.value + "," + ","; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } else if (n.getChilds()[1].getChilds()[0].type == ">") { n.value = temppro(); tempcount++; whilestart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "GTR" + " " + n.value + "," + n.getChilds()[0].value + "," + n.getChilds()[2].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; thenstart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMPF" + " " + n.value + "," + ","; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } else if (n.getChilds()[1].getChilds()[0].type == "<=") { n.value = temppro(); tempcount++; whilestart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "LEQ" + " " + n.value + "," + n.getChilds()[0].value + "," + n.getChilds()[2].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; thenstart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMPF" + " " + n.value + "," + ","; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } else if (n.getChilds()[1].getChilds()[0].type == ">=") { n.value = temppro(); tempcount++; whilestart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "GEQ" + " " + n.value + "," + n.getChilds()[0].value + "," + n.getChilds()[2].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; thenstart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMPF" + " " + n.value + "," + ","; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } else if (n.getChilds()[1].getChilds()[0].type == "==") { n.value = temppro(); tempcount++; whilestart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "EQL" + " " + n.value + "," + n.getChilds()[0].value + "," + n.getChilds()[2].value; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; thenstart = threeaddresscount; threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMPF" + " " + n.value + "," + ","; n.name = threeaddressshow[threeaddresscount]; threeaddresscount++; } break; case "boolop": threeaddress(n.getChilds()[0]); break; case "else": threeaddressshow[threeaddresscount] = Convert.ToString(threeaddresscount) + ":" + " " + "JMP" + " " + "," + ","; n.name = threeaddressshow[threeaddresscount]; elsestart = threeaddresscount; threeaddresscount++; threeaddressshow[thenstart] = threeaddressshow[thenstart] + Convert.ToString(threeaddresscount); break; default: break; } }
//过程栈和输入栈进行怼的过程,treestack为过程栈,b为输入栈 public void match(Stack<string[]> b, GrammarSheet c, int nResult/*判定是否是文件结束*/) { int[] errorshowrow = new int[100];//显示错误所在的行 c.outcount = -1;//每次进入match函数,序号初始化为-1 //p,q用于输出两个栈的内容 Stack<Node> p = new Stack<Node>(); Stack<string[]> q = new Stack<string[]>(); Stack<Node> r = new Stack<Node>();//用于反向输出的保存 while (!(treestack.Count == 0)) { c.outcount++;//process,inout,action的计数+1 //清空process,input,action使得每多读一个token都不是在原来的输出中写内容 c.process[outcount] = ""; c.input[outcount] = ""; c.action[outcount] = ""; //p,q用于输出两个栈的内容 p = new Stack<Node>(treestack); q = new Stack<string[]>(b); while (!(p.Count == 0)) { if (p.Peek().type != "empty") r.Push(p.Peek()); p.Pop(); } while (!(r.Count == 0)) { if (r.Peek().type != "") c.process[c.outcount] = c.process[c.outcount] + r.Peek().type + " ";//用字符串m获取过程栈中字符串 r.Pop(); } c.process[c.outcount] = c.process[c.outcount];//空一行 // printf("%-30s", m.c_str()); while (!(q.Count == 0)) { if (q.Peek()[2] != "empty") c.input[c.outcount] = c.input[c.outcount] + q.Peek()[2] + " ";//用字符串n获取输入栈中字符串 q.Pop(); } c.input[c.outcount] = c.input[c.outcount]; // printf("%-30s", n.c_str()); //把empty符号删除,因为empty表示空 if (treestack.Peek().type == "empty") { treestack.Pop(); } if (b.Peek()[2] == "empty") { b.Pop(); } //如果某个栈只剩$了,而另一个不可能变成$,那么就结束并报错 if ((treestack.Peek().type == "$" && b.Peek()[2] != "$") || (treestack.Peek().type != "$" && b.Peek()[2] == "$")) { c.action[c.outcount] = c.action[c.outcount] + "该语句出错"; c.programright = false; break; } //当两个栈的栈顶不同时 if (treestack.Peek().type != b.Peek()[2]) { Production k = Grammarsheet_Return_Production(treestack.Peek().type, b.Peek()[2], c); //假如能在符号表中找到生成式,说明分析过程还是正确的 if (k.productionSubstring[0] != "error" && k.productionSubstring[0] != "synch") { //构建临时list临时存放生成式的node,用于反向放入treestack中 List<Node> temp = new List<Node>(); //输出动作 c.action[c.outcount] = c.action[c.outcount] + "输出 "; c.action[c.outcount] = c.action[c.outcount] + Grammarsheet_Return(treestack.Peek().type, b.Peek()[2], c); //构建list Production currentproduction = Grammarsheet_Return_Production(treestack.Peek().type, b.Peek()[2], c); for (int i = 2; i < 10; i++) { if (currentproduction.productionSubstring[i] != "" && currentproduction.productionSubstring[i] != null) { //获取当前孩子节点中的某个 Node currentnode = new Node("", currentproduction.productionSubstring[i], "", "", ""); temp.Add(currentnode);// //取栈顶作为父节点来加入他的孩子 Node tmpnode = treestack.Peek(); tmpnode.Add(currentnode); //计算当前节点所在的层 currentnode.layer = tmpnode.layer + 1; //计算list的高 if (currentnode.layer >= treeroot.layerheight) treeroot.layerheight = currentnode.layer; } } treestack.Pop(); //treestack放入生成式节点 for (int i = temp.Count - 1; i >= 0; i--) { if (k.productionSubstring[i] != "" && k.productionSubstring[i] != null) { treestack.Push(temp[i]); } } //清空临时list temp.Clear(); } //如果没有对应的生成式,则弹出输入栈中最上方的字符并报错 else if (k.productionSubstring[0] == "error") { //输出动作 c.action[c.outcount] = c.action[c.outcount] + "出错"; c.errorshow = c.errorshow + "第" + b.Peek()[4] + "行 " + "缺少或多余" +found(b.Peek()[2],c)+ "\r\n" + "\r\n"; c.programright = false; b.Pop(); } //如果对应的生成式为错误处理,则弹出过程栈中最上方的非终结符并报错 else if (k.productionSubstring[0] == "synch") { //输出动作 c.action[c.outcount] = c.action[c.outcount] + "出错"; c.errorshow = c.errorshow + "第" + b.Peek()[4] + "行 " + "缺少或多余" +found(b.Peek()[2],c)+ "\r\n" + "\r\n"; c.programright = false; treestack.Pop(); } } //两个栈的栈顶相同 else if (treestack.Peek().type == b.Peek()[2]) { treestack.Peek().name = b.Peek()[1]; treestack.Peek().symbolname = b.Peek()[1]; treestack.Peek().value = b.Peek()[3]; treestack.Peek().symbolvalue = b.Peek()[3]; treestack.Peek().lineNo = b.Peek()[4]; treestack.Peek().columnNo = b.Peek()[5]; if (treestack.Peek().type == "}") { c.action[c.outcount] = c.action[c.outcount] + "匹配 " + treestack.Peek().type + "该句子正确"; } else { c.action[c.outcount] = c.action[c.outcount] + "匹配 " + treestack.Peek().type; } treestack.Pop(); b.Pop(); } } }
//加子节点 public void Add(Node n) { if (childs == null) childs = new List<Node>(); childs.Add(n); }
//初始化过程栈 public void Process_Stack_Initialize(ref Stack<Node> a) { //每次进入match函数,树根都要初始化 headfore = new Node("", "$", "", "", ""); treeroot = new Node("", "program", "", "", ""); headfore.Add(treeroot);//list初始化 //stack初始化 a.Push(headfore); a.Push(treeroot); }