Example #1
0
 /// <summary>
 /// AND
 /// </summary>
 /// <param name="left"></param>
 /// <param name="tbl"></param>
 /// <returns></returns>
 public static int and(Node[] nodes, Dictionary<string, int> row = null, Dictionary<string, int>[] tbl = null)
 {
     foreach (var node in nodes)
     {
         if (Node.Compute(node, row, tbl) == 0)
             return 0;
     }
     return 1;
 }
Example #2
0
        public void parse_関数_1項_1()
        {
            var node = new Node("SUM(2)");

            node.Parse();
            {
                Assert.True(node.Left.Expression       == "2");

            }
            Assert.True(node.Expression             == "SUM");
            Assert.True(node.Right                  == null);

            return;
        }
Example #3
0
        public void parse_関数_1項_2()
        {
            var node = new Node("SUM(-2)");

            node.Parse();
            Assert.True(node.Expression     == "SUM");
            Assert.True(node.Type           == NodeType.Function);
            Assert.True(node.Left.Expression    == "-");
            {
                Assert.True(node.Left.Left              == null);
                Assert.True(node.Left.Right.Expression  == "2");
            }
            Assert.True(node.Right              == null);
        }
Example #4
0
        public void parse_2項変数()
        {
            var node = new Node("2+abc");

            node.Parse();

            Assert.True(node.Left.Expression    == "2");
            Assert.True(node.Left.Type == NodeType.Constant);

            Assert.True(node.Expression         == "+");
            Assert.True(node.Type               == NodeType.Operator);

            Assert.True(node.Right.Expression   == "abc");
            Assert.True(node.Right.Type         == NodeType.Item);
            return;
        }
Example #5
0
        public void parse_4項カッコあり()
        {
            var node = new Node("(2+3+4)+5");

            node.Parse();
            {
                Assert.True(node.Left.Left.Expression  == "2");
                Assert.True(node.Left.Expression       == "+");
                {
                    Assert.True(node.Left.Right.Left.Expression  == "3");
                    Assert.True(node.Left.Right.Expression       == "+");
                    Assert.True(node.Left.Right.Right.Expression == "4");
                }

            }
            Assert.True(node.Expression             == "+");
            Assert.True(node.Right.Expression       == "5");
            return;
        }
Example #6
0
        public int 計算_カラム(string expression)
        {
            var row = new Dictionary<string, int>() { { "A", 1 }, { "B", 2 } };
            var tbl = new[]
                {
                    new Dictionary<string, int>() {{"A", 1}},
                    new Dictionary<string, int>() {{"A", 2}},
                    new Dictionary<string, int>() {{"A", 3}},
                };

            var node = new Node(expression);
            node.Parse();
            var ans = Node.Compute(node, row, tbl);
            return ans;
        }
Example #7
0
        public int 計算_if(string expression)
        {
            var row = new Dictionary<string, int>() { { "X", 4 }, { "Y", 2 } };
            var tbl = new[]
                {
                    new Dictionary<string, int>() {{"A", 1},{"B", 3}},
                    new Dictionary<string, int>() {{"A", 2},{"B", 6}},
                    new Dictionary<string, int>() {{"A", 3},{"B", 7}},
                };

            var node = new Node(expression);

            node.Parse();
            return Node.Compute(node, row, tbl);
        }
Example #8
0
        public int 計算(string expression)
        {
            var node = new Node(expression);

            node.Parse();
            //var ans = node.Compute();
            var ans = Node.Compute(node);
            return ans;
        }
Example #9
0
 public int 条件_less(string expression)
 {
     var node = new Node(expression);
     node.Parse();
     return Node.Compute(node);
 }
Example #10
0
        public void parse_2項()
        {
            var node = new Node("2+3");

            node.Parse();
            Assert.True(node.Left.Expression    == "2");
            Assert.True(node.Expression         == "+");
            Assert.True(node.Type               == NodeType.Operator);
            Assert.True(node.Right.Expression   == "3");
            return;
        }
Example #11
0
        public void parse_3項()
        {
            var node = new Node("2+3+4");

            node.Parse();
            Assert.True(node.Left.Expression  == "2");
            Assert.True(node.Expression       == "+");

            Assert.True(node.Right.Left.Expression  == "3");
            Assert.True(node.Right.Expression       == "+");
            Assert.True(node.Right.Right.Expression == "4");
            return;
        }
