Exemple #1
0
        /// <summary>
        /// Do operation on operator and value stacks.
        /// </summary>
        /// <param name="operators">Operator stack.</param>
        /// <param name="values">Value stack.</param>
        /// <param name="express">Express list.</param>
        private static void Operate(Stack<OperatorSerial> operators,
            Stack<OperatorSerial> values, List<OperatorSerial> express)
        {
            OperatorSerial x = operators.Pop();

            OperatorSerial a = values.Pop();

            if (x.Code == (int)Logic.Not)
            {
                x.Flag = a.Flag;
                x.LeftOp = a.LeftOp;
            }
            else
            {
                OperatorSerial b = values.Pop();

                x.Flag = (short)((ushort)b.Flag | ((ushort)a.Flag << 1));
                x.LeftOp = b.LeftOp;
                x.RightOp = a.LeftOp;
            }

            express.Add(x);

            // push result to the values stack
            OperatorSerial value = new OperatorSerial();
            value.Flag = (short)(value.Flag & ~OP_LEFT_FEATURE);
            value.LeftOp = (int)(express.Count - 1);
            values.Push(value);
        } 
Exemple #2
0
 /// <summary>
 /// Equal.
 /// </summary>
 /// <param name="other">Other object to compare with.</param>
 /// <returns>True if equal, otherwise false.</returns>
 public bool Equals(OperatorSerial other)
 {
     return Code == other.Code
             && Flag == other.Flag
             && LeftOp == other.LeftOp
             && RightOp == other.RightOp;
 }
Exemple #3
0
        internal const short OP_RIGHT_FEATURE = 0x02;  // bit1=1 : right operand is feature
        // bit1=0 : position of operator
        #endregion

        #region Static operatons

        /// <summary>
        /// Convert expresses as logical string, for example:
        /// <![CDATA[ 10|~20&30 ]]>.
        /// </summary>
        /// <param name="startPosition">First logical operator to take.</param>
        /// <param name="express">Express list.</param>
        /// <returns>Logic string.</returns>
        public static string ToString(int startPosition, OperatorSerial[] express)
        {
            if (express == null)
            {
                throw new ArgumentNullException("express");
            }

            if (express.Length == 0 || startPosition >= express.Length)
            {
                return string.Empty;
            }

            OperatorSerial opr = express[startPosition];

            if (opr.Code == (int)Logic.End)
            {
                return string.Empty;
            }

            if (opr.Code == (int)Logic.Value)
            {
                return opr.LeftOp.ToString(CultureInfo.InvariantCulture);
            }

            string leftOp;
            if ((opr.Flag & OP_LEFT_FEATURE) != 0)
            {
                leftOp = opr.LeftOp.ToString(CultureInfo.InvariantCulture);
            }
            else
            {
                leftOp = ToString(opr.LeftOp, express);
            }

            if (opr.Code == (int)Logic.Not)
            {
                uint temp = (uint)(opr.Flag & OP_LEFT_FEATURE);
                if (temp > 0 || (temp == 0 && express[opr.LeftOp].Code == (int)Logic.Not))
                {
                    return "~" + leftOp;
                }
                else
                {
                    return "~(" + leftOp + ")";
                }
            }

            string rightOp;
            if ((opr.Flag & OP_RIGHT_FEATURE) != 0)
            {
                rightOp = opr.RightOp.ToString(CultureInfo.InvariantCulture);
            }
            else
            {
                rightOp = ToString(opr.RightOp, express);
            }

            if (opr.Code == (int)Logic.And)
            {
                uint temp = (uint)(opr.Flag & OP_LEFT_FEATURE);
                if (temp == 0 && express[opr.LeftOp].Code == (int)Logic.Or)
                {
                    leftOp = "(" + leftOp + ")";
                }

                temp = (uint)(opr.Flag & OP_RIGHT_FEATURE);
                if (temp == 0 && (express[opr.RightOp].Code == (int)Logic.Or
                    || express[opr.RightOp].Code == (int)Logic.And))
                {
                    rightOp = "(" + rightOp + ")";
                }

                return leftOp + "&" + rightOp;
            }
            else
            {
                uint temp = (uint)(opr.Flag & OP_RIGHT_FEATURE);
                if (temp == 0 && express[opr.RightOp].Code == (int)Logic.Or)
                {
                    rightOp = "(" + rightOp + ")";
                }

                return leftOp + "|" + rightOp;
            }
        }
