Ejemplo n.º 1
0
        public void TestConditionParserInvalidConditions()
        {
            var conditionTests = new string[]
            {
                "$123",                     // Property names cannot start with a number
                "$_123",                    // Property names cannot start with an underscore
                "$1.23",                    // Property names cannot contain special characters
                "horizontal||$Prop[gt]1000",// OR is '|', not '||'
                "$Prop==1||$Prop==2"        // OR is '|', not '||'
            };

            var parseContext = new ParseContext();
            ConditionParser parser = new ConditionParser(new ConditionFormat() { StatesUnderscored = false });
            foreach (var test in conditionTests)
            {
                try
                {
                    parser.Parse(test, parseContext);
                    Assert.Fail("Parsing {0} succeeded", test);
                }
                catch
                {
                }
            }
        }
        public IConditionTreeItem Parse(string input, ParseContext context)
        {
            var andList = new Stack<ConditionTreeLeaf>();

            string[] conditions = input.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string condition in conditions)
                andList.Push(ParseLeaf(condition, context));

            return LegacyConditionParser.AndListToTree(andList);
        }
Ejemplo n.º 3
0
        public void TestConditionParserValidConditions()
        {
            var horizontal = new ConditionTreeLeaf(ConditionType.State, "horizontal", ConditionComparison.Equal, new PropertyUnion(true));
            var propertyEq1 = new ConditionTreeLeaf(ConditionType.Property, "Property", ConditionComparison.Equal, new PropertyUnion(1));

            var conditionTests = new Dictionary<string, IConditionTreeItem>()
            {
                { "horizontal", horizontal},
                { "$Property==1", propertyEq1},
                { "horizontal|$Property==1", new ConditionTree(ConditionTree.ConditionOperator.OR, horizontal, propertyEq1)},
                { "horizontal,$Property==1", new ConditionTree(ConditionTree.ConditionOperator.AND, horizontal, propertyEq1)}
            };

            var parseContext = new ParseContext();
            parseContext.PropertyTypes.Add(new KeyValuePair<string,PropertyUnionType>("Property", PropertyUnionType.Double));

            ConditionParser parser = new ConditionParser(new ConditionFormat() { StatesUnderscored = false });
            foreach(var test in conditionTests)
            {
                var parsed = parser.Parse(test.Key, parseContext);
                Assert.AreEqual(test.Value, parsed);
            }
        }
Ejemplo n.º 4
0
 public LoadContext()
 {
     Errors = new List<LoadError>();
     ParseContext = new ParseContext();
 }
Ejemplo n.º 5
0
        public IConditionTreeItem Parse(string input, ParseContext context)
        {
            // Tokenize

            var output = new Queue<ConditionToken>();
            var operators = new Stack<ConditionToken>();

            var reader = new PositioningReader(new StringReader(input));
            ConditionToken? token = ReadToken(reader);
            while (token.HasValue)
            {
                ConditionToken t = token.Value;

                if (t.Type == ConditionToken.TokenType.Symbol)
                    output.Enqueue(t);
                else if (t.Type == ConditionToken.TokenType.LeftBracket)
                    operators.Push(t);
                else if (t.Type == ConditionToken.TokenType.RightBracket)
                {
                    ConditionToken n = operators.Pop();
                    while (n.Type != ConditionToken.TokenType.LeftBracket)
                    {
                        if (operators.Count == 0)
                        {
                            // Not enough operators
                            throw new ConditionFormatException("Syntax error", 0, 0);
                        }

                        output.Enqueue(n);
                        n = operators.Pop();
                    }
                    if (operators.Count > 0 && operators.Peek() == ConditionToken.AND)
                        output.Enqueue(operators.Pop());
                }
                else if (t == ConditionToken.AND)
                {
                    while (operators.Count > 0 && (operators.Peek() == ConditionToken.AND || operators.Peek() == ConditionToken.OR))
                    {
                        output.Enqueue(operators.Pop());
                    }
                    operators.Push(t);
                }
                else if (t == ConditionToken.OR)
                {
                    while (operators.Count > 0 &&
                        (operators.Peek().Type == ConditionToken.TokenType.Operator && operators.Peek().Operator == ConditionToken.OperatorType.OR))
                    {
                        output.Enqueue(operators.Pop());
                    }
                    operators.Push(t);
                }

                token = ReadToken(reader);
            }

            while (operators.Count > 0)
                output.Enqueue(operators.Pop());

            // Convert to tree
            Queue<ConditionToken> reversed = new Queue<ConditionToken>(output.Reverse());
            return (ParseToken(reversed, context) as IConditionTreeItem);
        }
Ejemplo n.º 6
0
        private IConditionTreeItem ParseToken(Queue<ConditionToken> r, ParseContext context)
        {
            if (r.Count == 0)
                throw new ConditionFormatException("Invalid condition", 0, 0);

            ConditionToken t = r.Dequeue();
            if (t.Type == ConditionToken.TokenType.Symbol)
                return ParseLeaf(t, context);
            else if (t.Type == ConditionToken.TokenType.Operator && t.Operator == ConditionToken.OperatorType.AND)
            {
                IConditionTreeItem right = ParseToken(r, context);
                IConditionTreeItem left = ParseToken(r, context);

                return new ConditionTree(
                    ConditionTree.ConditionOperator.AND,
                    left,
                    right);
            }
            else if (t.Type == ConditionToken.TokenType.Operator && t.Operator == ConditionToken.OperatorType.OR)
            {
                IConditionTreeItem right = ParseToken(r, context);
                IConditionTreeItem left = ParseToken(r, context);

                return new ConditionTree(
                    ConditionTree.ConditionOperator.OR,
                    left,
                    right);
            }
            else
                throw new ArgumentException("Invalid queue.", "r");
        }