Example #12
0
        /// <summary>
        /// ツリー形式になっている関数の引数ノードを配列として返す
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public static Node[] GetArgumentNodes(Node root)
        {
            var nodes = new List<Node>();

            var node = root;
            while(true)
            {
                // 2回目以降(子要素)が関数型の場合もそれを最後として登録する
                if (node.Type == NodeType.Constant || node.Type == NodeType.Item ||
                    ( node.Type == NodeType.Operator && node.Expression != ",") ||
                    ( node.Type == NodeType.Function && node != root)
                    )
                {
                    nodes.Add(node);
                    break;
                }
                if (node.Left != null)
                {
                    nodes.Add(node.Left);
                }
                node = node.Right;
            }
            return nodes.ToArray();
        }
Example #13
0
        public void parse_1項_3()
        {
            var node = new Node("-2");

            node.Parse();
            Assert.True(node.Expression == "-");
            Assert.True(node.Right.Expression == "2");
            return;
        }
Example #14
0
        public void parse_関数引数取得2()
        {
            var node = new Node("SUM(2,3+4,-5)");

            node.Parse();
            var nodes = Node.GetArgumentNodes(node);

            Assert.True(nodes [ 0 ].Type        == NodeType.Constant);
            Assert.True(nodes [ 0 ].Expression  == "2");
            Assert.True(nodes [ 1 ].Type        == NodeType.Operator);
            Assert.True(nodes [ 1 ].Expression  == "+");
            {
                Assert.True(nodes [ 1 ].Left.Expression     == "3");
                Assert.True(nodes [ 1 ].Right.Expression    == "4");
            }
            Assert.True(nodes [ 2 ].Type        == NodeType.Operator);
            Assert.True(nodes [ 2 ].Expression  == "-");
            {
                Assert.True(nodes [ 2 ].Left                == null);
                Assert.True(nodes [ 2 ].Right.Expression    == "5");
            }
        }
Example #15
0
 /// <summary>
 /// IF
 /// </summary>
 /// <param name="left"></param>
 /// <param name="tbl"></param>
 /// <returns></returns>
 public static int iif(Node [] nodes, Dictionary<string, int> row = null, Dictionary<string, int>[] tbl = null)
 {
     var condition = Node.Compute(nodes[0], row, tbl);
     if (condition == 1)
     {
         return Node.Compute(nodes[1], row, tbl);
     }
     else
     {
         return Node.Compute(nodes[2], row, tbl);
     }
 }
Example #16
0
        public void parse_関数_3項()
        {
            var node = new Node("SUM(2,3+4,5)");

            node.Parse();
            Assert.True(node.Expression         == "SUM");
            Assert.True(node.Type               == NodeType.Function);
            Assert.True(node.Left.Expression    == "2");
            Assert.True(node.Right.Expression  == ",");
            {
                Assert.True(node.Right.Left.Expression  == "+");
                {
                    Assert.True(node.Right.Left.Left.Expression  == "3");
                    Assert.True(node.Right.Left.Right.Expression == "4");
                }
                Assert.True(node.Right.Right.Expression == "5");
            }

            var nodes = Node.GetArgumentNodes(node);
        }
Example #17
0
        public void parse_関数_2項()
        {
            var node = new Node("SUM(2,3)");

            node.Parse();
            Assert.True(node.Expression     == "SUM");
            Assert.True(node.Type           == NodeType.Function);
            Assert.True(node.Left.Expression  == "2");
            Assert.True(node.Right.Expression == "3");
        }
