Ejemplo n.º 1
0
        /// <summary>
        ///
        /// Unary syntax:
        ///   Unary -> UnaryOperator* Term ( ASTStructInitializer | ASTEmptyInitializer | ASTEmptyInitializer | ASTCall | ASTIndexing )*
        ///   ASTStructInitializer -> "{" ( Identifier "=" Expression )* "}"
        ///   ASTArrayInitializer  -> "{" Expression+ "}"
        ///   ASTEmptyInitializer  -> "{" "}"
        ///   ASTCall              -> "(" ( Expression ( "," Expression )* )? ")"
        ///   ASTIndexing          -> "[" ( Expression ( "," Expression )* )? "]"
        ///
        /// </summary>
        /// <returns></returns>
        private ASTNode ParseUnary()
        {
            (ASTUnaryNode top, ASTUnaryNode leaf) GetPrefix()
            {
                if (!EatToken(IsUnaryOperator))
                {
                    return(null, null);
                }

                var unaryTop = MakeUnaryOperator(EatenToken);

                var(child, unaryLeaf) = GetPrefix();
                unaryTop.Child        = child;

                if (unaryLeaf == null)
                {
                    unaryLeaf = unaryTop;
                }
                return(unaryTop, unaryLeaf);
            }

            (ASTNode top, ASTUnaryNode leaf) = GetPrefix();
            var term = ParseTerm();

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

            if (top == null)
            {
                top = term;
            }
            else
            {
                leaf.Child = term;
            }

            while (EatToken(t => t == TokenKind.CurlyLeft ||
                            t == TokenKind.ParenthesesLeft ||
                            t == TokenKind.SquareLeft))
            {
                if (EatenToken.Kind == TokenKind.CurlyLeft)
                {
                    // ASTStructInitializer -> "{" ( Identifier "=" Expression )+ "}"
                    if (PeekTokenIs(TokenKind.Identifier) && PeekTokenIs(TokenKind.Equal, 1))
                    {
                        ASTAssign ParseInitialized()
                        {
                            var ident = PeekToken();

                            if (!Expect(TokenKind.Identifier))
                            {
                                return(null);
                            }
                            if (!Expect(TokenKind.Equal))
                            {
                                return(null);
                            }

                            var right = ParseExpression();

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

                            return(new ASTAssign(null)
                            {
                                Left = new ASTSymbol(ident.Position, ident.Value),
                                Right = right
                            });
                        }

                        var equals = ParseMany(TokenKind.CurlyRight, ParseInitialized);
                        if (equals == null)
                        {
                            return(null);
                        }

                        top = new ASTStructInitializer(top.Position)
                        {
                            Child = top, Values = equals
                        };
                    }
                    //   ASTArrayInitializer  -> "{" Expression+ "}"
                    //   ASTEmptyInitializer  -> "{" "}"
                    else
                    {
                        var values = ParseMany(TokenKind.CurlyRight, ParseExpression);
                        if (values == null)
                        {
                            return(null);
                        }

                        if (values.Any())
                        {
                            top = new ASTArrayInitializer(top.Position)
                            {
                                Child = top, Values = values
                            }
                        }
                        ;
                        else
                        {
                            top = new ASTEmptyInitializer(top.Position)
                            {
                                Child = top
                            }
                        };
                    }
                }
                //   ASTIndexing -> "[" ( Expression ( "," Expression )* )? "]"
                //   ASTCall -> "(" ( Expression ( "," Expression )* )? ")"
                else
                {
                    var last = EatenToken.Kind == TokenKind.ParenthesesLeft
                        ? TokenKind.ParenthesesRight
                        : TokenKind.SquareRight;

                    var arguments = ParseMany(last, TokenKind.Comma, ParseExpression);
                    if (arguments == null)
                    {
                        return(null);
                    }

                    top = EatenToken.Kind == TokenKind.ParenthesesRight
                        ? (ASTNode) new ASTCall(top.Position)
                    {
                        Child = top, Arguments = arguments
                    }
                        : (ASTNode) new ASTIndexing(top.Position)
                    {
                        Child = top, Arguments = arguments
                    };
                }
            }

            return(top);
        }
Ejemplo n.º 2
0
 protected override bool Visit(ASTEmptyInitializer node)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 3
0
 protected abstract bool Visit(ASTEmptyInitializer node);