Ejemplo n.º 7
0
        private ConditionTreeLeaf ParseLeaf(ConditionToken token, ParseContext context)
        {
            bool isNegated;
            bool isState;
            string property;
            string comparisonStr;
            string compareToStr;
            SplitLeaf(token, out isNegated, out isState, out property, out comparisonStr, out compareToStr);

            if (compareToStr == String.Empty)
                compareToStr = "true"; // Implicit true

            ConditionComparison comparison;
            switch(comparisonStr)
            {
                case "==":
                    comparison = ConditionComparison.Equal;
                    break;
                case "!=":
                    comparison = ConditionComparison.NotEqual;
                    break;
                case "[gt]":
                    comparison = ConditionComparison.Greater;
                    break;
                case "[lt]":
                    comparison = ConditionComparison.Less;
                    break;
                case "[gteq]":
                    comparison = ConditionComparison.GreaterOrEqual;
                    break;
                case "[lteq]":
                    comparison = ConditionComparison.LessOrEqual;
                    break;
                default:
                    comparison = ConditionComparison.Equal;
                    break;
            }

            if (isNegated && comparison == ConditionComparison.Equal)
                comparison = ConditionComparison.NotEqual;
            else if (isNegated)
            {
                // Operator cannot be negated
                throw new ConditionFormatException("Comparison cannot be negated (illegal '!')", token.Position, token.Symbol.Length);
            }

            if (isState)
            {
                if (!legalStateNames.Contains(property))
                    throw new ConditionFormatException(String.Format("Unknown component state '{0}'", property), token.Position, token.Symbol.Length);

                return new ConditionTreeLeaf(ConditionType.State, property, comparison, new PropertyUnion(compareToStr, PropertyUnionType.Boolean));
            }
            else
            {
                PropertyUnionType propertyType;
                if (!context.PropertyTypes.TryGetValue(property, out propertyType))
                    throw new ConditionFormatException(String.Format("Unknown property '{0}'", property), token.Position, token.Symbol.Length);

                return new ConditionTreeLeaf(ConditionType.Property, property, comparison, new PropertyUnion(compareToStr, propertyType));
            }
        }
        private ConditionTreeLeaf ParseLeaf(string value, ParseContext context)
        {
            ConditionType type;
            if (value.IndexOf("_") <= 1 && value.IndexOf("_") != -1)
                type = ConditionType.State;
            else
                type = ConditionType.Property;

            ConditionComparison comparisonType = ConditionComparison.Equal;
            Regex ltCheck = new Regex("\\(lt_[0-9.]+\\)");
            Match ltMatch = ltCheck.Match(value);
            Regex gtCheck = new Regex("\\(gt_[0-9.]+\\)");
            Match gtMatch = gtCheck.Match(value);
            Regex eqCheck = new Regex("\\(eq_[a-zA-Z0-9.]+\\)");
            Match eqMatch = eqCheck.Match(value);
            Regex lteqCheck = new Regex("\\(lteq_[0-9.]+\\)");
            Match lteqMatch = lteqCheck.Match(value);
            Regex gteqCheck = new Regex("\\(gteq_[0-9.]+\\)");
            Match gteqMatch = gteqCheck.Match(value);
            Regex emptyCheck = new Regex("\\(empty\\)");
            Match emptyMatch = emptyCheck.Match(value);

            string compareTo = "true";
            if (ltMatch.Success)
            {
                comparisonType = ConditionComparison.Less;
                compareTo = ltMatch.Value.Replace("(lt_", "").Replace(")", "");
            }
            else if (gtMatch.Success)
            {
                comparisonType = ConditionComparison.Greater;
                compareTo = gtMatch.Value.Replace("(gt_", "").Replace(")", "");
            }
            else if (eqMatch.Success)
            {
                compareTo = eqMatch.Value.Replace("(eq_", "").Replace(")", "");
            }
            else if (lteqMatch.Success)
            {
                comparisonType = ConditionComparison.LessOrEqual;
                compareTo = lteqMatch.Value.Replace("(lteq_", "").Replace(")", "");
            }
            else if (gteqMatch.Success)
            {
                comparisonType = ConditionComparison.GreaterOrEqual;
                compareTo = gteqMatch.Value.Replace("(gteq_", "").Replace(")", "");
            }
            else if (emptyMatch.Success)
            {
                comparisonType = ConditionComparison.Empty;
                compareTo = "";
            }

            if (value.StartsWith("!"))
            {
                if (comparisonType == ConditionComparison.Equal)
                    comparisonType = ConditionComparison.NotEqual;
                else if (comparisonType == ConditionComparison.NotEqual)
                    comparisonType = ConditionComparison.Equal;
                else if (comparisonType == ConditionComparison.Empty)
                    comparisonType = ConditionComparison.NotEmpty;
            }

            string variableName = Regex.Match(value, "\\$[a-zA-Z]+").Value.Replace("$", "").Replace("!", "");
            if (type == ConditionType.State)
                variableName = value.Replace("_", "").Replace("!", "").ToLowerInvariant();

            var propertyType = PropertyUnionType.Boolean;
            if (type == ConditionType.Property && !context.PropertyTypes.TryGetValue(variableName, out propertyType))
                throw new ConditionFormatException(String.Format("Unknown property '{0}'", variableName), 0, 0);

            return new ConditionTreeLeaf(type, variableName, comparisonType, new PropertyUnion(compareTo, propertyType));
        }