Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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("");
        }