public static TemplateExpression Parse(ExpressionWalker ew)
        {
            ew.IsCurrentOrThrow(ExpressionToken.Template);
            ew.NextOrThrow();

            // ReSharper disable once UseObjectOrCollectionInitializer
            var ret = new TemplateExpression();

            ew.IsCurrentOrThrow(ExpressionToken.StringLiteral);

            ret._matchPath = new RegexResult[] { ew.Current.Match.AsResult() };
            ret.Path       = ew.Current.Match.Value.StartsWith("\"") ? ew.Current.Match.Value.Substring(1, ew.Current.Match.Length - 2) : ew.Current.Match.Value;

            ret._matchForEvery = ew.Next(ExpressionToken.ForEvery, true).Match.AsResult();
            ew.NextOrThrow();
            ret.Arguments = ArgumentsExpression.Parse(ew, token => token.Token == ExpressionToken.NewLine || token.Token == ExpressionToken.Mod, false, typeof(ForeachExpression));

            return(ret);
        }
示例#2
0
        public static ArgumentsExpression Parse(ExpressionWalker ew, ExpressionToken left, ExpressionToken right, bool argsOptional, Type caller = null)
        {
            var args = new ArgumentsExpression();

            ew.IsCurrentOrThrow(left);
            ew.NextOrThrow();
            var exprs = new List <Expression>();

            while (ew.Current.Token != right && ew.HasNext)
            {
                if (ew.Current.Token == ExpressionToken.Comma)
                {
                    if (ew.HasBack && ew.PeakBack.Token == ExpressionToken.Comma)
                    {
                        exprs.Add(NullIdentity.Instance);
                    }

                    ew.NextOrThrow();
                    continue;
                }

                var expression = ParseExpression(ew, caller);
                if (ew.IsCurrent(ExpressionToken.Colon))
                {
                    //handle keyvalue item
                    exprs.Add(KeyValueExpression.Parse(ew, expression, caller));
                }
                else
                {
                    exprs.Add(expression);
                }
            }

            if (exprs.Count == 0 && !argsOptional)
            {
                throw new UnexpectedTokenException($"Was expecting an expression between {left} and {right}");
            }

            ew.Next();
            args.Arguments = exprs.ToArray();
            return(args);
        }
示例#3
0
        public static GroupExpression Parse(ExpressionWalker ew, ExpressionToken left, ExpressionToken right)
        {
            var grp = new GroupExpression()
            {
                _matchLeft = AttributeExtensions.GetAttribute <ExpressionTokenAttribute>(left).Emit.AsResult(), _matchRight = AttributeExtensions.GetAttribute <ExpressionTokenAttribute>(right).Emit.AsResult()
            };

            ew.IsCurrentOrThrow(left);

            ew.NextOrThrow();
            if (ew.Current.Token == right)
            {
                throw new UnexpectedTokenException($"Expected an expression, found end of group of type {right}");
            }

            grp.InnerExpression = ParseExpression(ew);
            ew.IsCurrentOrThrow(right);
            ew.Next();
            return(grp);
        }
示例#4
0
        public static ArgumentsExpression Parse(ExpressionWalker ew, Func <TokenMatch, bool> parseTill, bool argsOptional, Type caller = null)
        {
            var args  = new ArgumentsExpression();
            var exprs = new List <Expression>();

            while (!parseTill(ew.Current) && ew.HasNext)
            {
                if (ew.Current.Token == ExpressionToken.Comma)
                {
                    if (ew.HasBack && ew.PeakBack.Token == ExpressionToken.Comma)
                    {
                        exprs.Add(NullIdentity.Instance);
                    }

                    ew.NextOrThrow();
                    continue;
                }

                var expression = ParseExpression(ew, caller);
                if (ew.IsCurrent(ExpressionToken.Colon))
                {
                    //handle keyvalue item
                    exprs.Add(KeyValueExpression.Parse(ew, expression));
                }
                else
                {
                    exprs.Add(expression);
                }
            }

            if (exprs.Count == 0 && !argsOptional)
            {
                throw new UnexpectedTokenException($"Was expecting arguments but found none while argsOptional is false");
            }

            ew.Next();
            args.Arguments = exprs.ToArray();
            return(args);
        }
