コード例 #1
0
ファイル: ImportExpression.cs プロジェクト: Nucs/Regen
        public static ImportExpression Parse(ExpressionWalker ew)
        {
            ew.IsCurrentOrThrow(ExpressionToken.Import);
            ew.NextOrThrow();

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

            if (ew.IsCurrent(ExpressionToken.StringLiteral))
            {
                ret._matchType = new RegexResult[] { ew.Current.Match.AsResult() };
                ret.Type       = ew.Current.Match.Value.Trim('\"');
            }
            else
            {
                ret._matchType = ew.TakeForwardWhile(t => t.Token == ExpressionToken.Period || t.Token == ExpressionToken.Literal)
                                 .Select(t => t.Match.AsResult()).ToArray();

                ret.Type = ret._matchType.Select(m => m.Value).StringJoin();

                if (ew.IsCurrent(ExpressionToken.As))
                {
                    ret._matchAlias = ew.Next(ExpressionToken.Literal, true).Match.AsResult();
                    ret.As          = ret._matchAlias.Value;
                }
            }

            ew.Next();
            return(ret);
        }
コード例 #2
0
ファイル: GroupExpression.cs プロジェクト: Nucs/Regen
        public static GroupExpression Parse(ExpressionWalker ew, ExpressionToken left, ExpressionToken right)
        {
            ew.IsCurrentOrThrow(left);

            ew.NextOrThrow();
            if (ew.Current.Token == right)
            {
                throw new UnexpectedTokenException($"Expected an expression, found end of group of type {right}");
            }
            var expr = ParseExpression(ew, typeof(GroupExpression));
            var grp  = new GroupExpression()
            {
                _matchLeft = AttributeExtensions.GetAttribute <ExpressionTokenAttribute>(left).Emit.AsResult(), _matchRight = AttributeExtensions.GetAttribute <ExpressionTokenAttribute>(right).Emit.AsResult()
            };

            if (ew.IsCurrent(ExpressionToken.Or))
            {
                grp.InnerExpression = TernaryExpression.Parse(ew, expr);
            }
            else
            {
                grp.InnerExpression = expr;
            }

            ew.IsCurrentOrThrow(right);
            ew.Next();
            return(grp);
        }
コード例 #3
0
        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));
            //we have to fall back because ArgumentsExpression.Parse swallows mod.
            ew.IsBack(ExpressionToken.Mod, true);
            if (ew.IsCurrent(ExpressionToken.Mod))
            {
                ew.Back(1);
            }

            return(ret);
        }
コード例 #4
0
        public static Expression TryParse(ExpressionWalker ew, Type caller = null)
        {
            if (ew.IsCurrent(ExpressionToken.Hashtag) && ew.HasNext && ew.IsNext(ExpressionToken.NumberLiteral))
            {
                return(Parse(ew, caller));
            }

            return(null);
        }
コード例 #5
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);
        }
コード例 #6
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);
        }
コード例 #7
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);
        }
コード例 #8
0
ファイル: Expression.cs プロジェクト: Nucs/Regen
        public static Expression ParseExpression(ExpressionWalker ew, Type caller = null)
        {
            Expression ret = null;

_retry:
            bool isOperatorCall = caller == typeof(OperatorExpression) || caller == typeof(RightOperatorExpression) || caller == typeof(ForeachExpression);
            var current = ew.Current.Token;

            if (current == ExpressionToken.Literal)
            {
                //cases like variable(.., variable[.., variable + .., variable
                if (ew.HasNext)
                {
                    var peak = ew.PeakNextOrThrow().Token;
                    if (peak == ExpressionToken.LeftParen)
                    {
                        ret = CallExpression.Parse(ew);
                    }
                    else if (peak == ExpressionToken.Period && caller != typeof(IdentityExpression) && caller != typeof(InteractableExpression))
                    {
                        ret = IdentityExpression.Parse(ew);
                    }
                    else if (peak == ExpressionToken.LeftBracet)
                    {
                        ret = IndexerCallExpression.Parse(ew);
                    }
                    else if (peak == ExpressionToken.New)
                    {
                        ret = NewExpression.Parse(ew);
                    }
                    else if (RightOperatorExpression.IsNextAnRightUniOperation(ew, caller) && caller != typeof(RightOperatorExpression))
                    {
                        ret = RightOperatorExpression.Parse(ew);
                    }
                    else if (OperatorExpression.IsNextAnOperation(ew) && !isOperatorCall)
                    {
                        ret = OperatorExpression.Parse(ew);
                    }
                    else
                    {
                        ret = IdentityExpression.Parse(ew, caller);
                    }
                }
                else
                {
                    ret = IdentityExpression.Parse(ew, caller);
                }
            }
            else if (LeftOperatorExpression.IsCurrentAnLeftUniOperation(ew))
            {
                ret = LeftOperatorExpression.Parse(ew);
            }
            else if (current == ExpressionToken.NumberLiteral)
            {
                ret = NumberLiteral.Parse(ew);
            }
            else if (current == ExpressionToken.StringLiteral)
            {
                ret = StringLiteral.Parse(ew);
            }
            else if (current == ExpressionToken.LeftParen)
            {
                ret = GroupExpression.Parse(ew, ExpressionToken.LeftParen, ExpressionToken.RightParen);
            }
            else if (current == ExpressionToken.LeftBracet)
            {
                ret = ArrayExpression.Parse(ew);
            }
            else if (current == ExpressionToken.New)
            {
                ret = NewExpression.Parse(ew);
            }
            else if (current == ExpressionToken.Boolean)
            {
                ret = BooleanLiteral.Parse(ew);
            }
            else if (current == ExpressionToken.CharLiteral)
            {
                ret = CharLiteral.Parse(ew);
            }
            else if (current == ExpressionToken.Throw)
            {
                ret = ThrowExpression.Parse(ew);
            }
            else if (current == ExpressionToken.Hashtag && ew.HasNext && ew.PeakNext.Token == ExpressionToken.NumberLiteral)
            {
                ret = HashtagReferenceExpression.Parse(ew, caller);
            }
            else if (current == ExpressionToken.Null)
            {
                ret = NullIdentity.Parse(ew);
            }
            else if (current == ExpressionToken.NewLine)
            {
                ew.NextOrThrow();
                goto _retry;
            }
            else
            {
                throw new UnexpectedTokenException($"Token was not expected to be a {ew.Current.Token}");
            }
_rereview:
            //here we parse chained math operations
            while (OperatorExpression.IsCurrentAnOperation(ew) && !isOperatorCall)
            {
                if (RightOperatorExpression.IsCurrentAnRightUniOperation(ew) && caller != typeof(OperatorExpression))
                {
                    ret = RightOperatorExpression.Parse(ew, ret);
                }
                else if (OperatorExpression.IsCurrentAnOperation(ew))
                {
                    ret = OperatorExpression.Parse(ew, ret);
                }
            }

            if (ew.IsCurrent(ExpressionToken.Or) && caller != typeof(TernaryExpression) && caller != typeof(OperatorExpression))
            {
                ret = TernaryExpression.Parse(ew, ret);
            }

            if (ew.IsCurrent(ExpressionToken.LeftBracet))
            {
                ret = IndexerCallExpression.Parse(ew, ret);
                goto _rereview;
            }

            if (ew.IsCurrent(ExpressionToken.LeftParen))
            {
                ret = CallExpression.Parse(ew, ret);
                goto _rereview;
            }

            return(ret);
        }