Example #18
0
        /// <summary>
        /// 比較「<」
        /// </summary>
        /// <param name="left"></param>
        /// <param name="tbl"></param>
        /// <returns></returns>
        public static int lt(Node left, Node right, Dictionary<string, int> row = null, Dictionary<string, int> [ ] tbl = null)
        {
            var leftVal  = Node.Compute(left,  row, tbl);
            var rightVal = Node.Compute(right, row, tbl);

            if (leftVal < rightVal)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
Example #19
0
        /// <summary>
        /// 式解析
        /// </summary>
        /// <remarks>再帰的に呼び出される</remarks>
        public void Parse()
        {
            int pos = GetOperatorPosition((this.Expression));

            // 符号として+-が指定されるケース
            if (pos == 0)
            {
                // TODO いきなり+-以外の演算子が出現したら異常
                this.Left       = null;
                this.Right      = new Node(this.Expression.Substring(pos + 1));
                this.Right.Parse();
                this.Expression = this.Expression[pos].ToString();
                this.Type       = NodeType.Operator;
            }
            // 「項 演算子 項」のケース
            else if (pos > 0)
            {
                this.Left       = new Node(this.Expression.Substring(0, pos));
                this.Left.Parse();
                this.Right      = new Node(this.Expression.Substring(pos+1));
                this.Right.Parse();
                this.Expression = this.Expression [ pos ].ToString();
                this.Type       = NodeType.Operator;
            }
            // 関数「Func(項・・・)」のケース
            else if (IsFunction(this.Expression) == true)
            {
                // 関数名だけをExpressionとして保存する。本当は属性を何か持ちたい
                var functionName = ( new Regex(@"^"+functionMatcher) ).Match(this.Expression).ToString();
                if (functionDictionary.ContainsKey(functionName) == false)
                {
                    throw new Exception("サポートされていない関数名が指定されています("+functionName+")");
                }
                else
                {
                    // 一旦オペランド部を解析する
                    var operandNode = new Node(Regex.Replace(Expression, @"^(" + functionMatcher +@")\((.+)\)$", "$2"));
                    operandNode.Parse();

                    // 多項の引数の場合
                    if (operandNode.Expression == ",")
                    {
                        this.Left  = operandNode.Left;
                        this.Right = operandNode.Right;
                    }
                    // 1項の引数の場合
                    else
                    {
                        this.Left = operandNode;
                        this.Right = null;
                    }
                    this.Expression = functionName;
                    this.Type       = NodeType.Function;
                }
            }
            // 式を含まないケース
            else
            {
                if((new Regex(@".*[^0-9].*")).IsMatch(this.Expression) )
                {
                    this.Type   = NodeType.Item;
                }else{
                    this.Type   = NodeType.Constant;
                }
            }
            return;
        }
Example #20
0
 /// <summary>
 /// 集合関数>累計
 /// </summary>
 /// <param name="item"></param>
 /// <param name="dic"></param>
 /// <returns></returns>
 public static int sum(Node left, Dictionary<string, int>[] tbl)
 {
     return (from n in tbl select Node.Compute(left, n)).Sum();
 }
Example #21
0
        public void parse_1項_1()
        {
            var node = new Node("2");

            node.Parse();
            Assert.True(node.Expression == "2");
            Assert.True(node.Type       == NodeType.Constant);
            return;
        }
Example #22
0
        /// <summary>
        /// 評価
        /// </summary>
        /// <param name="node"></param>
        /// <param name="row">親テーブルの一行</param>
        /// <param name="tbl">テーブル</param>
        /// <returns></returns>
        public static int Compute(Node node, Dictionary<string, int> row = null, Dictionary<string, int> [] tbl = null)
        {
            var ans = 0;

            // 無効ノード
            if (node.Expression == null || node.Type == NodeType.None)
            {
                return ans;
            }

            #region 特殊ケース
            // 関数処理
            if (node.Type == NodeType.Function)
            {
                if (node.Expression == "SUM")
                {
                    return Node.sum(node.Left, tbl);
                }
                else
                if (node.Expression == "lt")
                {
                    return Node.lt(node.Left, node.Right, row, tbl);
                }
                else
                if (node.Expression == "eq")
                {
                    return Node.eq(node.Left, node.Right, row, tbl);
                }
                else
                if (node.Expression == "gt")
                {
                    return Node.gt(node.Left, node.Right, row, tbl);
                }
                else
                if (node.Expression == "if")
                {
                    var nodes = GetArgumentNodes(node);
                    return Node.iif( nodes, row, tbl);
                }
                else
                if (node.Expression == "and")
                {
                    var nodes = GetArgumentNodes(node);
                    return Node.and( nodes, row, tbl);
                }
                else
                if (node.Expression == "or")
                {
                    var nodes = GetArgumentNodes(node);
                    return Node.or( nodes, row, tbl);
                }
                else
                {
                    throw new Exception("この関数は実装されていません("+node.Expression+")");
                }
            }

            // 行中のカラム指定
            if (node.Type == NodeType.Item)
            {
                return row[node.Expression];
            }
            #endregion

            // 左要素の評価
            if (node.Left != null)
            {
                ans = Compute(node.Left, row);
            }

            // 演算子に応じて評価
            if (node.Expression == "-")
            {
                ans -= Compute(node.Right, row);
            }
            else if (node.Expression == "+")
            {
                ans += Compute(node.Right, row);
            }
            else if (node.Expression == "/")
            {
                if (node.Right == null)
                {
                    throw new Exception("除算ですが項が不足しています");
                }
                ans /= Compute(node.Right, row);
            }
            else if (node.Expression == "*")
            {
                if (node.Right == null)
                {
                    throw new Exception("乗算ですが項が不足しています");
                }
                ans *= Compute(node.Right, row);
            }
            else
            {
                ans = int.Parse(node.Expression);
            }
            return ans;
        }