示例#5
0
        public static ParserAction Parse(ExpressionWalker ew, string code, LineBuilder output)
        {
            //  multiline:
            //      %foreach expr%
            //        code #1
            //      %
            //  singleline:
            //      %foreach expr
            //          code #1
            ew.IsCurrentOrThrow(ExpressionToken.Foreach);
            ew.NextOrThrow();
            //parse the arguments for the foreach
            var args = ArgumentsExpression.Parse(ew, token => token.Token == ExpressionToken.NewLine || token.Token == ExpressionToken.Mod, false, typeof(ForeachExpression));

            //ew.Back(); //agrumentsExpression skips the closer token and we need it to identify if this is a singleline or multiline
            if (output == null)
            {
                output = new LineBuilder(code);
            }

            string content;
            var    relatedLines = new List <Line>();

            relatedLines.AddRange(output.GetLinesRelated(args.Matches()));
            if (ew.PeakBack.Token == ExpressionToken.Mod)
            {
                //the content is % to % block
                var leftBorder = ew.Current.Match;
                var nextMod    = ForeachExpression.FindCloser(leftBorder.Index, code);
                //handle implicit end block (when % is not existing)
                if (nextMod == -1)
                {
                    nextMod = code.Length - 1;
                }
                ew.SkipForwardWhile(token => token.Match.Index < nextMod);
                ew.Next(); //skip % itself
                var l1 = output.GetLineAt(leftBorder.Index) ?? output.Lines.First();

                relatedLines.AddRange(new Range(l1.LineNumber, output.GetLineAt(nextMod).LineNumber).EnumerateIndexes().Select(output.GetLineByLineNumber));
                content = null;
            }
            else
            {
                //the content is only next line
                var leftMod = ew.Current.Match;
                var nextMod = code.IndexOf('\n', leftMod.Index);
                relatedLines.Add(output.GetLineByLineNumber(relatedLines.Last().LineNumber + 1)); //next line.
                content = code.Substring(leftMod.Index, nextMod == -1 ? (code.Length - leftMod.Index) : nextMod - leftMod.Index);
            }

            relatedLines = relatedLines.Distinct().OrderBy(l => l.StartIndex).ToList();

            if (relatedLines.Count(l => l.Content.Contains("%foreach")) <= relatedLines.Count(l => l.CleanContent() == "%") && relatedLines.Last().CleanContent() == "%")
            {
                relatedLines[relatedLines.Count - 1].MarkedForDeletion = true;
                relatedLines.RemoveAt(relatedLines.Count - 1);
            }

            //make sure to clean out % at the end
            if (content == null)
            {
                content = relatedLines.Select(l => l.Content).StringJoin();
            }


            //all lines of the foreach are destined to deletion
            foreach (var line in relatedLines)
            {
                line.MarkedForDeletion = true;
            }

            return(new ParserAction(ParserToken.ForeachLoop, relatedLines, new ForeachExpression()
            {
                Content = content, Arguments = args
            }));
        }
示例#6
0
        public static IdentityExpression Parse(ExpressionWalker ew, Type caller = null, Expression left = null)
        {
            var ret = new IdentityExpression();

            //types:
            //justname
            //justname.accessor
            //justname.accessor[5].second
            //justname.method().someval
            //justname.method().someval[3].thatsfar

            if (left == null)
            {
                ew.IsCurrentOrThrow(ExpressionToken.Literal);
            }
            if (ew.HasNext && ew.PeakNext.WhitespacesAfterMatch == 0 && ew.PeakNext.Token == ExpressionToken.Period && caller != typeof(IdentityExpression) || left != null)
            {
                var first = left ?? ParseExpression(ew, typeof(IdentityExpression));
                ew.NextOrThrow(); //skip the predicted period.
                var next = ew.PeakNext;
                switch (next.Token)
                {
                //currently we are at Literal
                case ExpressionToken.Period:
                    ret.Identity = new PropertyIdentity(first, Parse(ew));
                    return(ret);

                case ExpressionToken.LeftBracet:
                    ret.Identity = new PropertyIdentity(first, IndexerCallExpression.Parse(ew));
                    return(ret);

                case ExpressionToken.LeftParen:
                    ret.Identity = new PropertyIdentity(first, CallExpression.Parse(ew));
                    return(ret);

                default:
                    if (left != null)
                    {
                        return(new IdentityExpression(new PropertyIdentity(left, Parse(ew, typeof(IdentityExpression), null))));
                    }

                    if (first != null)
                    {
                        //just a plain single word!
                        var right = new IdentityExpression();
                        if (ew.IsCurrent(ExpressionToken.Null))
                        {
                            right.Identity = NullIdentity.Instance;
                        }
                        else
                        {
                            ew.IsCurrentOrThrow(ExpressionToken.Literal);
                            right.Identity = StringIdentity.Create(ew.Current.Match);
                        }

                        ew.Next();
                        return(new IdentityExpression(new PropertyIdentity(first, right)));
                    }

                    goto _plain_identity;
                }
            }

_plain_identity:
            //just a plain single word!
            if (ew.IsCurrent(ExpressionToken.Null))
            {
                ret.Identity = NullIdentity.Instance;
            }
            else
            {
                ew.IsCurrentOrThrow(ExpressionToken.Literal);
                ret.Identity = StringIdentity.Create(ew.Current.Match);
            }

            ew.Next();
            return(ret);
        }
示例#7
0
 public static Expression Parse(ExpressionWalker ew)
 {
     ew.IsCurrentOrThrow(ExpressionToken.Null);
     ew.Next();
     return(new IdentityExpression(Instance));
 }