Exemple #1
0
        public ParserIssue[] TryParse(string text, out IContentExpression result)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            result = null;

            var tokens = _tokenizer.Tokenize(text);

            try
            {
                var q = new Queue <DslToken>(tokens);

                result = ParseExpression(q, t => false);

                return(new ParserIssue[] { });
            }
            catch (ParserException ex)
            {
                return(new ParserIssue[]
                {
                    new ParserIssue
                    {
                        CodeOrMessage = ex.Message,
                        Index = ex.Token?.Match.StartIndex ?? (text.Length - 1),
                        Value = ex.Token?.Value
                    }
                });
            }
        }
Exemple #2
0
        void Test(string text, IContentExpression expected)
        {
            var parser = new ContentExpressionParser(new Tokenizer());

            var issues = parser.TryParse(text, out IContentExpression actual);

            Assert.AreEqual(expected, actual);
        }
Exemple #3
0
        public RegexFilter(IContentExpression value, string regex)
        {
            if (regex == null)
            {
                throw new ArgumentNullException(nameof(regex));
            }

            Value = value ?? throw new ArgumentNullException(nameof(value));
            Regex = new Regex(regex, RegexOptions.Compiled);
        }
Exemple #4
0
 public EqualToFilter(IContentExpression left, IContentExpression right)
 {
     Left  = left ?? throw new ArgumentNullException(nameof(left));
     Right = right ?? throw new ArgumentNullException(nameof(right));
 }
Exemple #5
0
 public OfTypeFilter(IContentExpression value, ContentType contentType)
 {
     Value       = value ?? throw new ArgumentNullException(nameof(value));
     ContentType = contentType;
 }
Exemple #6
0
        IContentExpression ParseExpression(Queue <DslToken> q, Func <DslToken, bool> terminate)
        {
            IContentExpression exp = null;

            while (q.Count > 0)
            {
                var lookAhead = q.Peek();

                if (terminate(lookAhead))
                {
                    break;
                }

                else if (lookAhead.IsConstant())
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(Utils.ConstantTokens);
                    exp = CreateConstant(token);
                }

                else if (lookAhead.TokenType == TokenType.Equals)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Equals);
                    exp = new EqualToFilter(exp,
                                            ParseExpression(q, t => t.TokenType == TokenType.And || t.TokenType == TokenType.Or || terminate(t)));
                }

                else if (lookAhead.TokenType == TokenType.Contains)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Contains);
                    exp = new ContainsFilter(exp,
                                             ParseExpression(q, t => t.TokenType == TokenType.And || t.TokenType == TokenType.Or || terminate(t)));
                }

                else if (lookAhead.TokenType == TokenType.MatchRegex)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token   = q.DequeueAndValidate(TokenType.MatchRegex);
                    var pattern = q.DequeueAndValidate(TokenType.String);
                    exp = new RegexFilter(exp, pattern.Value);
                }

                else if (lookAhead.TokenType == TokenType.And)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.And);
                    if (exp is IContentFilter leftBool)
                    {
                        var right = ParseExpression(q, terminate);
                        if (right is IContentFilter rightBool)
                        {
                            exp = new AndFilter(leftBool, rightBool);
                        }
                        else
                        {
                            throw new ParserException("AND cannot have a right operand that does not yield boolean", token);
                        }
                    }
                    else
                    {
                        throw new ParserException("AND cannot have a left operand that does not yield boolean", token);
                    }
                }

                else if (lookAhead.TokenType == TokenType.Or)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Or);
                    if (exp is IContentFilter leftBool)
                    {
                        var right = ParseExpression(q, terminate);
                        if (right is IContentFilter rightBool)
                        {
                            exp = new OrFilter(leftBool, rightBool);
                        }
                        else
                        {
                            throw new ParserException("OR cannot have a right operand that does not yield boolean", token);
                        }
                    }
                    else
                    {
                        throw new ParserException("OR cannot have a left operand that does not yield boolean", token);
                    }
                }

                else if (lookAhead.TokenType == TokenType.Path)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Path);
                    exp = new PathExpression(exp, ContentPath.Parse($"$.{token.Value.TrimStart('.')}"));
                }

                else if (lookAhead.TokenType == TokenType.DollarSign)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    q.DequeueAndValidate(TokenType.DollarSign);
                    exp = new ScopeRootExpression();
                }

                else if (lookAhead.TokenType == TokenType.OpenCurly)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    exp = CreateObjectExpression(q);
                }

                else if (lookAhead.TokenType == TokenType.OpenSquareBracket)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    exp = CreateListExpression(q);
                }

                else if (lookAhead.TokenType == TokenType.OpenBracket)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    q.DequeueAndValidate(TokenType.OpenBracket);  // open bracket (
                    exp = ParseExpression(q, t => t.TokenType == TokenType.CloseBracket);
                    q.DequeueAndValidate(TokenType.CloseBracket); // close bracket )
                }
                else
                {
                    throw new ParserException($"Unexpected token", lookAhead);
                }
            }

            if (exp == null)
            {
                throw new ParserException($"Unexpected end", null);
            }

            return(exp);
        }
 public ContainsWhereFilter(IContentExpression list, IContentFilter item)
 {
     List       = list ?? throw new ArgumentNullException(nameof(list));
     ItemFilter = item ?? throw new ArgumentNullException(nameof(item));
 }