C# net 使用Irony+XLParser实现类似于Excel中的公式和运算

C# net 使用Irony+XLParser实现类似于Excel中的公式和运算

安装包 XLParser

使用方法:

var bbb = new PnHelp().Jx("=1+2+A1","3");

    public class PnHelp
    {
        public List<Exception> ErrAll = new List<Exception>();

        public Exception ErrFirst { get => ErrAll.FirstOrDefault(); }

        public bool IsSucceed { get; private set; } = false;

        public string Jx(string text, string th_A1 = null)
        {
            var aaa = new Dictionary<string, string>();
            if (!string.IsNullOrWhiteSpace(th_A1))
                aaa.Add("A1", th_A1);

            return Jx(text, aaa);
        }

        public string Jx(string text, Dictionary<string, string> th = null)
        {
            if (string.IsNullOrWhiteSpace(text) || !text.StartsWith("="))
                return text;

            var par = ExcelFormulaParser.Parse(text.Substring(1));
            var aaa1 = Jx(par, th);
            var bbb = aaa1.AllNodes().LastOrDefault();
            if (bbb != null && bbb.Is(GrammarNames.TokenError))
                throw ErrFirst;

            IsSucceed = true;
            return bbb?.Token.ValueString ?? "";
        }

        public string JxTry(string text, string th_A1 = null)
        {
            var aaa = new Dictionary<string, string>();
            if (!string.IsNullOrWhiteSpace(th_A1))
                aaa.Add("A1", th_A1);

            return JxTry(text, aaa);
        }

        public string JxTry(string text, Dictionary<string, string> th = null)
        {
            if (string.IsNullOrWhiteSpace(text) || !text.StartsWith("="))
                return text;

            var par = ExcelFormulaParser.Parse(text.Substring(1));
            var aaa1 = Jx(par, th);
            var bbb = aaa1.AllNodes().LastOrDefault();

            IsSucceed = !(bbb != null && bbb.Is(GrammarNames.TokenError));
            return bbb?.Token.ValueString ?? "";
        }

        private ParseTreeNode Jx(ParseTreeNode treeNode, Dictionary<string, string> th = null)
        {
            var nodes = treeNode.ChildNodes;
            foreach (var node in nodes)
            {
                var p1 = node.Print();
                if (node.IsFunction())
                {
                    //函数
                    var hs = node.GetFunction();
                    //参数
                    var csList = node.GetFunctionArguments();
                    //参数
                    List<ParseTreeNode> csa = new List<ParseTreeNode>();
                    foreach (var cs in csList)
                    {
                        var p12 = cs.Print();
                        var cs4 = cs.AllNodes().ElementAtOrDefault(3);
                        if (cs4 != null && (cs4.Is(GrammarNames.TokenText) || cs4.Is(GrammarNames.TokenNumber) || cs4.Is(GrammarNames.TokenBool) || cs4.Is(GrammarNames.TokenError)))
                        {
                            csa.Add(cs4);
                        }
                        else if (cs4 != null && cs4.Is(GrammarNames.TokenCell))
                        {
                            var cellval = cs4.Token.ValueString;

                            if (th != null && th.TryGetValue(cellval, out string val2))
                                csa.Add(GetNode(val2).AllNodes().ElementAtOrDefault(3));
                            else
                                csa.Add(GetNode(cellval).AllNodes().ElementAtOrDefault(3));
                        }
                        else
                        {
                            var csjg = Jx(cs, th);
                            var cs5 = csjg.AllNodes().LastOrDefault();
                            csa.Add(cs5);
                        }
                    }

                    //执行
                    ParseTreeNode newval;
                    try
                    {
                        newval = keyValuePairs[hs].Item1.Invoke(csa);
                    }
                    catch (Exception ex)
                    {
                        newval = GetErrNode();
                        ErrAll.Add(ex);
                    }

                    treeNode.ChildNodes.Clear();
                    treeNode.ChildNodes.Add(newval);
                    return newval;
                }
                else if (node.Is(GrammarNames.Reference))
                {
                    return Jx(node, th);
                }
                else if (node.Is(GrammarNames.Formula))
                {
                    return Jx(node, th);
                }
                //else if (node.Is(GrammarNames.Cell))
                //{
                //    return Jx(node, th);
                //}
            }
            return treeNode;
        }

        public static Dictionary<string, (Func<List<ParseTreeNode>, ParseTreeNode>, string)> keyValuePairs = new Dictionary<string, (Func<List<ParseTreeNode>, ParseTreeNode>, string)>()
        {
            //excel自带
            { "+",(Jia,"加号")},
            { "-",(Jian,"减号、负数")},
            { "*",(Cen,"乘号")},
            { "/",(Chu,"除号")},
            { "%",(BaiFenBi,"百分号")},
            { "^",(CenMu,"乘幂")},
            { "&",(HeBin,"和号,连接文本或数值。")},
            { "=",(DengYu,"等于")},
            { "<>",(BuDengYu,"不等于")},
            { ">",(DaYu,"大于")},
            { "<",(XiaoYu,"小于")},
            { ">=",(DaYuDengYu,"大于等于")},
            { "<=",(XiaoYuDengYu,"小于等于")},
            { "IF",(IF,"条件判断。IF(TRUE|FALSE,值_true,值_false)")},
            { "IFS",(IFS,"多条件判断并执行。IFS(TRUE|FALSE,值1,TRUE|FALSE,值2,...)")},
            { "IFERROR",(IFERROR,"错误时采用其他值。IFERROR(值,错误时采用的值)")},
            { "AND",(AND,"多个条件判断,需要所有满足。AND(TRUE|FALSE,TRUE|FALSE,...)")},
            { "OR",(OR,"多个条件判断,需要一个满足。OR(TRUE|FALSE,TRUE|FALSE,...)")},
            { "ABS",(ABS,"绝对值。ABS(值)")},
            { "LOG",(LOG,"对数。LOG(值,[底,默认10])")},
            { "REPLACE",(REPLACE,"替换字符串。REPLACE(值,开始位置,个数,新值)")},
            { "SUBSTITUTE",(SUBSTITUTE,"替换字符串。SUBSTITUTE(值,原值,新值,[替换序号|未实现])")},
            { "MID",(MID,"截取字符串。MID(值,开始位置|负数倒取,[字符个数,默认结尾])")},
            { "SEARCH",(SEARCH,"查找字符串,没有找到为0。SEARCH(值,查找值,[开始位置,默认1])")},
            { "TRIM",(TRIM,"清除前后空格。TRIM(值)")},
            { "LEN",(LEN,"获取长度。LEN(值)")},
            { "VALUE",(VALUE,"文本转为数字。VALUE(值,[视为小数点的值])")},
            //自定义函数
            { "REVERSE",(REVERSE,"反转字符串。REVERSE(值)")},
            { "REPLACES",(REPLACES,"替换多个字符串。REPLACES(值,新值,查找值1,查找值2,...)")},
            { "CONTAINS",(CONTAINS,"字符串中是否存在。CONTAINS(值,值1,值2,...)")},
            { "WHERENUM",(WHERENUM,"只保留数字,可识别小数点。WHERENUM(值,[1不停止,2不满足停止,默认1])")},
            { "WHERENUM2",(WHERENUM2,"只保留数字。WHERENUM(值)")},
            { "WHEREAZ",(WHEREAZ,"只保留字母。WHEREAZ(值,[1不停止,2不满足停止,默认1],[1默认,2转大写,3转小写,默认1])")},
            { "WHERENUMAZ",(WHERENUMAZ,"只保留数字和字母。WHERENUMAZ(值)")},
            { "SPLIT",(SPLIT,"分隔字符串。SPLIT(值,[取的位置|负数倒取,默认1],[分隔值1,分隔值2...,默认_])")},
            { "PADLEFT",(PADLEFT,"字符串左侧填充字符,实现右对齐。PADLEFT(值,长度,[对齐字符,默认0])")},
            { "PADRIGHT",(PADRIGHT,"字符串右侧填充字符,实现左对齐。PADRIGHT(值,长度,[对齐字符,默认0])")},
            { "DEC2DEC",(DEC2DEC,"进制转换。DEC2DEC(值,当前进制2-36,目标进制2-36)")},
            { "MIDLOG10",(MIDLOG10,"截取后计算10底的指数(如:1000=102)。MIDLOG10(值,基数位数,[1末尾追加基数|2不追加,默认1])")},
            { "MIDLOG10R",(MIDLOG10R,"尾位当做10底的指数转为整数,<10返回本身(如:102=1000)。MIDLOG10R(值,[尾位长度,默认1])")},
            { "KILO4",(KILO4,"千值转为4长度字符串(如:1000=001K)。KILO4(值,从小到大的3个长度的字符单位)")},
            { "KILO4R",(KILO4R,"4长度字符串转为千值(如:001K=1000)。KILO4R(值,从小到大的3个长度的字符单位)")},
        };

        #region 内置
        public static ParseTreeNode GetNode(object val)
        {
            if (val is bool bo)
                return ExcelFormulaParser.Parse(bo.ToString().ToUpper());
            else if (val is "#VALUE!")
                return ExcelFormulaParser.Parse($"{val.ToString()}");
            else if (val is ParseTreeNode node)
            {
                if (node.Is(GrammarNames.TokenError))
                    return ExcelFormulaParser.Parse("#VALUE!");
                else
                    return ExcelFormulaParser.Parse($"\"{node.Token.ValueString}\"");
            }
            else
                return ExcelFormulaParser.Parse($"\"{val}\"");
        }

        public static ParseTreeNode GetErrNode()
        {
            return GetNode("#VALUE!");
        }

        public static bool TryGetErrNode(List<ParseTreeNode> datas, out ParseTreeNode errNode)
        {
            errNode = null;
            foreach (var item in datas)
            {
                if (item.Is(GrammarNames.TokenError))
                {
                    errNode = GetErrNode();
                    return true;
                }
            }
            return false;
        }

        public static bool TryGetErrNode(ParseTreeNode data, out ParseTreeNode errNode)
        {
            errNode = null;

            if (data.Is(GrammarNames.TokenError))
            {
                errNode = GetErrNode();
                return true;
            }
            return false;
        }
        #endregion

        static ParseTreeNode Jia(List<ParseTreeNode> data)
        {
            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) + Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode Jian(List<ParseTreeNode> data)
        {
            if (data.Count() == 1)
                return GetNode((0m - Convert.ToDecimal(data[0].Token.ValueString)));
            else
                return GetNode((Convert.ToDecimal(data[0].Token.ValueString) - Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode Cen(List<ParseTreeNode> data)
        {
            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) * Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode Chu(List<ParseTreeNode> data)
        {
            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) / Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode BaiFenBi(List<ParseTreeNode> data)
        {
            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) / 100m));
        }
        static ParseTreeNode CenMu(List<ParseTreeNode> data)
        {
            return GetNode((Math.Pow(Convert.ToDouble(data[0].Token.ValueString), Convert.ToDouble(data[1].Token.ValueString))));
        }
        static ParseTreeNode HeBin(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode(string.Join("", data.Select(o => o.Token.ValueString)));
        }
        static ParseTreeNode DengYu(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode((data[0].Token.ValueString == data[1].Token.ValueString));
        }
        static ParseTreeNode BuDengYu(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode((data[0].Token.ValueString != data[1].Token.ValueString));
        }
        static ParseTreeNode DaYu(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) > Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode XiaoYu(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) < Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode DaYuDengYu(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) >= Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode XiaoYuDengYu(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode((Convert.ToDecimal(data[0].Token.ValueString) <= Convert.ToDecimal(data[1].Token.ValueString)));
        }
        static ParseTreeNode IF(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data[0], out ParseTreeNode errNode))
                return errNode;

            if (data[0].Token.ValueString == "TRUE")
                return GetNode(data[1]);
            else
                return GetNode(data[2]);
        }
        static ParseTreeNode IFS(List<ParseTreeNode> data)
        {
            int i = 0;
            while (true)
            {
                if (data[i * 2].Token.ValueString == "TRUE")
                    return GetNode(data[(i * 2) + 1]);
                i++;
            }
        }
        static ParseTreeNode IFERROR(List<ParseTreeNode> data)
        {
            if (data[0].Is(GrammarNames.TokenError) || data[0].Is(GrammarNames.TokenRefError))
                return GetNode(data[1]);

            return GetNode(data[0]);
        }
        static ParseTreeNode AND(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode(data.All(o => o.Token.ValueString == "TRUE"));
        }
        static ParseTreeNode OR(List<ParseTreeNode> data)
        {
            return GetNode(data.Any(o => o.Token.ValueString == "TRUE"));
        }
        static ParseTreeNode ABS(List<ParseTreeNode> data)
        {
            return GetNode(Math.Abs(Convert.ToDecimal(data[0].Token.ValueString)));
        }
        static ParseTreeNode LOG(List<ParseTreeNode> data)
        {
            return GetNode(Math.Log(Convert.ToDouble(data[0].Token.ValueString), data.Count() == 1 ? 10 : Convert.ToDouble(data[1].Token.ValueString)));
        }
        static ParseTreeNode REPLACE(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode($"{data[0].Token.ValueString.Substring(0, Convert.ToInt32(data[1].Token.ValueString) - 1)}{data[3].Token.ValueString}{data[0].Token.ValueString.Substring(Convert.ToInt32(data[1].Token.ValueString) + Convert.ToInt32(data[2].Token.ValueString) - 1)}");
        }
        static ParseTreeNode SUBSTITUTE(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode(data.Count == 3 ? data[0].Token.ValueString.Replace(data[1].Token.ValueString, data[2].Token.ValueString) : data[0].Token.ValueString.Replace(data[1].Token.ValueString, data[2].Token.ValueString));
        }
        static ParseTreeNode MID(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var v0 = data[0].Token.ValueString;
            var v1 = Convert.ToInt32(data[1].Token.ValueString);
            var v2 = data.Count < 3 ? v0.Length : Convert.ToInt32(data[2].Token.ValueString);

            return GetNode(v1 > 0 ? new string(v0.Skip(v1 - 1).Take(v2).ToArray()) : new string(v0.Reverse().Skip(Math.Abs(v1) - 1).Take(v2).Reverse().ToArray()));
        }
        static ParseTreeNode SEARCH(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var v1 = data[0].Token.ValueString;
            var v2 = data[1].Token.ValueString;
            var v3 = data.Count > 2 ? Convert.ToInt32(data[2].Token.ValueString) - 1 : 0;

            var v = v1.Substring(v3).IndexOf(v2) + 1;
            return GetNode(v);
        }
        static ParseTreeNode TRIM(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode(data[0].Token.ValueString.Trim());
        }
        static ParseTreeNode LEN(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode(data[0].Token.ValueString.Length);
        }
        static ParseTreeNode VALUE(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            if (data.Count == 1)
                return GetNode(double.Parse(data[0].Token.ValueString));
            else
                return GetNode(double.Parse(data[0].Token.ValueString.Replace(data[1].Token.ValueString, ".")));
        }
        static ParseTreeNode REVERSE(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            return GetNode(new string(data[0].Token.ValueString.Reverse().ToArray()));
        }
        static ParseTreeNode REPLACES(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var va = data[0].Token.ValueString;
            foreach (var v in data.Skip(2))
            {
                va = va.Replace(v.Token.ValueString, data[1].Token.ValueString);
            }
            return GetNode(va);
        }
        static ParseTreeNode CONTAINS(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            foreach (var item in data.Skip(1))
            {
                if (data[0].Token.ValueString.Contains(item.Token.ValueString))
                    return GetNode(true);
            }
            return GetNode(false);
        }
        static ParseTreeNode WHERENUM(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var v1 = data[0].Token.ValueString;
            var v2 = data.Count > 1 ? data[1].Token.ValueString : "1";

            var sb = new StringBuilder();

            foreach (var item in v1)
                if (Char.IsDigit(item) || (item == '.' && !sb.ToString().Contains('.')))
                    sb.Append(item);
                else if (v2 == "2" && sb.Length > 0)
                    break;

            return GetNode(Convert.ToDouble(sb.ToString()));
        }

        static ParseTreeNode WHERENUM2(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var v1 = data[0].Token.ValueString;
            var sb = new StringBuilder();

            foreach (var item in v1)
                if (Char.IsDigit(item))
                    sb.Append(item);

            return GetNode(sb.ToString());
        }
        static ParseTreeNode WHEREAZ(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var v1 = data[0].Token.ValueString;
            var v2 = data.Count > 1 ? data[1].Token.ValueString : "1";
            var v3 = data.Count > 2 ? data[2].Token.ValueString : "1";

            var sb = new StringBuilder();

            foreach (var item in v1)
                if (Char.IsLetter(item))
                    sb.Append(item);
                else if (v2 == "2" && sb.Length > 0)
                    break;

            if (v3 == "2")
                return GetNode(sb.ToString().ToUpper());
            else if (v3 == "3")
                return GetNode(sb.ToString().ToLower());
            else
                return GetNode(sb.ToString());
        }
        static ParseTreeNode WHERENUMAZ(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var sb = new StringBuilder();
            foreach (var item in data[0].Token.ValueString)
                if (Char.IsLetterOrDigit(item))
                    sb.Append(item);

            return GetNode(sb.ToString());
        }
        static ParseTreeNode SPLIT(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var v0 = data[0].Token.ValueString;
            var v1 = data.Count < 3 ? new string[] { "_" } : data.Skip(2).Select(o => o.Token.ValueString).ToArray();
            var v2 = data.Count < 2 ? 1 : Convert.ToInt32(data[1].Token.ValueString);
            return GetNode(v2 > 0 ? v0.Split(v1, StringSplitOptions.None).ElementAtOrDefault(v2 - 1) : v0.Split(v1, StringSplitOptions.None).Reverse().ElementAtOrDefault(Math.Abs(v2) - 1));
        }
        static ParseTreeNode PADLEFT(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var zf = data.Count() >= 3 ? data[2].Token.ValueString.First() : '0';
            return GetNode(data[0].Token.ValueString.PadLeft(Convert.ToInt32(data[1].Token.ValueString), zf));
        }
        static ParseTreeNode PADRIGHT(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var zf = data.Count() >= 3 ? data[2].Token.ValueString.First() : '0';
            return GetNode(data[0].Token.ValueString.PadRight(Convert.ToInt32(data[1].Token.ValueString), zf));
        }

        const string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        static ParseTreeNode DEC2DEC(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var val = data[0].Token.ValueString.ToUpper();
            var j1 = Convert.ToInt32(data[1].Token.ValueString);
            var j2 = Convert.ToInt32(data[2].Token.ValueString);
            if (j1 < 2 || j1 > 36 || j2 < 2 || j2 > 36)
                throw new Exception("进制参数必须为2-36");

            double j10 = 0;
            if (j1 == 10)
                j10 = Convert.ToDouble(val);
            else
            {
                var zs = val.Split('.').ElementAtOrDefault(0) ?? "";
                var xs = val.Split('.').ElementAtOrDefault(1) ?? "";
                int js = zs.Length;
                foreach (var x in zs)
                {
                    double aa = digits.IndexOf(x);
                    if (aa == -1 || aa >= j1)
                        throw new Exception($"进制参数[{x}]不在进制[{j1}]范围");

                    js--;
                    j10 += aa * Math.Pow(j1, js);
                }
                js = 0;
                foreach (var x in xs)
                {
                    double aa = digits.IndexOf(x);
                    if (aa == -1 || aa >= j1)
                        throw new Exception($"进制参数[{x}]不在进制[{j1}]范围");

                    js--;
                    j10 += aa * Math.Pow(j1, js);
                }
            }

            if (j2 == 10)
            {
                return GetNode(j10);
            }
            else
            {
                var zs = Convert.ToInt64(j10.ToString().Split('.').ElementAtOrDefault(0) ?? "0");
                double xs = Convert.ToDouble("0." + j10.ToString().Split('.').ElementAtOrDefault(1) ?? "0");
                StringBuilder js = new StringBuilder();
                long shang = zs;
                while (true)
                {
                    var shang1 = (long)(shang / j2);
                    int yu = (int)(shang % j2);
                    js.Insert(0, digits[yu]);
                    if (shang1 <= 0)
                        break;

                    shang = shang1;
                }
                if (xs > 0)
                {
                    js.Append(".");
                    var i = 0;
                    while (true)
                    {
                        i--;
                        var shang2 = (xs / Math.Pow(j2, i));
                        int yu = (int)((long)shang2 % j2);
                        js.Append(digits[yu]);

                        if (!shang2.ToString().Contains(".") || i < -8)
                            break;
                    }
                }

                return GetNode(js.ToString());
            }
        }
        static ParseTreeNode MIDLOG10R(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var val = data[0].Token.ValueString;
            if (double.TryParse(val, out double bbb))
            {
                if (bbb < 10)
                {
                    return GetNode(bbb);
                }
            }

            var cc = data[0].Token.ValueString.Length - (data.Count > 1 ? Convert.ToInt32(data[1].Token.ValueString) : 1);
            var v1 = Convert.ToInt32(data[0].Token.ValueString.Substring(0, cc));
            var v2 = Convert.ToInt32(data[0].Token.ValueString.Substring(cc));
            return GetNode((v1 * Math.Pow(10, v2)));
        }
        static ParseTreeNode MIDLOG10(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var d1 = (Int32)Convert.ToDecimal(data[0].Token.ValueString);
            var d2 = Convert.ToInt32(data[1].Token.ValueString);
            var d3 = data.Count < 3 ? 1 : Convert.ToInt32(data[2].Token.ValueString);
            var ws = Convert.ToInt32(new string(d1.ToString().Take(d2).ToArray()));
            var log = ws == 0 ? 0 : Math.Log10(d1 / ws);
            if (double.IsNaN(log) || double.IsInfinity(log))
                log = 0;

            return GetNode(d3 == 1 ? (ws.ToString() + log).PadLeft(d2, '0') : log.ToString());
        }
        static ParseTreeNode KILO4(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var d1 = Convert.ToDecimal(data[0].Token.ValueString);
            var d2 = data[1].Token.ValueString.Skip(0).First();
            var d3 = data[1].Token.ValueString.Skip(1).First();
            var d4 = data[1].Token.ValueString.Skip(2).First();
            if (d1 <= 0)
            {
                return GetNode("000" + d2);
            }
            else if (d1 < 1)
            {
                return GetNode(d1.ToString().Replace('.', d2).Trim('0').PadLeft(4, '0').Substring(0, 4));
            }
            else if (d1 < 1000)
            {
                var aa = d1.ToString().Replace('.', d2);
                return GetNode((aa.IndexOf(d2) == -1 ? (aa + d2) : aa).PadLeft(4, '0').Substring(0, 4));
            }
            else if (d1 < 1000 * 1000)
            {
                d1 = d1 / 1000m;
                var aa = d1.ToString().Replace('.', d3);
                return GetNode((aa.IndexOf(d3) == -1 ? (aa + d3) : aa).PadLeft(4, '0').Substring(0, 4));
            }
            else if (d1 < 1000 * 1000 * 1000)
            {
                d1 = d1 / (1000m * 1000m);
                var aa = d1.ToString().Replace('.', d4);
                return GetNode((aa.IndexOf(d4) == -1 ? (aa + d4) : aa).PadLeft(4, '0').Substring(0, 4));
            }
            else
            {
                return GetNode("999" + d4);
            }
        }
        static ParseTreeNode KILO4R(List<ParseTreeNode> data)
        {
            if (TryGetErrNode(data, out ParseTreeNode errNode))
                return errNode;

            var d0 = data[0].Token.ValueString;
            var d2 = data[1].Token.ValueString.Skip(0).First();
            var d3 = data[1].Token.ValueString.Skip(1).First();
            var d4 = data[1].Token.ValueString.Skip(2).First();

            if (d0.Contains(d2))
            {
                return GetNode(Convert.ToDecimal(d0.Replace(d2, '.')));
            }
            else if (d0.Contains(d3))
            {
                return GetNode((Convert.ToDecimal(d0.Replace(d3, '.')) * 1000m));
            }
            else if (d0.Contains(d4))
            {
                return GetNode((Convert.ToDecimal(d0.Replace(d4, '.')) * 1000m * 1000m));
            }
            else
            {
                return GetNode(Convert.ToDecimal(d0));
            }
        }
    }

  

posted @ 2025-05-23 16:48  爱恋的红尘  阅读(32)  评论(0)    收藏  举报