예제 #1
0
        public IEnumerable <Binding> ResolveAll(SymbolExpression collection, out string[] missingTokens)
        {
            var val = WalkTo(collection, out missingTokens);

            if (val == null)
            {
                return(Enumerable.Empty <Binding>());
            }

            if (val.Indexable.Count != 0)
            {
                return(val.Indexable.Select(c => c.Value));
            }

            if (val.Item == null)
            {
                return(Enumerable.Empty <Binding>());
            }

            Binding[] bindings;
            if (JsonParser.TryParse(new Binding(val.Item), out bindings))
            {
                return(bindings);
            }

            return(val.Item.Split(',').Select(s => new Binding(s)));
        }
예제 #2
0
        public string Resolve(SymbolExpression expression, out string[] missingTokens)
        {
            var val = WalkTo(expression, out missingTokens);

            if (val == null)
            {
                return("");
            }
            return(val.Item ?? "");
        }
예제 #3
0
        internal static bool TryParseIdentifierPath(string path, out SymbolExpression expression)
        {
            var result = Symbol.TryParse(path);

            if (result.WasSuccessful)
            {
                expression = result.Value;
                return(true);
            }
            expression = null;
            return(false);
        }
예제 #4
0
        private void ValidateThatRecursionIsNotOccuring(SymbolExpression expression)
        {
            var ancestor = this;

            while (ancestor != null)
            {
                if (ancestor.symbolStack.Contains(expression, SymbolExpression.StepsComparer))
                {
                    throw new RecursiveDefinitionException(expression, ancestor.symbolStack);
                }
                ancestor = ancestor.parent;
            }
        }
예제 #5
0
        private void ValidateNoRecursion(SymbolExpression expression)
        {
            var ancestor = this;

            while (ancestor != null)
            {
                if (ancestor.symbolStack.Contains(expression))
                {
                    throw new InvalidOperationException(string.Format("An attempt to parse the variable symbol \"{0}\" appears to have resulted in a self referencing loop. Ensure that recursive loops do not exist in the variable values.", expression));
                }
                ancestor = ancestor.parent;
            }
        }
예제 #6
0
        private void ValidateThatRecursionIsNotOccuring(SymbolExpression expression)
        {
            var ancestor = this;

            while (ancestor != null)
            {
                if (ancestor.symbolStack.Contains(expression, SymbolExpression.StepsComparer))
                {
                    throw new InvalidOperationException(string.Format("An attempt to parse the variable symbol \"{0}\" appears to have resulted in a self referencing loop ({1}). Ensure that recursive loops do not exist in the variable values.",
                                                                      expression, string.Join(" -> ", ancestor.symbolStack.Select(x => x.ToString()))));
                }
                ancestor = ancestor.parent;
            }
        }
예제 #7
0
        private SymbolExpression CopyExpression(SymbolExpression expression)
        {
            //any indexers that are lookups, do them now so we are in the right context
            //take a copy so the lookup version remains for later use
            return(new SymbolExpression(expression.Steps.Select(s =>
            {
                if (s is Indexer indexer && indexer.IsSymbol)
                {
                    var index = WalkTo(indexer.Symbol !, out string[] _);

                    return index == null
                        ? new Indexer(CopyExpression(indexer.Symbol !))
                        : new Indexer(index.Item);
                }
                return s;
            })));
        }
예제 #8
0
 public ConditionalSymbolExpressionToken(SymbolExpression leftSide, bool eq, SymbolExpression rightSide) : base(leftSide)
 {
     Equality  = eq;
     RightSide = rightSide;
 }
예제 #9
0
 public ConditionalExpressionToken(SymbolExpression leftSide)
 {
     LeftSide = leftSide;
 }
