/// <summary> /// 解析任意hslang脚本 /// </summary> /// <param name="script">脚本的内容</param> /// <returns>返回解析后的单词表,可以拿来运行脚本</returns> public static List <string> Parser(string script) { List <string> word = new List <string>(); //全部单词 string text = ""; //有效字符 cfg.ParserMode mode = cfg.ParserMode.common; //初始化模式 bool wrong = true; //错误,为true时会在解析完毕后抛出错误并返回空的,当扫描到;时自动变成false for (int i = 0; i < script.Length; i++) { string text1 = script.Substring(i, 1);//现行文字 bool wrong1 = false; //文本域 if (text.Equals("\"") && mode == cfg.ParserMode.common)//在普通模式,如果遇到"则代表进入文本模式,如果已经进入则代表进入正常模式,如果为转义模式则把本符号计入有效字符 { mode = cfg.ParserMode.text; text = text + text1; continue; } if (text1.Equals("\"") && mode == cfg.ParserMode.text) //在文本模式 { mode = cfg.ParserMode.common; //进入普通模式 text = text + text1; word.Add(text); //添加单词 text = ""; //清空 continue; } if (text1.Equals("\"") && mode == cfg.ParserMode.escape) //在转义模式 { mode = cfg.ParserMode.text; //进入文本模式 text = text + text1; continue; } //遇到/时的情况 if (text1.Equals("/") && mode == cfg.ParserMode.text) {//在文本模式 text = text + text1; continue; } if (text1.Equals("/") && script.Length >= i && script.Substring(i + 1, 1).Equals("/")) { //文本数组下标大于当前下标并下一个字符也是/ break; //直接结束for循环 } if (text1.Equals("/") && script.Length >= i && !script.Substring(i + 1, 1).Equals("/")) {//文本数组下标大于当前下标并下一个字符不是/ word.Add(text); word.Add(text1); text = ""; continue; } //遇到\时的情况 if (text1.Equals("\\") && mode == cfg.ParserMode.text) { //在文本模式 mode = cfg.ParserMode.escape; //进入转义模式 continue; } if (text1.Equals("\\") && mode == cfg.ParserMode.escape) {//在转义模式 text = text + text1; mode = cfg.ParserMode.text; continue; } //如果为+-*(/)=;,则将前面的做单词,本符号也做单词,不在文本模式 if (mode != cfg.ParserMode.text) { for (int a = 0; a < cfg.u.Length; a++) { if (cfg.u[a].Equals(text1)) { if (wrong) { if (text1.Equals(";")) { wrong = false; } } if (!text.Equals("")) { word.Add(text);//前面做一个单词 } word.Add(text1); text = ""; wrong1 = true; break; } } if (wrong1) { continue; } } //如果为.时的情况 if (text1.Equals(".") && mode != cfg.ParserMode.text && tools.Parser_isNum(text) != true) {//引用了类 word.Add(text); word.Add(text1); text = ""; continue; } if (text1.Equals(".") && mode != cfg.ParserMode.text && tools.Parser_isNum(text) == true) {//浮点整数 text = text + text1; continue; } //如果为空格时的情况 if (text1.Equals(" ") && mode != cfg.ParserMode.text && tools.IsImportantWord(text)) { word.Add(text); text = ""; continue; } if (text1.Equals(" ") && mode != cfg.ParserMode.text && !tools.IsImportantWord(text)) { continue; } //没什么就当做有效字符 text = text + text1; } if (wrong) { Console.WriteLine("警告:在解析阶段没有扫描到结束符号(;)"); } return(word); }
/// <summary> /// 运行解析后的脚本 /// </summary> /// <param name="code">解析后的数组</param> /// <param name="pro">脚本对象</param> /// <param name="RuntimeMode">运行时模式,如果为cfg.RuntimeMode.value则返回执行后的结果,反之不返回</param> /// <returns>指定代码执行后该代码返回的值</returns> public static string Run(List <string> code, script pro, cfg.RuntimeMode RuntimeMode) { cfg.ParserMode ParserMode = cfg.ParserMode.common; int jumpNum = 0; string left = ""; string type = "null"; cfg.typeX typeX = cfg.typeX.Null; for (int point = 0; point < code.Count; point++) { string word = code[point]; if (ParserMode == cfg.ParserMode.jump) { jumpNum--; if (jumpNum == 0) { ParserMode = cfg.ParserMode.common; } continue; } if (tools.IsImportantWord(word)) { if (word.Equals("include") && code.Count >= point + 2) { Console.WriteLine("[debug]引入了" + word + "包"); continue; } if ((word.Equals("int") || word.Equals("string")) && code.Count >= point + 1) { type = word; continue; } } if (tools.IsNum(word)) { if (ParserMode == cfg.ParserMode.common) { left = "[int]" + word; continue; } } if (tools.IsString(word)) { if (ParserMode == cfg.ParserMode.common) { left = "[string]" + word; continue; } } if (word.Equals("=")) { if (!type.Equals("null") && typeX == cfg.typeX.var)//类型不为空的情况下 { List <string> s_code = new List <string>(); int i = 1; for (; point + i < code.Count; i++) { s_code.Add(code[point - 1 + i]); if (code[point - 1 + i].Equals(";")) { break; } } ParserMode = cfg.ParserMode.jump; jumpNum = i - 1; s_code.Add(";"); pro.Var.Add(left, Run(code, pro, cfg.RuntimeMode.value)); type = "null"; if (RuntimeMode == cfg.RuntimeMode.value) { return("[bool]true"); } continue; } } if (code.Count >= point && tools.IsNum(code[point]) && tools.IsNum(left)) { if (word.Equals("+")) { left = "[int]" + Convert.ToString(tools.getTrue(left) + int.Parse(code[point])); } if (word.Equals("-")) { left = "[int]" + Convert.ToString(tools.getTrue(left) - int.Parse(code[point])); } if (word.Equals("*")) { left = "[int]" + Convert.ToString(tools.getTrue(left) * int.Parse(code[point])); } if (word.Equals("/")) { left = "[int]" + Convert.ToString(tools.getTrue(left) / int.Parse(code[point])); } ParserMode = cfg.ParserMode.jump; jumpNum = 1; } if (!tools.IsNum(word) && !tools.IsString(word)) { if (code.Count >= point + 3 && code[point].Equals(".") && code[point + 2].Equals("(")) { string className = word; string funcName = code[point + 1]; List <string> cs = new List <string>(); int i = 0; for (; point + 3 + i < code.Count; i++) { if (code[point + 2 + i].Equals(")")) { break; } else { cs.Add(code[point + 2 + i]); } } ParserMode = cfg.ParserMode.jump; jumpNum = 2 + i;//现在是在类的位置,跳过两个是点+funcName,x最小为1,最少是左括号,右括号也在x里,参数也算在x里 left = func.runFunc(className, funcName, cs, pro); continue; } if (code.Count >= point + 2 && code[point].Equals(".")) { string className = word; string sxName = code[point + 1]; left = func.getSx(className, sxName, pro); ParserMode = cfg.ParserMode.jump; jumpNum = 2; continue; } if (!type.Equals("null") && code.Count > point + 2)//应该是函数的返回值(#0003中不可能有函数)或变量的数据类型 { if (code[point].Equals("(")) { //do something } else { pro.Var.Add("[" + type + "]", ""); left = "[" + type + "]" + word; } continue; } if (RuntimeMode == cfg.RuntimeMode.value) { if (pro.Var.ContainsKey("[string]" + word)) { left = pro.Var["[string]" + word]; } if (pro.Var.ContainsKey("[int]" + word)) { left = pro.Var["[int]" + word]; } continue; } } if (word.Equals(";")) { ParserMode = cfg.ParserMode.common; jumpNum = 0; left = ""; if (RuntimeMode == cfg.RuntimeMode.value) { return(left); } continue; } } return(""); }