private void button1_Click(object sender, EventArgs e) { OperatorList operatorList = (OperatorList)Controls.Find("operatorList", true)[0]; ListBox listBox = (ListBox)operatorList.Controls.Find("operatorLB", true)[0]; Operator operatorO = (Operator)listBox.SelectedItem; if (Program.modelBase.ChangeOperator(operatorO)) { Button button = (Button)Program.mainForm.Controls.Find("operatorBtn", true)[0]; button.Text = operatorO.ToString(); ModelBase.currentOperator = operatorO; Hide(); } else { MessageBox.Show("Помилка! Виберіть оператора"); } }
public void PostfixParserTest() { var op = new AddOperator(); IPostfixNotationParser parser = new PostfixNotationParser(); List <PNToken> expr = new List <PNToken> { new PNOperandToken(3), new PNOperatorToken(op), new PNOperandToken(4) }; var opList = new OperatorList(); opList.Add(op); var res = parser.Parse(expr, opList); Assert.Equal(3m, res.Dequeue().Subject); Assert.Equal(4m, res.Dequeue().Subject); Assert.Equal("+", ((Operator)(res.Dequeue().Subject)).Symbol); }
private Operator GetOperator(OperatorList opList, string sym, bool mayNextUnary) { Operator op; if (opList.HasManyOverload(sym)) { if (mayNextUnary) { op = opList.GetByType(sym, OperatorType.UnaryOperator); } else { op = opList.GetByType(sym, OperatorType.BinaryOperator); } } else { op = opList.Get(sym); } return(op); }
/// <summary> /// 登陆进程 /// </summary> /// <param name="account">登陆账号</param> /// <param name="psw">登录密码</param> /// <returns>返回0为登陆成功,-404为账户密码错误,-1为被禁用无法登陆</returns> public static int LoginIn(string account, string psw) { if (CheckAccPsw(account, psw) == true) { OperatorList node = OperatorListService.FindOperatorByID(-1, "", account, 3); if (node.Enable == false) { return(-1); } LoginInfo.Account = account; LoginInfo.DegreeLevel = node.AuthDegree; LoginInfo.OperID = node.OperID; LoginInfo.Name = node.OperName; OperatorListService.ChangeOperator(node.OperID, node.OperName, node.AuthDegree, node.LogInCount + 1, node.LoginAccount, "", true, 3); } else { return(-404); } return(0); }
/// <summary> /// 获取所有操作员对象(不获取密码) /// </summary> /// <returns>返回操作员列表</returns> public static List <OperatorList> GetAllOperatorList() { List <OperatorList> list = new List <OperatorList>(); string sqlstr = "select OperID,OperName,AuthDegree,LogInCount,LoginAccount,Enable from OperatorList";//安全起见不获取密码 SqlDataReader reader = SqlHelper.ExecuteReader(sqlstr); while (reader.Read()) { OperatorList node = new OperatorList(); node.OperID = Convert.ToInt32(reader[0]); node.OperName = reader[1].ToString(); node.AuthDegree = Convert.ToInt32(reader[2]); node.LogInCount = Convert.ToInt32(reader[3]); node.LoginAccount = reader[4].ToString(); node.Enable = Convert.ToInt32(reader[5]) == 1 ? true : false; list.Add(node); } reader.Close(); return(list); }
public CustomParser() : base() { OperatorList.Add("!"); OperatorList.Add("_"); OperatorAction.Add("!", (x, y) => Factorial(x)); OperatorAction.Add("_", (x, y) => 10.130M); LocalFunctions["log"] = (input) => { if (input.Length == 1) { return((decimal)Math.Log((double)input[0])); } else if (input.Length == 2) { return((decimal)Math.Log((double)input[1], (double)input[0])); } else { return(0); // false } }; LocalFunctions.Add("ln", x => (decimal)Math.Log((double)x[0])); LocalFunctions.Add("logn", x => (decimal)Math.Log((double)x[0])); }
/// <summary> /// Tokenizes <paramref name="expr"/>. /// </summary> /// <param name="expr">The expression to tokenize.</param> /// <returns>The tokens.</returns> private List <string> Lexer(string expr) { var token = ""; var tokens = new List <string>(); expr = expr.Replace("+-", "-"); expr = expr.Replace("-+", "-"); expr = expr.Replace("--", "+"); for (var i = 0; i < expr.Length; i++) { var ch = expr[i]; if (char.IsWhiteSpace(ch)) { continue; } if (char.IsLetter(ch)) { if (i != 0 && (char.IsDigit(expr[i - 1]) || expr[i - 1] == ')')) { tokens.Add("*"); } token += ch; while (i + 1 < expr.Length && char.IsLetterOrDigit(expr[i + 1])) { token += expr[++i]; } tokens.Add(token); token = ""; continue; } if (char.IsDigit(ch)) { token += ch; while (i + 1 < expr.Length && (char.IsDigit(expr[i + 1]) || expr[i + 1] == '.')) { token += expr[++i]; } tokens.Add(token); token = ""; continue; } if (i + 1 < expr.Length && (ch == '-' || ch == '+') && char.IsDigit(expr[i + 1]) && (i == 0 || OperatorList.IndexOf(expr[i - 1].ToString( #if !NETSTANDARD1_4 CultureInfo #endif )) != -1 || i - 1 > 0 && expr[i - 1] == '(')) { // if the above is true, then the token for that negative number will be "-1", not "-","1". // to sum up, the above will be true if the minus sign is in front of the number, but // at the beginning, for example, -1+2, or, when it is inside the brakets (-1). // NOTE: this works for + as well! token += ch; while (i + 1 < expr.Length && (char.IsDigit(expr[i + 1]) || expr[i + 1] == '.')) { token += expr[++i]; } tokens.Add(token); token = ""; continue; } if (ch == '(') { if (i != 0 && (char.IsDigit(expr[i - 1]) || char.IsDigit(expr[i - 1]) || expr[i - 1] == ')')) { tokens.Add("*"); tokens.Add("("); } else { tokens.Add("("); } } else { tokens.Add(ch.ToString()); } } return(tokens); }
public ActionResult operatorshiftList() { weighingcontrolSystemEntities _db = new weighingcontrolSystemEntities(); var search = Request.Form.GetValues("search[value]")[0]; var draw = Request.Form.GetValues("draw").FirstOrDefault(); var start = Request.Form.GetValues("start").FirstOrDefault(); var length = Request.Form.GetValues("length").FirstOrDefault(); //Find Order Column string sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault(); string sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault(); int pageSize = length != null?Convert.ToInt32(length) : 0; int skip = start != null?Convert.ToInt32(start) : 0; int recordsTotal = 0; try { //dc.Configuration.LazyLoadingEnabled = false; // if your table is relational, contain foreign key var v = (from a in _db.tbl_operatorMapping select new { pkid = a.pkid, operatorName = _db.tbl_operatorDetails.Where(x => x.pkid == a.operator_fkId).FirstOrDefault().OperatorName, truckNo = _db.tbl_TruckDetails.Where(x => x.pkid == a.rfiDfkId).FirstOrDefault().truckNo, shiftName = _db.tbl_operatorshift.Where(x => x.pkid == a.shift_fkid).FirstOrDefault().shiftname, date = a.workingdate }); //SORT if (!string.IsNullOrEmpty(search) && !string.IsNullOrWhiteSpace(search)) { v = (from a in _db.tbl_operatorMapping select new { pkid = a.pkid, operatorName = _db.tbl_operatorDetails.Where(x => x.pkid == a.operator_fkId).FirstOrDefault().OperatorName, truckNo = _db.tbl_TruckDetails.Where(x => x.pkid == a.rfiDfkId).FirstOrDefault().truckNo, shiftName = _db.tbl_operatorshift.Where(x => x.pkid == a.shift_fkid).FirstOrDefault().shiftname, date = a.workingdate }).Where(x => x.operatorName.Contains(search) || x.truckNo.Contains(search)); } if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir))) { v = v.OrderBy(sortColumn, sortColumnDir); //v = v.OrderBy(x=>x.orderfkid); } recordsTotal = v.Count(); var data = v.Skip(skip).Take(pageSize).ToList(); List <OperatorList> opelist = new List <OperatorList>(); foreach (var item in data) { OperatorList _obj = new OperatorList(); _obj.pkid = item.pkid; _obj.shiftName = item.shiftName; _obj.truckNo = item.truckNo; _obj.operatorName = item.operatorName; _obj.date = Convert.ToDateTime(item.date).ToShortDateString(); opelist.Add(_obj); } return(Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = opelist }, JsonRequestBehavior.AllowGet)); } catch (Exception e) { Commonfunction.LogError(e, HttpContext.Server.MapPath("~/ErrorLog.txt")); return(Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = "" }, JsonRequestBehavior.AllowGet)); } }
/// <summary> /// This constructor will add some basic operators, functions, and variables /// to the parser. Please note that you are able to change that using /// boolean flags /// </summary> /// <param name="loadPreDefinedFunctions">This will load "abs", "cos", "cosh", "arccos", "sin", "sinh", "arcsin", "tan", "tanh", "arctan", "sqrt", "rem", "round"</param> /// <param name="loadPreDefinedOperators">This will load "%", "*", ":", "/", "+", "-", ">", "<", "="</param> /// <param name="loadPreDefinedVariables">This will load "pi" and "e"</param> public MathParser(bool loadPreDefinedFunctions = true, bool loadPreDefinedOperators = true, bool loadPreDefinedVariables = true) { if (loadPreDefinedOperators) { // by default, we will load basic arithmetic operators. // please note, its possible to do it either inside the constructor, // or outside the class. the lowest value will be executed first! OperatorList.Add("%"); // modulo OperatorList.Add("^"); // to the power of OperatorList.Add(":"); // division 1 OperatorList.Add("/"); // division 2 OperatorList.Add("*"); // multiplication OperatorList.Add("-"); // subtraction OperatorList.Add("+"); // addition OperatorList.Add(">"); // greater than OperatorList.Add("<"); // less than OperatorList.Add("="); // are equal // when an operator is executed, the parser needs to know how. // this is how you can add your own operators. note, the order // in this list does not matter. _operatorAction.Add("%", (numberA, numberB) => numberA % numberB); _operatorAction.Add("^", (numberA, numberB) => (decimal)Math.Pow((double)numberA, (double)numberB)); _operatorAction.Add(":", (numberA, numberB) => numberA / numberB); _operatorAction.Add("/", (numberA, numberB) => numberA / numberB); _operatorAction.Add("*", (numberA, numberB) => numberA * numberB); _operatorAction.Add("+", (numberA, numberB) => numberA + numberB); _operatorAction.Add("-", (numberA, numberB) => numberA - numberB); _operatorAction.Add(">", (numberA, numberB) => numberA > numberB ? 1 : 0); _operatorAction.Add("<", (numberA, numberB) => numberA < numberB ? 1 : 0); _operatorAction.Add("=", (numberA, numberB) => numberA == numberB ? 1 : 0); } if (loadPreDefinedFunctions) { // these are the basic functions you might be able to use. // as with operators, localFunctions might be adjusted, i.e. // you can add or remove a function. // please open the "MathosTest" project, and find MathParser.cs // in "CustomFunction" you will see three ways of adding // a new function to this variable! // EACH FUNCTION MAY ONLY TAKE ONE PARAMETER, AND RETURN ONE // VALUE. THESE VALUES SHOULD BE IN "DECIMAL FORMAT"! LocalFunctions.Add("abs", x => (decimal)Math.Abs((double)x[0])); LocalFunctions.Add("cos", x => (decimal)Math.Cos((double)x[0])); LocalFunctions.Add("cosh", x => (decimal)Math.Cosh((double)x[0])); LocalFunctions.Add("arccos", x => (decimal)Math.Acos((double)x[0])); LocalFunctions.Add("sin", x => (decimal)Math.Sin((double)x[0])); LocalFunctions.Add("sinh", x => (decimal)Math.Sinh((double)x[0])); LocalFunctions.Add("arcsin", x => (decimal)Math.Asin((double)x[0])); LocalFunctions.Add("tan", x => (decimal)Math.Tan((double)x[0])); LocalFunctions.Add("tanh", x => (decimal)Math.Tanh((double)x[0])); LocalFunctions.Add("arctan", x => (decimal)Math.Atan((double)x[0])); //LocalFunctions.Add("arctan2", x => (decimal)Math.Atan2((double)x[0], (double)x[1])); LocalFunctions.Add("sqrt", x => (decimal)Math.Sqrt((double)x[0])); LocalFunctions.Add("rem", x => (decimal)Math.IEEERemainder((double)x[0], (double)x[1])); LocalFunctions.Add("root", x => (decimal)Math.Pow((double)x[0], 1.0 / (double)x[1])); LocalFunctions.Add("ln", x => (decimal)Math.Log((double)x[0], Math.E)); LocalFunctions.Add("pow", x => (decimal)Math.Pow((double)x[0], (double)x[1])); LocalFunctions.Add("e", x => (decimal)Math.Pow(Math.E, (double)x[0])); LocalFunctions.Add("exp", x => (decimal)Math.Exp((double)x[0])); //LocalFunctions.Add("log", x => (decimal)Math.Log((double)x[0])); //LocalFunctions.Add("log10", x => (decimal)Math.Log10((double)x[0])); LocalFunctions.Add("log", delegate(decimal[] input) { // input[0] is the number // input[1] is the base switch (input.Length) { case 1: return((decimal)Math.Log((double)input[0])); case 2: return((decimal)Math.Log((double)input[0], (double)input[1])); default: return(0); // false } }); LocalFunctions.Add("round", x => (decimal)Math.Round((double)x[0])); LocalFunctions.Add("truncate", x => (decimal)(x[0] < 0.0m ? -Math.Floor(-(double)x[0]) : Math.Floor((double)x[0]))); LocalFunctions.Add("floor", x => (decimal)Math.Floor((double)x[0])); LocalFunctions.Add("ceiling", x => (decimal)Math.Ceiling((double)x[0])); LocalFunctions.Add("sign", x => (decimal)Math.Sign((double)x[0])); } if (loadPreDefinedVariables) { // local variables such as pi can also be added into the parser. LocalVariables.Add("pi", (decimal)3.14159265358979323846264338327950288); // the simplest variable! LocalVariables.Add("pi2", (decimal)6.28318530717958647692528676655900576); LocalVariables.Add("pi05", (decimal)1.57079632679489661923132169163975144); LocalVariables.Add("pi025", (decimal)0.78539816339744830961566084581987572); LocalVariables.Add("pi0125", (decimal)0.39269908169872415480783042290993786); LocalVariables.Add("pitograd", (decimal)57.2957795130823208767981548141051704); LocalVariables.Add("piofgrad", (decimal)0.01745329251994329576923690768488612); LocalVariables.Add("e", (decimal)2.71828182845904523536028747135266249); LocalVariables.Add("phi", (decimal)1.61803398874989484820458683436563811); LocalVariables.Add("major", (decimal)0.61803398874989484820458683436563811); LocalVariables.Add("minor", (decimal)0.38196601125010515179541316563436189); } }
/* UNDER THE HOOD - THE CORE OF THE PARSER */ private List <string> Scanner(string expr) { // SCANNING THE INPUT STRING AND CONVERT IT INTO TOKENS var tokens = new List <string>(); var vector = ""; //_expr = _expr.Replace(" ", ""); // remove white space expr = expr.Replace("+-", "-"); // some basic arithmetical rules expr = expr.Replace("-+", "-"); expr = expr.Replace("--", "+"); /* foreach (var item in LocalVariables) * { * // replace the current variables with their value * _expr = _expr.Replace(item.Key, "(" + item.Value.ToString(CULTURE_INFO) + ")"); * }*/ for (var i = 0; i < expr.Length; i++) { var ch = expr[i]; if (char.IsWhiteSpace(ch)) { } // could also be used to remove white spaces. else if (Char.IsLetter(ch)) { if (i != 0 && (Char.IsDigit(expr[i - 1]) || Char.IsDigit(expr[i - 1]) || expr[i - 1] == ')')) { tokens.Add("*"); } vector = vector + ch; while ((i + 1) < expr.Length && Char.IsLetterOrDigit(expr[i + 1])) // here is it is possible to choose whether you want variables that only contain letters with or without digits. { i++; vector = vector + expr[i]; } tokens.Add(vector); vector = ""; } else if (Char.IsDigit(ch)) { vector = vector + ch; while ((i + 1) < expr.Length && (Char.IsDigit(expr[i + 1]) || expr[i + 1] == '.')) // removed || _expr[i + 1] == ',' { i++; vector = vector + expr[i]; } tokens.Add(vector); vector = ""; } else if ((i + 1) < expr.Length && (ch == '-' || ch == '+') && Char.IsDigit(expr[i + 1]) && (i == 0 || OperatorList.IndexOf(expr[i - 1].ToString(CultureInfo.InvariantCulture)) != -1 || ((i - 1) > 0 && expr[i - 1] == '('))) { // if the above is true, then, the token for that negative number will be "-1", not "-","1". // to sum up, the above will be true if the minus sign is in front of the number, but // at the beginning, for example, -1+2, or, when it is inside the brakets (-1). // NOTE: this works for + sign as well! vector = vector + ch; while ((i + 1) < expr.Length && (Char.IsDigit(expr[i + 1]) || expr[i + 1] == '.')) // removed || _expr[i + 1] == ',' { i++; vector = vector + expr[i]; } tokens.Add(vector); vector = ""; } else if (ch == '(') { if (i != 0 && (Char.IsDigit(expr[i - 1]) || Char.IsDigit(expr[i - 1]) || expr[i - 1] == ')')) { tokens.Add("*"); // if we remove this line(above), we would be able to have numbers in function names. however, then we can't parser 3(2+2) tokens.Add("("); } else { tokens.Add("("); } } else { tokens.Add(ch.ToString()); } } return(tokens); //return MathParserLogic(_tokens); }
public CustomParser() : base() { OperatorList.Add("!"); OperatorAction.Add("!", (x, y) => Factorial(x)); }
/// <summary> /// Делает разбор символов находящийся в выражении /// </summary> /// <param name="expr">Полное математическое выражение</param> protected override List <string> Lexer(string expr) { var token = ""; var tokens = new List <string>(); expr = expr.Replace(" ", ""); expr = expr.Replace("+-", "-"); expr = expr.Replace("-+", "-"); expr = expr.Replace("--", "+"); for (var i = 0; i < expr.Length; i++) { var ch = expr[i]; if (char.IsWhiteSpace(ch)) { continue; } if (char.IsLetter(ch)) { if (i != 0 && (char.IsDigit(expr[i - 1]) || expr[i - 1] == ')')) { tokens.Add("*"); } token += ch; while (i + 1 < expr.Length && char.IsLetterOrDigit(expr[i + 1])) { token += expr[++i]; } tokens.Add(token); token = ""; continue; } if (char.IsDigit(ch)) { token += ch; // для больших чисел > 9 сразу соединяет вместе while (i + 1 < expr.Length && (char.IsDigit(expr[i + 1]) || expr[i + 1] == '.')) { token += expr[++i]; } tokens.Add(token); token = ""; continue; } if (i + 1 < expr.Length && (ch == '-' || ch == '+') && char.IsDigit(expr[i + 1]) && (i == 0 || OperatorList.IndexOf(expr[i - 1].ToString( #if !NETSTANDARD1_4 this.CultureInfo #endif )) != -1 || i - 1 >= 0 && expr[i - 1] == '(')) { token += ch; while (i + 1 < expr.Length && (char.IsDigit(expr[i + 1]) || expr[i + 1] == '.')) { token += expr[++i]; } tokens.Add(token); token = ""; continue; } if (ch == '(') { if (i != 0 && (char.IsDigit(expr[i - 1]) || char.IsDigit(expr[i - 1]) || expr[i - 1] == ')')) { tokens.Add("*"); tokens.Add("("); } else { tokens.Add("("); } } else { tokens.Add(ch.ToString()); } } return(tokens); }
/// <summary> /// This constructor will add some basic operators, functions, and variables /// to the parser. Please note that you are able to change that using /// boolean flags /// </summary> /// <param name="loadPreDefinedOperators">This will load "%", "*", ":", "/", "+", "-", ">", "<", "="</param> public ILMathParser(bool loadPreDefinedOperators = true) { if (loadPreDefinedOperators) { OperatorList.Add("/"); // division 2 OperatorList.Add("*"); // multiplication OperatorList.Add("-"); // subtraction OperatorList.Add("+"); // addition OperatorList.Add(">"); // greater than OperatorList.Add("<"); // less than OperatorList.Add("="); // are equal OperatorActionIL.Add("/", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Division(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)"); OperatorAction.Add("/", (x, y) => x - y); OperatorActionIL.Add("*", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Multiply(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)"); OperatorAction.Add("*", (x, y) => x - y); OperatorActionIL.Add("-", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Subtraction(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)"); OperatorAction.Add("-", (x, y) => x - y); OperatorActionIL.Add("+", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)"); OperatorAction.Add("+", (x, y) => x + y); OperatorActionIL.Add(">", "call bool [mscorlib]System.Decimal::op_GreaterThan(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" + "brtrue.s q@\r\n" + "ldc.i4.0 \r\n" + "br.s p@\r\n" + "q@: ldc.i4.1\r\n" + "p@: nop\r\n" + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)"); OperatorAction.Add(">", (x, y) => x > y ? 1 : 0); OperatorActionIL.Add("<", "call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" + "brtrue.s q@\r\n" + "ldc.i4.0 \r\n" + "br.s p@\r\n" + "q@: ldc.i4.1\r\n" + "p@: nop\r\n" + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)"); OperatorAction.Add("<", (x, y) => x < y ? 1 : 0); OperatorActionIL.Add("=", "call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" + "brtrue.s q@\r\n" + "ldc.i4.0 \r\n" + "br.s p@\r\n" + "q@: ldc.i4.1\r\n" + "p@: nop\r\n" + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)"); OperatorAction.Add("=", (x, y) => x == y ? 1 : 0); //OperatorListIL.Add("+",); // by default, we will load basic arithmetic operators. // please note, its possible to do it either inside the constructor, //// or outside the class. the lowest value will be executed first! //OperatorList.Add("%"); // modulo //OperatorList.Add("^"); // to the power of //OperatorList.Add(":"); // division 1 //OperatorList.Add("/"); // division 2 //OperatorList.Add("*"); // multiplication //OperatorList.Add("-"); // subtraction //OperatorList.Add("+"); // addition //OperatorList.Add(">"); // greater than //OperatorList.Add("<"); // less than //OperatorList.Add("="); // are equal //// when an operator is executed, the parser needs to know how. //// this is how you can add your own operators. note, the order //// in this list does not matter. //_operatorAction.Add("%", (numberA, numberB) => numberA % numberB); //_operatorAction.Add("^", (numberA, numberB) => (decimal)Math.Pow((double)numberA, (double)numberB)); //_operatorAction.Add(":", (numberA, numberB) => numberA / numberB); //_operatorAction.Add("/", (numberA, numberB) => numberA / numberB); //_operatorAction.Add("*", (numberA, numberB) => numberA * numberB); //_operatorAction.Add("+", (numberA, numberB) => numberA + numberB); //_operatorAction.Add("-", (numberA, numberB) => numberA - numberB); //_operatorAction.Add(">", (numberA, numberB) => numberA > numberB ? 1 : 0); //_operatorAction.Add("<", (numberA, numberB) => numberA < numberB ? 1 : 0); //_operatorAction.Add("=", (numberA, numberB) => numberA == numberB ? 1 : 0); } }
/// <summary> /// This constructor will add some basic operators, functions, and variables /// to the parser. Please note that you are able to change that using /// boolean flags /// </summary> /// <param name="loadPreDefinedFunctions">This will load "abs", "cos", "cosh", "arccos", "sin", "sinh", "arcsin", "tan", "tanh", "arctan", "sqrt", "rem", "round"</param> /// <param name="loadPreDefinedOperators">This will load "%", "*", ":", "/", "+", "-", ">", "<", "="</param> /// <param name="loadPreDefinedVariables">This will load "pi"</param> public MathParser(bool loadPreDefinedFunctions = true, bool loadPreDefinedOperators = true, bool loadPreDefinedVariables = true) { if (loadPreDefinedOperators) { // by default, we will load basic arithmetic operators. // please note, its possible to do it either inside the constructor, // or outside the class. the lowest value will be executed first! OperatorList.Add("%"); // modulo OperatorList.Add("^"); // to the power of OperatorList.Add(":"); // division 1 OperatorList.Add("/"); // division 2 OperatorList.Add("*"); // multiplication OperatorList.Add("-"); // subtraction OperatorList.Add("+"); // addition OperatorList.Add(">"); // greater than OperatorList.Add("<"); // less than OperatorList.Add("="); // are equal // when an operator is executed, the parser needs to know how. // this is how you can add your own operators. note, the order // in this list does not matter. _operatorAction.Add("%", (numberA, numberB) => numberA % numberB); _operatorAction.Add("^", (numberA, numberB) => (decimal)Math.Pow((double)numberA, (double)numberB)); _operatorAction.Add(":", (numberA, numberB) => numberA / numberB); _operatorAction.Add("/", (numberA, numberB) => numberA / numberB); _operatorAction.Add("*", (numberA, numberB) => numberA * numberB); _operatorAction.Add("+", (numberA, numberB) => numberA + numberB); _operatorAction.Add("-", (numberA, numberB) => numberA - numberB); _operatorAction.Add(">", (numberA, numberB) => numberA > numberB ? 1 : 0); _operatorAction.Add("<", (numberA, numberB) => numberA < numberB ? 1 : 0); _operatorAction.Add("=", (numberA, numberB) => numberA == numberB ? 1 : 0); } if (loadPreDefinedFunctions) { // these are the basic functions you might be able to use. // as with operators, localFunctions might be adjusted, i.e. // you can add or remove a function. // please open the "MathosTest" project, and find MathParser.cs // in "CustomFunction" you will see three ways of adding // a new function to this variable! // EACH FUNCTION MAY ONLY TAKE ONE PARAMETER, AND RETURN ONE // VALUE. THESE VALUES SHOULD BE IN "DECIMAL FORMAT"! LocalFunctions.Add("abs", x => (decimal)Math.Abs((double)x[0])); LocalFunctions.Add("cos", x => (decimal)Math.Cos((double)x[0])); LocalFunctions.Add("cosh", x => (decimal)Math.Cosh((double)x[0])); LocalFunctions.Add("arccos", x => (decimal)Math.Acos((double)x[0])); LocalFunctions.Add("sin", x => (decimal)Math.Sin((double)x[0])); LocalFunctions.Add("sinh", x => (decimal)Math.Sinh((double)x[0])); LocalFunctions.Add("arcsin", x => (decimal)Math.Asin((double)x[0])); LocalFunctions.Add("tan", x => (decimal)Math.Tan((double)x[0])); LocalFunctions.Add("tanh", x => (decimal)Math.Tanh((double)x[0])); LocalFunctions.Add("arctan", x => (decimal)Math.Atan((double)x[0])); LocalFunctions.Add("sqrt", x => (decimal)Math.Sqrt((double)x[0])); LocalFunctions.Add("rem", x => (decimal)Math.IEEERemainder((double)x[0], (double)x[1])); LocalFunctions.Add("round", x => (decimal)Math.Round((double)x[0])); LocalFunctions.Add("pow", x => (decimal)Math.Pow((double)x[0], (double)x[1])); } if (loadPreDefinedVariables) { // local variables such as pi can also be added into the parser. LocalVariables.Add("pi", (decimal)Math.PI); // the simplest variable! } }
/* UNDER THE HOOD - THE CORE OF THE PARSER */ private decimal Scanner(string _expr) { // SCANNING THE INPUT STRING AND CONVERT IT INTO TOKENS List <string> _tokens = new List <string>(); string _vector = ""; //_expr = _expr.Replace(" ", ""); // remove white space _expr = _expr.Replace("+-", "-"); // some basic arithmetical rules _expr = _expr.Replace("-+", "-"); _expr = _expr.Replace("--", "+"); foreach (var item in LocalVariables) { // replace the current variables with their value _expr = _expr.Replace(item.Key, "(" + item.Value.ToString(CULTURE_INFO) + ")"); } for (int i = 0; i < _expr.Length; i++) { char ch = _expr[i]; if (char.IsWhiteSpace(ch)) { } // could also be used to remove white spaces. else if (Char.IsLetter(ch)) { if (i != 0 && (Char.IsDigit(_expr[i - 1]) || Char.IsDigit(_expr[i - 1]) || _expr[i - 1] == ')')) { _tokens.Add("*"); } _vector = _vector + ch; while ((i + 1) < _expr.Length && Char.IsLetter(_expr[i + 1])) { i++; _vector = _vector + _expr[i]; } if (_vector != null) { _tokens.Add(_vector); _vector = ""; } } else if (Char.IsDigit(ch)) { _vector = _vector + ch; while ((i + 1) < _expr.Length && (Char.IsDigit(_expr[i + 1]) || _expr[i + 1] == '.')) // removed || _expr[i + 1] == ',' { i++; _vector = _vector + _expr[i]; } if (_vector != null) { _tokens.Add(_vector); _vector = ""; } } else if ((i + 1) < _expr.Length && (ch == '-' || ch == '+') && Char.IsDigit(_expr[i + 1]) && (i == 0 || OperatorList.IndexOf(_expr[i - 1].ToString()) != -1 || ((i - 1) > 0 && _expr[i - 1] == '('))) { // if the above is true, then, the token for that negative number will be "-1", not "-","1". // to sum up, the above will be true if the minus sign is in front of the number, but // at the beginning, for example, -1+2, or, when it is inside the brakets (-1). // NOTE: this works for + sign as well! _vector = _vector + ch; while ((i + 1) < _expr.Length && (Char.IsDigit(_expr[i + 1]) || _expr[i + 1] == '.')) // removed || _expr[i + 1] == ',' { i++; _vector = _vector + _expr[i]; } if (_vector != null) { _tokens.Add(_vector); _vector = ""; } } else if (ch == '(') { if (i != 0 && (Char.IsDigit(_expr[i - 1]) || Char.IsDigit(_expr[i - 1]) || _expr[i - 1] == ')')) { _tokens.Add("*"); _tokens.Add("("); } else { _tokens.Add("("); } } else { _tokens.Add(ch.ToString()); } } return(MathParserLogic(_tokens)); }
public Queue <PNToken> Parse(IEnumerable <PNToken> expr, OperatorList opList) { Queue <PNToken> outString = new Queue <PNToken>(); Stack <Operator> operatorStack = new Stack <Operator>(); foreach (var item in expr) { if (item is PNOperandToken) { outString.Enqueue(item); } else { Operator op = (Operator)item.Subject; switch (op.OperatorType) { case OperatorType.InBracket: operatorStack.Push(op); continue; case OperatorType.OutBracket: bool inBracketFound = false; while (operatorStack.Count > 0) { Operator popOperator = operatorStack.Pop(); if (popOperator.OperatorType != OperatorType.InBracket) { outString.Enqueue(new PNOperatorToken(popOperator)); } else { inBracketFound = true; break; } } if (!inBracketFound) { throw new InvalidOperationException("Несогласованные скобки в выражении!"); } continue; case OperatorType.BinaryOperator: case OperatorType.UnaryOperator: while (operatorStack.Count > 0 && op.Priority <= operatorStack.Peek().Priority) { outString.Enqueue(new PNOperatorToken(operatorStack.Pop())); } operatorStack.Push(op); continue; } } } while (operatorStack.Count > 0) { var op = operatorStack.Pop(); if (op.OperatorType != OperatorType.BinaryOperator && op.OperatorType != OperatorType.UnaryOperator) { throw new InvalidOperationException("Несогласованные скобки в выражении!"); } outString.Enqueue(new PNOperatorToken(op)); } return(outString); }