예제 #10
0
        Binding WalkTo(SymbolExpression expression, out string[] missingTokens)
        {
            ValidateNoRecursion(expression);
            symbolStack.Push(expression);

            try
            {
                var val = binding;
                missingTokens = new string[0];

                //any indexers that are lookups, do them now so we are in the right context
                //take a copy so the lookup version remains for later use
                expression = new SymbolExpression(expression.Steps.Select(s =>
                {
                    var indexer = s as Indexer;
                    if (indexer != null && indexer.IsSymbol)
                    {
                        string[] missing;
                        var index = WalkTo(indexer.Symbol, out missing);
                        return(new Indexer(index.Item));
                    }
                    return(s);
                }));

                foreach (var step in expression.Steps)
                {
                    var iss = step as Identifier;
                    if (iss != null)
                    {
                        if (val.TryGetValue(iss.Text, out val))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        var ix = step as Indexer;
                        if (ix != null && !ix.IsSymbol)
                        {
                            if (ix.Index == "*" && val.Indexable.Count > 0)
                            {
                                val = val.Indexable.First().Value;
                                continue;
                            }

                            if (val.Indexable.TryGetValue(ix.Index, out val))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            throw new NotImplementedException("Unknown step type: " + step);
                        }
                    }

                    if (parent == null)
                    {
                        return(null);
                    }

                    return(parent.WalkTo(expression, out missingTokens));
                }

                if (val != null && val.Item != null)
                {
                    Template template;
                    string   error;
                    if (TemplateParser.TryParseTemplate(val.Item, out template, out error))
                    {
                        using (var x = new StringWriter())
                        {
                            var context = new EvaluationContext(new Binding(), x, this);
                            TemplateEvaluator.Evaluate(template, context, out missingTokens);
                            x.Flush();
                            return(new Binding(x.ToString()));
                        }
                    }
                }

                return(val);
            }
            finally
            {
                symbolStack.Pop();
            }
        }
예제 #11
0
 public Indexer(SymbolExpression expression)
 {
     Symbol = expression;
 }
예제 #12
0
 public AnalysisContext BeginChild(Identifier ident, SymbolExpression expan)
 {
     return(new AnalysisContext(this, ident, expan));
 }
예제 #13
0
 public string Expand(SymbolExpression expression)
 {
     return(new SymbolExpression(Expand(expression.Steps)).ToString());
 }
예제 #14
0
 AnalysisContext(AnalysisContext parent, Identifier identifier, SymbolExpression expansion)
 {
     this.parent     = parent;
     this.identifier = identifier;
     this.expansion  = expansion;
 }
예제 #15
0
 internal RecursiveDefinitionException(SymbolExpression symbol, Stack <SymbolExpression> ancestorSymbolStack)
     : base($"An attempt to parse the variable symbol \"{symbol}\" appears to have resulted in a self referencing " +
            $"loop ({string.Join(" -> ", ancestorSymbolStack.Reverse().Select(x => x.ToString()))} -> {symbol}). " +
            $"Ensure that recursive loops do not exist in the variable values.")
 {
 }
예제 #16
0
        public string?ResolveOptional(SymbolExpression expression, out string[] missingTokens)
        {
            var val = WalkTo(expression, out missingTokens);

            return(val?.Item);
        }
예제 #17
0
        Binding?WalkTo(SymbolExpression expression, out string[] missingTokens)
        {
            ValidateThatRecursionIsNotOccuring(expression);
            symbolStack.Push(expression);

            try
            {
                Binding?val = binding;
                missingTokens = new string[0];

                expression = CopyExpression(expression);

                foreach (var step in expression.Steps)
                {
                    var iss = step as Identifier;
                    if (iss != null)
                    {
                        Binding?newVal;
                        if (val.TryGetValue(iss.Text, out newVal))
                        {
                            val = newVal;
                            continue;
                        }

                        if (TryCustomParsers(val, iss.Text, out newVal))
                        {
                            val = newVal;
                            continue;
                        }
                    }
                    else
                    {
                        if (step is Indexer ix)
                        {
                            if (ix.IsSymbol || ix.Index == null)
                            {
                                // Substitution should have taken place in previous CopyExpression above.
                                // If not then it must not be found.
                                return(null);
                            }

                            if (ix.Index == "*" && val?.Indexable.Count > 0)
                            {
                                val = val.Indexable.First().Value;
                                continue;
                            }

                            if (val != null && val.Indexable.TryGetValue(ix.Index, out Binding? newVal))
                            {
                                val = newVal;
                                continue;
                            }

                            if (val != null && TryCustomParsers(val, ix.Index, out newVal))
                            {
                                val = newVal;
                                continue;
                            }
                        }
                        else
                        {
                            throw new NotImplementedException("Unknown step type: " + step);
                        }
                    }

                    if (parent == null)
                    {
                        return(null);
                    }

                    return(parent.WalkTo(expression, out missingTokens));
                }
                return(ParseTemplate(val, out missingTokens));
            }
            finally
            {
                symbolStack.Pop();
            }
        }
예제 #18
0
 public RepetitionToken(SymbolExpression collection, Identifier enumerator, IEnumerable <TemplateToken> template)
 {
     this.collection = collection;
     this.enumerator = enumerator;
     this.template   = template.ToArray();
 }