Exemple #4
0
        /// <summary>
        /// Parse logical string to operators.
        /// </summary>
        /// <param name="logic">Logic string.</param>
        /// <returns>Operators.</returns>
        public static OperatorSerial[] Parse(string logic)
        {
            if (string.IsNullOrEmpty(logic))
            {
                throw new ArgumentNullException("logic");
            }

            List<OperatorSerial> express = new List<OperatorSerial>();
            Stack<OperatorSerial> operators = new Stack<OperatorSerial>();
            Stack<OperatorSerial> values = new Stack<OperatorSerial>();

            OperatorSerial op;
            int index = 0;
            while (logic.Length > index)
            {
                op = new OperatorSerial();
                while (logic[index] == ' ')
                {
                    index++;
                }

                if (logic[index] == '~')
                {
                    op.Code = (int)Logic.Not;
                    operators.Push(op);
                }
                else if (logic[index] == '|')
                {
                    DoHighPriorOperation(operators, values, (int)Logic.Or, express);
                    op.Code = (int)Logic.Or;
                    operators.Push(op);
                }
                else if (logic[index] == '&')
                {
                    DoHighPriorOperation(operators, values, (int)Logic.And, express);
                    op.Code = (int)Logic.And;
                    operators.Push(op);
                }
                else if (logic[index] == '(')
                {
                    op.Code = (int)Logic.Bracket;
                    operators.Push(op);
                }
                else if (logic[index] == ')')
                {
                    DoBracketOperation(operators, values, express);
                }
                else if (logic[index] >= '0' && logic[index] <= '9')
                {
                    op.Code = (int)Logic.Value;
                    op.Flag = (short)OP_LEFT_FEATURE;
                    op.LeftOp = ParseInt(logic, ref index);
                    values.Push(op);

                    DoHighPriorOperation(operators, values, (int)Logic.Not, express);

                    index--;
                }
                else
                {
                    Debug.Assert(false);
                    string message = string.Format(CultureInfo.InvariantCulture,
                        "Invalid logic express [{0}] found.", logic[index]);
                    throw new InvalidDataException(message);
                }

                index++;
            }

            while (operators.Count > 0)
            {
                Operate(operators, values, express);
            }

            op = new OperatorSerial();

            if (values.Count > 0 && values.Peek().Flag == OP_LEFT_FEATURE)
            {
                op = values.Peek();
                express.Add(op);
            }

            return express.ToArray();
        }
Exemple #5
0
        /// <summary>
        /// Load a Cart Node from bindary stream, which is Mulan CRT compatible.
        /// </summary>
        /// <param name="br">Binary reader to load CART node.</param>
        public void Load(BinaryReader br)
        {
            if (br == null)
            {
                throw new ArgumentNullException("br");
            }

            try
            {
                br.ReadInt32(); // Skip the yes child's offset
                br.ReadInt32(); // Skip the no child's offset
                NodeType noteType = (NodeType)br.ReadInt32();

                if (noteType == NodeType.NotLeaf)
                {
                    _question = new Question(_metaCart);
                    uint size = br.ReadUInt32();
                    int startPos = br.ReadInt32();
                    OperatorSerial[] express = new OperatorSerial[size];
                    for (uint i = 0; i < size; i++)
                    {
                        express[i] = OperatorSerial.Read(br);
                    }

                    // TODO: parse it into logical presentation
                    string logic = OperatorSerial.ToString(startPos, express);
                    _question.Parse(logic);

                    _leftChild = new CartNode(_metaCart);
                    _leftChild.Load(br);
                    _leftChild.Parent = this;

                    _rightChild = new CartNode(_metaCart);
                    _rightChild.Load(br);
                    _rightChild.Parent = this;

                    QuestionLogic = _question.ToString();
                }
                else if (noteType == NodeType.Leaf)
                {
                    // AbstractSet
                    int setType = br.ReadInt32();
                    Debug.Assert(setType == (int)SetType.AbstractSet);

                    int minValue = br.ReadInt32();
                    int maxValue = br.ReadInt32();

                    Debug.Assert(maxValue >= minValue);

                    setType = br.ReadInt32();
                    _setType = (SetType)setType;
                    switch (_setType)
                    {
                        case SetType.BitSet:
                            {
                                // BitSet
                                int size = br.ReadInt32();
                                Debug.Assert(size == maxValue - minValue + 1);

                                int setCount = br.ReadInt32();

                                // calculate the number of bytes to allocate to save
                                // the bit set data. the data is INT (4 bytes) aligned
                                int bytesRequired = ((size + 31) >> 5) * 4;

                                byte[] bits = br.ReadBytes(bytesRequired);
                                if (bits.Length != bytesRequired)
                                {
                                    string message = string.Format(CultureInfo.InvariantCulture,
                                    "Malformed data found, for there is no enough data for Bit set.");
                                    throw new InvalidDataException(message);
                                }

                                _unitSet = new BitArray(bits);
                                _unitSet.Length = size;
                                int loadSetCount = 0;
                                for (int k = 0; k < _unitSet.Length; k++)
                                {
                                    loadSetCount += _unitSet.Get(k) ? 1 : 0;
                                }

                                Debug.Assert(loadSetCount == setCount);
                            }

                            break;
                        case SetType.IndexSet:
                            {
                                // Count of integer
                                int size = br.ReadInt32();

                                // Index data
                                _unitSet = new BitArray(maxValue - minValue + 1);
                                _unitSet.SetAll(false);
                                int n = 0;
                                for (int i = 0; i < size; i++)
                                {
                                    n = br.ReadInt32();
                                    if (n > _unitSet.Length - 1 || n < 0)
                                    {
                                        throw new InvalidDataException("Invalid index set data");
                                    }

                                    _unitSet.Set(n, true);
                                }
                            }

                            break;
                        default:
                            {
                                throw new InvalidDataException("Invalid set type");
                            }
                    }
                }
                else
                {
                    Debug.Assert(false);
                    string message = string.Format(CultureInfo.InvariantCulture,
                        "Invalid node type [{0}] of CART tree node found", noteType);
                    throw new InvalidDataException(message);
                }
            }
            catch (EndOfStreamException ese)
            {
                string message = string.Format(CultureInfo.InvariantCulture,
                    "Fail to CART tree node from binary stream for invalid data.");
                throw new InvalidDataException(message, ese);
            }
            catch (InvalidDataException ide)
            {
                string message = string.Format(CultureInfo.InvariantCulture,
                        "Fail to load CART node from binary stream");
                throw new InvalidDataException(message, ide);
            }
        }