123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802 |
- /**
- *
- * @author seagle
- * @date 2024-7-10
- * @Description 表达式计算
- */
- using MECF.Framework.UI.Core.DxfScript;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- namespace MECF.Framework.UI.Core.DxfScript
- {
- public partial class Express
- {
- public ExpressNode Root { get; set; }
- private Dictionary<string, Variable> Variables = new Dictionary<string, Variable>();
- public Express()
- {
- Root = null;
-
- }
- private void Trace(string s)
- {
- string a = s;
- }
-
- public ExpressNode AddChild(ExpressNode curr, ExpressNode node)
- {
- if (curr == null)
- {
- if (Root != null )
- {
- throw new Exception("Add tree child error:try to add the fist node,but root is not null");
-
- }
- else
- {
- Root = node;
- return Root;
- }
- }
- if (curr.FirstChild == null)
- {
- //maintain father-child realtionship
- curr.FirstChild = node;
- curr.LastChild = node;
- node.Father = curr;
- }
- else
- {
- //maintain brothers realtionship
- curr.LastChild.NextBrother = node;
- node.PrevBrother = curr.LastChild;
- //maintain father-child realtionship
- curr.LastChild = node;
- node.Father = curr;
- }
- return node;
- }
- public ExpressNode AddFather(ExpressNode curr, ExpressNode node)
- {
- if (curr == null)
- {
- throw new Exception("It's invalid to add father to a null node");
-
- }
- if (curr.Father == null)
- {
- if (curr != Root)
- {
- throw new Exception("Try to add father and be root,but current node is not root");
-
- }
- //maintain father-child realtionship
- curr.Father = node;
- node.FirstChild = curr;
- node.LastChild = curr;
- Root = node;
- }
- else
- {
- //take over curr's brothers relationship
- if (curr.PrevBrother != null)
- {
- node.PrevBrother = curr.PrevBrother;
- curr.PrevBrother.NextBrother = node;
- }
- curr.PrevBrother = null;
- if (curr.NextBrother != null)
- {
- node.NextBrother = curr.NextBrother;
- curr.NextBrother.PrevBrother = node;
- }
- curr.NextBrother = null;
- //take over curr's father relationship
- node.Father = curr.Father;
- if (node.Father.FirstChild == curr)
- {
- node.Father.FirstChild = node;
- }
- if (node.Father.LastChild == curr)
- {
- node.Father.LastChild = node;
- }
- //maintain curr's child realtionship
- node.FirstChild = curr;
- node.LastChild = curr;
- curr.Father = node;
- }
- return node;
- }
- public void Create(StringReader reader)
- {
- CreateMain(reader);
- ComputeNode(Root, true);
-
- }
- public Variable GetTopVariable()
- {
-
- return Root.Var;
- }
- public Variable Compute()
- {
-
- ComputeNode(Root);
-
- return Root.Var ;
- }
- public void ComputeNode(ExpressNode curr,bool OnlyCheckDataType = false)
- {
- if (curr == null)
- {
- return ;
- }
- if (curr.NodeType == KeywordType.KW_VARIABLE || curr.NodeType == KeywordType.KW_CONST_TRUE || curr.NodeType == KeywordType.KW_CONST_FALSE ||
- curr.NodeType == KeywordType.KW_CONST_INTEGER || curr.NodeType == KeywordType.KW_CONST_DECIMAL || curr.NodeType == KeywordType.KW_CONST_STRING)
- {
- //变量或常量
- if (curr.Var.IsNone && !OnlyCheckDataType)
- {
- throw new Exception("Computing varialbe:" + curr.Var.Name + " is none");
- }
- else
- {
- return;
- }
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_NEGATIVE)
- {
- //单目运算符-
- if (curr.FirstChild == null)
- {
- throw new Exception("Negtive operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- curr.Var.Nigtive(OnlyCheckDataType);
- return;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_NOT)
- {
- if (curr.FirstChild == null)
- {
- throw new Exception("Not operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- curr.Var.Not(OnlyCheckDataType);
- return;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_BIT_NOT)
- {
- throw new Exception("BitNot operator not implemented");
- if (curr.FirstChild == null)
- {
- throw new Exception("BitNot operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
- //curr.Var.BitNot(OnlyCheckDataType);
-
-
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_PLUS)
- {
- //双目运算符+(多目)
- if (curr.FirstChild == null)
- {
- throw new Exception("Plus operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Plus operator error:No second data");
-
- }
- while (child != null)
- {
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Plus(child.Var, OnlyCheckDataType);
-
- child = child.NextBrother;
- }
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_MINUS)
- {
- //双目运算符-
- if (curr.FirstChild == null)
- {
- throw new Exception("Minus operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Minus otperator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Minus(child.Var, OnlyCheckDataType);
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_MULTIPLE)
- {
- //双目运算符*(多目)
- if (curr.FirstChild == null)
- {
- throw new Exception("Multiple operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Multiple operator error:No second data");
-
- }
- while (child != null)
- {
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Multiple(child.Var, OnlyCheckDataType);
-
- child = child.NextBrother;
- }
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_DEVIDE)
- {
- //双目运算符/
- if (curr.FirstChild == null)
- {
- throw new Exception("Multiple operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Devide operator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Devide(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_EQUAL)
- {
- //双目运算符==
- if (curr.FirstChild == null)
- {
- throw new Exception("Equal operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Equal operator error:No second data");
- ;
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Equal(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_NOT_EQUAL)
- {
- //双目运算符!=
- if (curr.FirstChild == null)
- {
- throw new Exception("NotEqual operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
-
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("NotEqual operator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.NotEqual(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_GT)
- {
- //双目运算符>
- if (curr.FirstChild == null)
- {
- throw new Exception("Gt operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Gt operator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Gt(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_GE)
- {
- //双目运算符>=
- if (curr.FirstChild == null)
- {
- throw new Exception("Ge operator error:No data");
- ;
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Ge operator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Ge(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_LT)
- {
- //双目运算符<
- if (curr.FirstChild == null)
- {
- throw new Exception("Lt operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
-
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Lt operator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Lt(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_LE)
- {
- //双目运算符<=
- if (curr.FirstChild == null)
- {
- throw new Exception("Le operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Le operator error:No second data");
-
- }
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Le(child.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_AND)
- {
- //双目运算符&&
- if (curr.FirstChild == null)
- {
- throw new Exception("And operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("And operator error:No second data");
-
- }
- while (child != null)
- {
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.And(child.Var, OnlyCheckDataType);
-
- child = child.NextBrother;
- }
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_OR)
- {
- //双目运算符||
- if (curr.FirstChild == null)
- {
- throw new Exception("Or operator error:No data");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- ExpressNode child = curr.FirstChild.NextBrother;
- if (child == null)
- {
- throw new Exception("Or operator error:No second data");
-
- }
- while (child != null)
- {
- ComputeNode(child, OnlyCheckDataType);
- curr.Var.Or(child.Var, OnlyCheckDataType);
-
- child = child.NextBrother;
- }
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_BIT_OR)
- {
- //双目运算符|
- throw new Exception("BitOr operator error:Not support");
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_BIT_AND)
- {
- //双目运算符&
- throw new Exception("BitAnd operator error:Not support");
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_MOVE_LEFT)
- {
- //双目运算符<<
- throw new Exception("Move left operator error:Not support");
- }
- else if (curr.NodeType == KeywordType.KW_OPERATOR_MOVE_RIGHT)
- {
- //双目运算符>>
- throw new Exception("Move right operator error:Not support");
- }
- else if (curr.NodeType == KeywordType.KW_ROUND_LEFT)
- {
- //左小括号
- if (curr.FirstChild == null)
- {
- throw new Exception("Move operator error:No data");
-
- }
- if (!curr.Closed)
- {
- throw new Exception("() not matched");
-
- }
- ComputeNode(curr.FirstChild, OnlyCheckDataType);
- curr.Var.CopyFrom(curr.FirstChild.Var, OnlyCheckDataType);
-
- return ;
- }
- else if (curr.NodeType == KeywordType.KW_FUNCTION)
- {
- //函数
-
- if (!curr.Closed)
- {
- throw new Exception("() not matched");
-
- }
- UserFunction function = curr.UserFunc;
- function(curr, OnlyCheckDataType);
- return;
- }
-
- else
- {
- throw new Exception("Undefined operator:"+ curr.NodeType);
-
- }
- }
-
- private void CreateMain(StringReader reader)
- {
-
- ExpressNode curr = Root;
- KeywordType kw;
- while ((kw = reader.Next()) != KeywordType.KW_EOF && kw != KeywordType.KW_SEP)
- {
- Trace("kw="+kw+","+reader.Data());
- if (kw == KeywordType.KW_CONST_INTEGER || kw == KeywordType.KW_CONST_DECIMAL ||
- kw == KeywordType.KW_CONST_TRUE || kw == KeywordType.KW_CONST_FALSE ||
- kw == KeywordType.KW_CONST_STRING)
- {
- Variable var;
- if (kw == KeywordType.KW_CONST_INTEGER)
- {
- var = new Variable(null, VariableDataType.DOUBLE);
- var.DoubleValue=(int.Parse(reader.Data()));
- }
- else if (kw == KeywordType.KW_CONST_DECIMAL)
- {
- var = new Variable(null, VariableDataType.DOUBLE);
- var.DoubleValue =(double.Parse(reader.Data()));
- }
- else if (kw == KeywordType.KW_CONST_TRUE)
- {
- var = new Variable(null, VariableDataType.BOOL);
- var.BoolValue=true;
- }
- else if (kw == KeywordType.KW_CONST_FALSE)
- {
- var = new Variable(null, VariableDataType.BOOL);
- var.BoolValue= false;
- }
- else
- {
- var = new Variable(null, VariableDataType.STRING);
- var.StringValue=reader.Data();
- }
- ExpressNode expressNode = new ExpressNode(var, null, KeywordType.KW_VARIABLE);
- if (curr == null)
- {
- curr = AddChild(curr, expressNode);
- }
- else
- {
- if (curr.NodeType == KeywordType.KW_VARIABLE || curr.Closed)
- {
- throw new Exception("Syntax error:Expected operator but const found in line:"+ reader.__line__);
-
-
- }
- curr = AddChild(curr, expressNode);
- }
- }
- else if (kw == KeywordType.KW_VARIABLE)
- {
- string varName = reader.Data();
- Variable var = null;
- if (Variables.ContainsKey(varName))
- {
- var = Variables[varName];
- }
- else
- {
- VariableDataType varType = ScriptVariables.GetVariableDataTypeByName(varName);
- var = new Variable(varName, varType);
- Variables.Add(varName, var);
- }
-
- ExpressNode expressNode = new ExpressNode(var, null, KeywordType.KW_VARIABLE);
- if (curr == null)
- {
- curr = AddChild(curr, expressNode);
- }
- else
- {
- if (curr.NodeType == KeywordType.KW_VARIABLE || curr.Closed)
- {
- throw new Exception("Syntax error:Expected operator but variable found:"+ reader.__line__);
-
- }
- curr = AddChild(curr, expressNode);
- }
- }
- else if (kw == KeywordType.KW_ROUND_LEFT)
- {
- Variable var = new Variable(null, VariableDataType.DOUBLE);
- ExpressNode expressNode = new ExpressNode(var, null, KeywordType.KW_ROUND_LEFT);
- if (curr == null)
- {
- curr = AddChild(curr, expressNode);
- }
- else
- {
- if (curr.NodeType == KeywordType.KW_VARIABLE || curr.Closed)
- {
- throw new Exception("Syntax error:Expected operator but '(' found:"+ reader.__line__);
- }
- curr = AddChild(curr, expressNode);
- }
- }
- else if (kw == KeywordType.KW_FUNCTION)
- {
- string funName = reader.Data();
- UserFunction function = GetFunAddr(funName);
- KeywordType kw2 = reader.Next();
- if (kw2 != KeywordType.KW_ROUND_LEFT)
- {
- throw new Exception("Syntax error:Expected '(' :"+ reader.__line__);
-
- }
- //g_log.info("funName=%s,addr=%d",funName,function);
- Variable var = new Variable(null, VariableDataType.DOUBLE);
- ExpressNode expressNode = new ExpressNode(var, function, KeywordType.KW_FUNCTION);
- if (curr == null)
- {
- curr = AddChild(curr, expressNode);
- }
- else
- {
- if (curr.NodeType == KeywordType.KW_VARIABLE || curr.Closed)
- {
- throw new Exception("Syntax error:Expected operator but function found:"+reader.__line__);
-
- }
- curr = AddChild(curr, expressNode);
- }
- }
- else if (kw == KeywordType.KW_ROUND_RIGHT)
- {
- while (curr != null)
- {
- if ((curr.NodeType == KeywordType.KW_FUNCTION || curr.NodeType == KeywordType.KW_ROUND_LEFT) && !curr.Closed)
- {
- break;
- }
- curr = curr.Father;
- }
- if (curr == null)
- {
- reader.rollback(KeywordType.KW_ROUND_RIGHT);
- return;
-
- }
- curr.Closed = true;
- }
- else if (kw == KeywordType.KW_OPERATOR_NEGATIVE || kw == KeywordType.KW_OPERATOR_NOT ||
- kw == KeywordType.KW_OPERATOR_BIT_NOT)
- {
- //single data operator
- Variable var = new Variable(null, VariableDataType.DOUBLE);
- ExpressNode expressNode = new ExpressNode(var, null, kw);
- if (curr == null)
- {
- curr = AddChild(curr, expressNode);
- }
- else
- {
- if (curr.NodeType == KeywordType.KW_VARIABLE || curr.Closed)
- {
- throw new Exception("Syntax error:Unexpected variable found:"+reader.__line__);
-
- }
- curr = AddChild(curr, expressNode);
- }
- }
- else if (kw == KeywordType.KW_OPERATOR_PLUS || kw == KeywordType.KW_OPERATOR_MINUS ||
- kw == KeywordType.KW_OPERATOR_MULTIPLE || kw == KeywordType.KW_OPERATOR_DEVIDE ||
- kw == KeywordType.KW_OPERATOR_AND || kw == KeywordType.KW_OPERATOR_BIT_AND ||
- kw == KeywordType.KW_OPERATOR_OR || kw == KeywordType.KW_OPERATOR_BIT_OR ||
- kw == KeywordType.KW_OPERATOR_GT || kw == KeywordType.KW_OPERATOR_GE ||
- kw == KeywordType.KW_OPERATOR_LT || kw == KeywordType.KW_OPERATOR_LE ||
- kw == KeywordType.KW_OPERATOR_EQUAL || kw == KeywordType.KW_OPERATOR_NOT_EQUAL ||
- kw == KeywordType.KW_OPERATOR_MOVE_LEFT || kw == KeywordType.KW_OPERATOR_MOVE_RIGHT || kw == KeywordType.KW_OPERATOR_COMMA)
- {
- //two data operator
- Variable var = new Variable(null, VariableDataType.DOUBLE);
- ExpressNode expressNode = new ExpressNode(var, null, kw);
- if (curr == null)
- {
- throw new Exception("Syntax error:Can not begin with a operator:"+reader.__line__);
- }
- int compare = -2;
- while (curr != null)
- {
- compare = -2;
- if (curr.Father == null)
- {
- break;
- }
- else if ((compare = curr.Father.ComparePrior(kw)) <= 0)
- {
- if (compare < -1)
- {
- throw new Exception("Syntax error:Unmatched operator:"+reader.__line__);
-
- }
- break;
- }
- curr = curr.Father;
- }
- if (curr.Father == null || compare == -1)
- {
- curr = AddFather(curr, expressNode);
- }
- else
- {
- //优先级相等
- curr = curr.Father;
- }
- }
- else
- {
- reader.rollback(kw);
- return ;
- }
- }
-
- //throw new Exception("Syntax error:Found unexpected EOF:"+ reader.__line__);
-
- }
-
- }
- }
|