var Syntax = { index :0, word :new Token(), root :new Node(), lineNubmer :1, readall :false,// 是否读取完所有 error :"", tableList :new Array(), table :new SymTable(), mainTable :new SymTable(), item :new SymItem(), nonexistence :new SymItem("nonexistence", SymType_INT, 0), checkStr :'', varInDec :false, varInAss :false, isIndex :false, tempName :"", ifLevel :0, whileLevel :0, expressionVal :1, iIndex :0, instream :new Array(100), inWrite :false, intercode :new Array(), /* 获取最后一个临时存储单元名称 */ getLastReg : function() { return Syntax.intercode[Syntax.intercode.length - 1]; }, /* 在总表中查询某变量,如果找到返回该符号表项,否则返回null */ LookUp : function(s) { for ( var i = Syntax.tableList.length - 1; i >= 0; i--) { if (Syntax.tableList[i].position(s) != null) return Syntax.tableList[i].position(s); } return null; }, /* 检查变量名冲突。如果存在冲突,则返回false,不存在则返回true */ Check : function(str) { for ( var i = 0; i < Syntax.table.SymItemList.length; ++i) { if (Syntax.table.SymItemList[i].Name == str) { return false; } } return true; }, /* 获得从当前位置开始的第一个表达式*/ getExpressionStr : function() { var expIndex = Syntax.index; var s = "1"; if (expIndex < tokens.length) { s = ""; while (tokens[expIndex].value != ";" && tokens[expIndex].value != "," && tokens[expIndex].value != "=" && tokens[expIndex].value != "{") { if (expIndex < tokens.length) { if (expIndex < tokens.length) { s += (tokens[expIndex]).value; } expIndex++; if (expIndex == tokens.length) { break; } } else { break; } } } return s; }, /* 获得从当前位置开始的条件表达式*/ getConditionStr : function() { var count = 0; // 取到一个左括号就减1,取到一个右括号就加1 var conIndex = Syntax.index; var s = "("; if (conIndex < tokens.length) { while (count != 1) { if (conIndex < tokens.length) { if (tokens[conIndex].value == "(") { count--; } if (tokens[conIndex].value == ")") { count++; } s += (tokens[conIndex]).value; conIndex++; } else break; } } return s; }, /* 获得从当前位置开始的数组下标表达式 */ getIndexStr : function() { var count = 0; // 取到一个左括号就减1,取到一个右括号就加1 var conIndex = Syntax.index; var s = ""; if (conIndex < tokens.length) { while (count != 1) { if (conIndex < tokens.length) { if (tokens[conIndex].value == "[") { count--; } if (tokens[conIndex].value == "]") { count++; } s += tokens[conIndex].value; conIndex++; } else break; } } return s; }, /* 求出表达式的值 */ getExpressionValue : function(s) { // 去右端多余小括号 var indexOfLastParen = s.lastIndexOf(')'); if (indexOfLastParen == s.length - 1) { var leftToken = new Array(); leftToken.push("("); var rightToken = new Array(); rightToken.push(")"); var leftCount = s.split(leftToken).length - 1; var rightCount = s.split(rightToken).length - 1; if (leftCount != rightCount) s = s.substring(0, s.length - 1); } // 去右端多余中括号 var indexOfLastBracket = s.lastIndexOf(']'); if (indexOfLastBracket == s.length - 1) { var leftToken = new Array(); leftToken.push("("); var rightToken = new Array(); rightToken.push(")"); var leftCount = s.split(leftToken).length - 1; var rightCount = s.split(rightToken).length - 1; if (leftCount != rightCount) s = s.substring(0, s.length - 1); } ExprCal.init(s); // ///////////////////////////////////////////////////// return ExprCal.Calculate(); }, /* 生成中间代码 */ gen : function(s1, s2, s3, s4) { Syntax.intercode.push(s1); Syntax.intercode.push(s2); Syntax.intercode.push(s3); Syntax.intercode.push(s4); }, /* 初始化语法语义分析 */ init : function() { Syntax.index = 0; Syntax.root = null; Syntax.lineNubmer = 1; Syntax.readall = false; Syntax.error = ""; Syntax.checkStr =''; Syntax.varInDec =false; Syntax.varInAss =false; Syntax.isIndex =false; Syntax.tempName =""; Syntax.ifLevel =0; Syntax.whileLevel =0; Syntax.expressionVal =1; Syntax.iIndex =0; Syntax.instream =new Array(100); Syntax.inWrite =false; Syntax.intercode =new Array(); Syntax.tableList = new Array(); // 创建符号总表 Syntax.mainTable = new SymTable(); // 创建最底层的符号分表 Syntax.table = Syntax.mainTable; // 当前符号分表初始为最底层的符号分表 Syntax.tableList.push(Syntax.table); // 将最底层的符号分表加入符号总表 }, // 获取当前的单词 getWord : function() { if (Syntax.index < tokens.length) { Syntax.word = tokens[Syntax.index]; } }, /* 获取下一个单词 */ nextWord : function() { if (Syntax.index < tokens.length) { Syntax.index++; if (Syntax.index == tokens.length) { Syntax.readall = true; } } else { Syntax.readall = true; return; } }, /* 启动逐Token的语法分析 */ run : function(tokens) { tokens.shift();// 删除数组第一个元素 tokens.pop();//删除最后一个元素 Syntax.init();// 初始化变量 for ( var i = 0; i < 100; i++) { Syntax.instream[i] = "0"; } // 语法分析 进程启动 Syntax.root = Syntax.ParseProgram(tokens); }, /* 分析程序 */ ParseProgram : function(tokens) { var node = new Node('Program'); var child; while (Syntax.index < tokens.length && !(Syntax.readall)) { Syntax.getWord(); child = Syntax.ParseStatement(); node.children.push(child); } return node; }, /* 分析语句 */ ParseStatement : function() { var node = new Node('Statement'); var child; while (!(Syntax.readall)) { Syntax.getWord(); if (Syntax.word.value == "read") { node.match2("read"); child = Syntax.ParseInputStm(); // 进行输入语句分析 node.children.push(child); break; } else if (Syntax.word.value == "write") { node.match2("write"); child = Syntax.ParseOutputStm(); // 进行输出语句分析 node.children.push(child); break; } else if (Syntax.word.value == "if") { node.match2("if"); child = Syntax.ParseIfStm(); // 进行if语句分析 node.children.push(child); break; } else if (Syntax.word.value == "while") { node.match2("while"); child = Syntax.ParseWhileStm(); // 进行while语句分析 node.children.push(child); break; } else if (Syntax.word.value == "int" || Syntax.word.value == "real") { if (Syntax.word.value == "int") { node.match2("int"); } else { node.match2("real"); } // 登录符号表 Syntax.item = new SymItem(); Syntax.table.SymItemList.push(Syntax.item); // 生成中间代码 Syntax.gen("new", "@item", "_", "@table"); // 确定符号表项的类型 if (Syntax.word.value == "int") { Syntax.item.Type = SymType_INT; // 生成中间代码 Syntax.gen("assign", "type", "int", "@item"); } else { Syntax.item.Type = SymType_REAL; // 生成中间代码 Syntax.gen("assign", "type", "real", "@item"); } child = Syntax.ParseVarDeclaration(); // 进行变量声明分析 node.children.push(child); break; } else if (Syntax.word.type == "IDENT") { child = Syntax.ParseAssignment(); // 进行赋值语句分析 node.children.push(child); break; } else if (Syntax.word.value == "{") { node.match2("{"); // 新建符号分表并接在符号总表的尾部 Syntax.table = new SymTable(); Syntax.tableList.push(Syntax.table); // 生成中间代码 Syntax.gen("new", "@table", "_", "@tableList"); child = Syntax.ParseBlock(); // 进行复合语句分析 node.children.push(child); break; } else if (word.value == ";") { node.match2(";"); break; } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:以不合法的token开头。"; Syntax.nextWord(); } } return node; }, /* 分析输入语句 */ ParseInputStm : function() { Syntax.getWord(); //alert("inputstm"); var node = new Node("InputStm"); var child; node.match2("("); // 匹配左括号 Syntax.getWord(); if (Syntax.word.value == ")") { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:缺少参数。"; } else { child = Syntax.ParseVariable(); // 进行变量分析 node.children.push(child); /* 将输入流中的相应元素赋给当前的item的值 */ if (Syntax.item.Type == SymType_INT) { Syntax.item.Val = parseInt(Syntax.instream[Syntax.iIndex]); } else { Syntax.item.Val = parseFloat(Syntax.instream[Syntax.iIndex]); } Syntax.iIndex++; /* 生成中间代码 */ Syntax.gen("read", Syntax.item.Type, "_", Syntax.item.Name); } Syntax.getWord(); while (Syntax.word.value == ",") // 如果有逗号,说明还有其它参数 { node.match2(","); // 匹配逗号 child = Syntax.ParseVariable(); // 进行变量分析 node.children.push(child); /* 将输入流中的相应元素赋给当前的item的值 */ if (Syntax.item.Type == SymType_INT) Syntax.item.Val = parseInt(Syntax.instream[Syntax.iIndex]); else Syntax.item.Val = parseFloat(Syntax.instream[Syntax.iIndex]); /* 生成中间代码 */ Syntax.gen("read", Syntax.item.Type, "_", Syntax.item.Name); Syntax.iIndex++; Syntax.getWord(); } node.match2(")"); // 匹配右括号 node.match2(";"); // 匹配分号 return node; }, /* 分析输出语句 */ ParseOutputStm : function() { Syntax.getWord(); //alert("outputstm"); var node = new Node("OutputStm"); var child; node.match2("("); // 匹配左括号 Syntax.getWord(); if (Syntax.word.value != ")") { /* 将表达式的计算结果的字符串赋给输出流中的相应元素 */ Syntax.expressionVal = Syntax.getExpressionValue(Syntax.getExpressionStr()); // 生成中间代码 Syntax.gen("write", "@result", "_", "@outstream"); Syntax.inWrite = true; child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:缺少参数。"; } Syntax.inWrite = false; node.match2(")"); // 匹配右括号 node.match2(";"); // 匹配分号 return node; }, /* 分析if语句 */ ParseIfStm : function() { Syntax.getWord(); //alert("ifstm"); var node = new Node("IfStm"); var child; node.match2("("); // 匹配左括号 Syntax.getWord(); if (Syntax.word.value != ")") { Syntax.expressionVal = Syntax.getExpressionValue(Syntax.getConditionStr()); // 生成中间代码 Syntax.ifLevel++; Syntax.gen("judge", "if", "@result", Syntax.ifLevel); child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:缺少逻辑表达式。"; } node.match2(")"); // 匹配右括号 child = Syntax.ParseStatement(); // 进行语句分析 node.children.push(child); // 生成中间代码 Syntax.gen("mark", "if", "_", Syntax.ifLevel); // 如果条件为真,则执行到这里便开始跳转至else标记;否则从这里开始执行 Syntax.getWord(); if (Syntax.word.value == "else" && !(Syntax.readall)) // 如果有else,说明还有else语句 { node.match2("else"); // 匹配else child = Syntax.ParseStatement(); // 进行语句分析 node.children.push(child); Syntax.getWord(); } // 生成中间代码 Syntax.gen("mark", "else", "_", Syntax.ifLevel); // 如果条件为真,则跳转至到这里;否则可以不管 Syntax.ifLevel--; return node; }, /* 分析while语句 */ ParseWhileStm : function() { Syntax.getWord(); //alert(whilestm); var node = new Node("WhileStm"); var child; node.match2("("); // 匹配左括号 Syntax.getWord(); if (Syntax.word.value != ")") { Syntax.whileLevel++; // 生成中间代码 Syntax.gen("mark", "while", "begin", Syntax.whileLevel); Syntax.expressionVal = Syntax.getExpressionValue(Syntax.getConditionStr()); // 生成中间代码 Syntax.gen("judge", "while", "@result", Syntax.whileLevel); child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:缺少逻辑表达式。"; } node.match2(")"); // 匹配右括号 child = Syntax.ParseStatement(); // 进行语句分析 node.children.push(child); // 生成中间代码 Syntax.gen("mark", "while", "end", Syntax.whileLevel); Syntax.whileLevel--; return node; }, /* 分析变量声明语句 */ ParseVarDeclaration : function() { Syntax.varInDec = true; Syntax.getWord(); //alert("vardec"); var node = new Node("VarDeclaration"); var child; child = Syntax.ParseVariable(); // 进行变量分析 node.children.push(child); Syntax.getWord(); if (Syntax.word.value == "=") { if (tokens[Syntax.index - 1].value != "]") // 声明的变量不是数组,可同时赋值 { node.match2("="); // 匹配等号 Syntax.getWord(); // 将表达式的值赋给当前项的值 Syntax.item.Val = Syntax.getExpressionValue(Syntax .getExpressionStr()); // 生成中间代码 Syntax.gen("assign", Syntax.item.Type, "@result", Syntax.item.Name); child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:数组在声明的同时被赋值。"; } } Syntax.getWord(); while (Syntax.word.value == ",") { if (Syntax.readall == true) { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:出现多余的逗号。"; break; } Syntax.getWord(); node.match2(","); // 匹配逗号 // 记录之前的item类型 var tempType = Syntax.item.Type; // 新建另外的符号表项 Syntax.item = new SymItem(); Syntax.table.SymItemList.push(Syntax.item); // 生成中间代码 Syntax.gen("new", "@item", "_", "@table"); // 确定符号表项的类型 Syntax.item.Type = tempType; // 生成中间代码 Syntax.gen("assign", "type", tempType, "@item"); child = Syntax.ParseVariable(); // 进行变量分析 node.children.push(child); Syntax.getWord(); if (Syntax.word.value == "=") { if (tokens[Syntax.index - 1].value != "]") // 声明的变量不是数组,可同时赋值 { node.match2("="); // 匹配等号 Syntax.getWord(); // 将表达式的值赋给当前项的值 Syntax.item.Val = Syntax.getExpressionValue(Syntax.getExpressionStr()); // 生成中间代码 Syntax.gen("assign", tempType, "@result", Syntax.item.Name); child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:数组在声明的同时被赋值。"; } } Syntax.getWord(); } node.match2(";"); // 匹配分号 Syntax.varInDec = false; return node; }, /* 分析赋值语句 */ ParseAssignment : function() { Syntax.varInAss = true; Syntax.getWord(); //alert("assign"); var node = new Node("Assignment"); var child; child = Syntax.ParseVariable(); // 进行变量分析 node.children.push(child); var tempType = Syntax.item.Type; node.match2("="); // 匹配等号 Syntax.getWord(); var itemVal = parseInt(Syntax.getExpressionValue(Syntax.getExpressionStr())); Syntax.item.Val = itemVal; // 生成中间代码 if (Syntax.isIndex) // 要用开关变量 { Syntax.gen("assign", tempType, "@result", Syntax.tempName + "[@index]"); } else { Syntax.gen("assign", Syntax.item.Type, "@result", Syntax.item.Name); } Syntax.isIndex = false; child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); node.match2(";"); // 匹配分号 Syntax.varInAss = false; return node; }, /* 分析复合语句 */ ParseBlock : function() { Syntax.getWord(); //alert("block"); var node = new Node("Block"); var child; while (Syntax.word.value != "}") { Syntax.getWord(); child = Syntax.ParseStatement(); // 进行语句分析 node.children.push(child); Syntax.getWord(); if (Syntax.readall) // 如果结尾缺少右花括号则跳出 break; } if (!(Syntax.readall)) { node.match2("}"); // 匹配右括号 } if(node==null){ Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:缺少 } 。"; } // 删除当前的符号分表 Syntax.tableList.pop(); Syntax.table = Syntax.tableList[Syntax.tableList.length - 1]; Syntax.gen("remove", "@table", "_", "@tableList"); return node; }, /* 分析表达式 */ ParseExpression : function() { Syntax.getWord(); //alert("expr"); var node = new Node("Expression"); var child; child = Syntax.ParseTerm(); // 进行项分析 node.children.push(child); Syntax.getWord(); while (Syntax.word.value == "+" || Syntax.word.value == "-" || Syntax.word.value == "<" || Syntax.word.value == ">" || Syntax.word.value == "==" || Syntax.word.value == "<>") // 如果有加号或者减号,说明还有其它项 { Syntax.getWord(); if (Syntax.word.value == "+") // 如果有正号则匹配正号 node.match2("+"); if (Syntax.word.value == "-") // 如果有负号则匹配负号 node.match2("-"); if (word.value == "<") // 如果有小于号则匹配小于号 node.match2("<"); if (Syntax.word.value == ">") // 如果有大于号则匹配大于号 node.match2(">"); if (Syntax.word.value == "==") // 如果有等于号则匹配等于号 node.match2("=="); if (Syntax.word.value == "<>") // 如果有不等号则匹配不等号 node.match2("<>"); child = Syntax.ParseTerm(); // 进行项分析 node.children.push(child); Syntax.getWord(); } return node; }, /* 分析项 */ ParseTerm : function() { Syntax.getWord(); //alert("term"); var node = new Node("Term"); var child; child = Syntax.ParseFactor(); // 进行因子分析 node.children.push(child); Syntax.getWord(); while (Syntax.word.value == "*" || Syntax.word.value == "/") // 如果有乘号或者除号,说明还有其它因子 { Syntax.getWord(); if (Syntax.word.value == "*") { // 如果有乘号则匹配乘号 node.match2("*"); } if (Syntax.word.value == "/") { // 如果有除号则匹配除号 node.match2("/"); } child = Syntax.ParseFactor(); // 进行因子分析 node.children.push(child); Syntax.getWord(); } return node; }, /* 分析因子 */ ParseFactor : function() { Syntax.getWord(); //alert("factor"); var node = new Node("Factor"); var child; if (Syntax.word.type == "IDENT") { child = Syntax.ParseVariable(); // 进行变量分析 node.children.push(child); } else if (Syntax.word.type == "INT" || Syntax.word.type == "REAL" || Syntax.word.value == "+" || Syntax.word.value == "-") { child = Syntax.ParseConstant(); // 进行常量分析 node.children.push(child); } else if (word.value == "(") { node.match2("("); // 匹配左括号 if (!(Syntax.readall)) { child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:小括号不匹配。"; } node.match2(")"); // 匹配右括号 } else { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:存在不合法的因子。"; Syntax.nextWord(); } return node; }, /* 分析变量 */ ParseVariable : function() { Syntax.getWord(); //alert("var"); var node = new Node("Variable"); var child; if (Syntax.index < tokens.length) { if (Syntax.varInDec == false) { // 变量不在声明语句中,将item指向当前找到的符号表项 Syntax.item = Syntax.LookUp(Syntax.word.value); // 如果item为null,要么使用了未定义的变量,要么变量是一个数组元素 if (Syntax.item == null) { Syntax.tempName = Syntax.word.value; } if (Syntax.index < tokens.length - 1) { if (tokens[Syntax.index + 1].value != "[") // 不为数组元素 { node.match1("IDENT"); // 匹配ID if (typeof (Syntax.item) == "undefined" || Syntax.item == null) // 使用了未定义的变量 { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:使用了未声明的变量。"; Syntax.item = Syntax.nonexistence; } } else { child = Syntax.ParseArray(); // 进行数组分析 node.children.push(child); } } else { node.match1("IDENT"); // 匹配ID } } else { Syntax.checkStr = Syntax.word.value; if (Syntax.Check(Syntax.checkStr)) { // 在声明语句中,应该给符号表项的名字赋值 Syntax.item.Name = Syntax.word.value; } else // 在同一层对变量进行了重复定义 { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:变量名冲突。"; } if (Syntax.index < tokens.length - 1) { if (tokens[Syntax.index + 1].value != "[") { // 生成中间代码 Syntax.gen("assign", "name", Syntax.word.value, "@item"); node.match1("IDENT"); // 匹配ID } else { if (!(Syntax.Check(Syntax.checkStr + "[0]"))) // 在同一层对变量进行了重复定义 { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:变量名冲突。"; } child = Syntax.ParseArray(); // 进行数组分析 node.children.push(child); } } else { node.match1("IDENT"); // 匹配ID } } } return node; }, /* 分析常量 */ ParseConstant : function() { Syntax.getWord(); //alert("const"); var node = new Node("Constant"); if (Syntax.word.value == "+") { node.match2("+"); } else if (word.value == "-") { node.match2("-"); } Syntax.getWord(); if (Syntax.word.type == "INT") { node.match1("INT"); // 匹配整数 } else { node.match1("REAL"); // 匹配实数 } return node; }, /* 分析数组 */ ParseArray : function() { Syntax.getWord(); //alert("array"); var node = new Node("Array"); var child; node.match1("IDENT"); // 匹配ID node.match2("["); // 匹配左括号 Syntax.getWord(); if (Syntax.varInDec == true) { if (Syntax.Check(Syntax.checkStr + "[0]")) { Syntax.item.Name += "[0]"; // 生成中间代码 Syntax.gen("assign", "name", Syntax.item.Name, "@item"); if (Syntax.word.type != "INT") // 防止数组长度不为正整数,但没有包括对长度为0的检查 { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:数组长度不为正整数。"; } else { var length = parseInt(Syntax.word.value); // 获得数组长度 var type = Syntax.item.Type; // 获得数组类型 if (length < 1) // 防止声明数组的长度为0 { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:数组长度不为正整数。"; } else { for ( var i = 1; i < length; i++) { // 新建的符号表项名字 var str = tokens[Syntax.index - 2].value + "[" + i + "]"; // 获得数组元素名字 Syntax.item = new SymItem(str, type, 0); // 构造存放该数组元素的符号表项 Syntax.table.SymItemList.push(Syntax.item); // 生成中间代码 Syntax.gen("new", "@item", "_", "@table"); Syntax.gen("assign", "type", type, "@item"); Syntax.gen("assign", "name", str, "@item"); } } } } } else { var arrayIndex; if (Syntax.varInAss == false) { arrayIndex = parseInt(Syntax.getExpressionValue(Syntax .getIndexStr())); } else { arrayIndex = parseInt(Syntax.getExpressionValue(Syntax .getIndexStr())); Syntax.isIndex = true; // 生成中间代码 Syntax.gen("assign", "int", "@result", "@index");///////////////INT改int } if (Syntax.LookUp(Syntax.tempName + "[0]") == null) // 不检查数组越界,只检查是否有此数组存在 { Syntax.error += "
错误发生在第" + Syntax.word.rowNum + "行:使用了未定义的变量。"; Syntax.item = Syntax.nonexistence; } else { Syntax.item = Syntax.LookUp(Syntax.tempName + "[" + arrayIndex + "]"); // 可能发生数组越界 } } child = Syntax.ParseExpression(); // 进行表达式分析 node.children.push(child); node.match2("]"); // 匹配右括号 return node; } //treeview : function(node) { // var ul = document.createElement("ul"); // var li = document.createElement("li"); // li.onclick = function(e) { // showNode(this); // e.cancelBubble = true; // } // if (node.children.length != 0) { // li.style.backgroundImage = "url(images/minus.gif)"; // li.style.backgroundRepeat = "no-repeat"; // li.style.backgroundPosition = "0px 5px"; // } // var txt = document.createTextNode(node.type); // li.appendChild(txt); // for ( var i = 0; i < node.children.length; ++i) { // var child = Syntax.treeview(node.children[i]); // li.appendChild(child); // } // ul.appendChild(li); // return ul; //} }