示例#1
0
        public virtual object VisitElementAccessExpression(ElementAccessExpression elementAccessExpression, object data)
        {
            stackMap.Push(elementAccessExpression);
            elementAccessExpression.LeftSide.AcceptVisitor(this, data);

            elementAccessExpression.Expressions.AcceptVisitor(this, data);

            stackMap.Pop();
            return(null);
        }
示例#2
0
        private ExpressionNode ParseSubexpression(int precBound, ExpressionNode left)
        {
            while (true)
            {
                int curPrec = precedence[(int)curtok.ID];
                if (curPrec < precBound) break;

                int associativity = ASSOC_LEFT;
                TokenID curOp = curtok.ID;
                switch (curOp)
                {
                    case TokenID.Equal:
                    case TokenID.PlusEqual:
                    case TokenID.MinusEqual:
                    case TokenID.StarEqual:
                    case TokenID.SlashEqual:
                    case TokenID.PercentEqual:
                    case TokenID.BAndEqual:
                    case TokenID.BOrEqual:
                    case TokenID.BXorEqual:
                    case TokenID.ShiftLeftEqual:
                    case TokenID.QuestionQuestion:
                        associativity = ASSOC_RIGHT;
                        goto case TokenID.Percent;		// "FALL THROUGH"

                    case TokenID.Greater:
                        Advance();
                        if (curtok.ID == TokenID.Greater && curtok.LastCharWasGreater)
                        {
                            curOp = TokenID.ShiftRight;
                            Advance();
                        }
                        else if (curtok.ID == TokenID.GreaterEqual && curtok.LastCharWasGreater)
                        {
                            curOp = TokenID.ShiftRightEqual;
                            associativity = ASSOC_RIGHT;
                            Advance();
                        }
                        goto parseBinOp;

                    case TokenID.Or:
                    case TokenID.And:
                    case TokenID.BOr:
                    case TokenID.BXor:
                    case TokenID.BAnd:
                    case TokenID.EqualEqual:
                    case TokenID.NotEqual:
                    case TokenID.Less:
                    case TokenID.LessEqual:
                    case TokenID.GreaterEqual:
                    case TokenID.ShiftLeft:
                    case TokenID.Plus:
                    case TokenID.Minus:
                    case TokenID.Star:
                    case TokenID.Slash:
                    case TokenID.Percent:
                        Advance();
                    parseBinOp: left = new BinaryExpression(curOp, left, ParseSubexpression(curPrec + associativity));
                    break;

                    case TokenID.PlusPlus:								// postfix
                    Advance();
                    left = new PostIncrementExpression(left);
                    break;

                    case TokenID.MinusMinus:							// postfix
                    Advance();
                    left = new PostDecrementExpression(left);
                    break;

                    case TokenID.Is:
                    case TokenID.As:
                    Advance();
                    left = new BinaryExpression(curOp, left, ParseType(true));
                    break;

                    case TokenID.Question:
                    {
                        Advance();
                        ExpressionNode thenExpr = ParseExpression();
                        AssertAndAdvance(TokenID.Colon);
                        left = new ConditionalExpression(left, thenExpr, ParseExpression());
                        break;
                    }

                    case TokenID.LParen:								// invocation
                    Advance();
                    left = new InvocationExpression(left, ParseArgumentList());
                    AssertAndAdvance(TokenID.RParen);
                    break;

                    case TokenID.LBracket:								// element access
                    Advance();
                    left = new ElementAccessExpression(left, ParseExpressionList());
                    AssertAndAdvance(TokenID.RBracket);
                    break;

                    case TokenID.Dot:									// member access
                    case TokenID.MinusGreater:
                    left = ParseMemberAccess(left);
                    break;

                    default:
                    ReportError("Unexpected token", curtok);
                    return left;
                }
            }
            return left;
        }
示例#3
0
        private ExpressionNode ParseExpressionOrType(bool inStatementContext)
        {
            // Can the interior be a type? (A.2.2)
            switch (curtok.ID)
            {
                // type-name
                case TokenID.Ident:

                // simple-type
                case TokenID.SByte:
                case TokenID.Byte:
                case TokenID.Short:
                case TokenID.UShort:
                case TokenID.Int:
                case TokenID.UInt:
                case TokenID.Long:
                case TokenID.ULong:
                case TokenID.Char:

                case TokenID.Float:
                case TokenID.Double:

                case TokenID.Decimal:

                case TokenID.Bool:

                // class-type
                case TokenID.Object:
                case TokenID.String:
                    // yes, it can
                    break;

                default:
                    // no, it can not
                    return ParseExpression();
            }

            ExpressionNode expr = ParseIdentifierOrKeyword(false, false, false, false, false);
            if (curtok.ID == TokenID.ColonColon)
            {
                // id :: id type-parameter-list_opt

                QualifiedIdentifierExpression qualID = new QualifiedIdentifierExpression(curtok);	// TODO: Replace by QualifiedAliasMember instance
                qualID.IsNamespaceAliasQualifier = true;
                qualID.Expressions.Add(expr);

                Advance(); // over ColonColon
                qualID.Expressions.Add(ParseMember(inStatementContext));

                expr = qualID;
            }
            else if (ParsePossibleTypeParameterNode(false, false, false, inStatementContext))
            {
                expr = new TypeNode(expr);
                ApplyTypeParameters((TypeNode)expr);
            }

            while (curtok.ID == TokenID.Dot)
            {
                Advance(); // over Dot
                if (curtok.ID != TokenID.Ident)
                {
                    RecoverFromError(TokenID.Ident);
                    return expr;
                }
                expr = new MemberAccessExpression(expr, ParseMember(inStatementContext), TokenID.Dot);
            }

            bool hasQuestionMark = false;
            int starCount = 0;
            bool hasBracket = false;

            if (curtok.ID == TokenID.Question)
            {
                Advance();
                hasQuestionMark = true;
            }

            while (curtok.ID == TokenID.Star)
            {
                Advance();
                starCount++;
            }

            // return (a * b);
            // return (a ? b : c);
            // a* b = c;
            // a? b = c;
            // a b = c;

            //if(curtok.ID == TokenID.Ident || (hasQuestionMark || starCount > 0) && curtok.ID == TokenID.RParen) goto foundType;

            if (curtok.ID == TokenID.Ident)
            {
                if (inStatementContext) goto foundType;
                else if (!hasQuestionMark && starCount == 0) goto foundType;	// it is a parse error
            }
            else if (curtok.ID == TokenID.RParen)
            {
                if (hasQuestionMark || starCount > 0) goto foundType;
            }
            else if (curtok.ID == TokenID.LBracket)
            {
                Advance();
                hasBracket = true;
                if (hasQuestionMark || starCount > 0 || curtok.ID == TokenID.Comma || curtok.ID == TokenID.RBracket) goto foundType;
            }

            //
            // treat as expression
            //
            if (hasQuestionMark)
            {
                // hasBracket is false
                ExpressionNode trueExpr = ParseSubexpression(starCount > 0 ? (int)PRECEDENCE_UNARY : 1);
                while (starCount-- > 0)
                    trueExpr = new DereferenceExpression(trueExpr);
                AssertAndAdvance(TokenID.Colon);
                return new ConditionalExpression(expr, trueExpr, ParseExpression());
            }
            else if (starCount > 0)
            {
                // hasBracket is false
                starCount--;
                ExpressionNode right = ParseSubexpression(starCount > 0 ? PRECEDENCE_UNARY : PRECEDENCE_MULTIPLICATIVE + ASSOC_LEFT);
                while (starCount-- > 0)
                    right = new DereferenceExpression(right);
                expr = new BinaryExpression(TokenID.Star, expr, right);
            }
            else if (hasBracket)
            {
                expr = new ElementAccessExpression(expr, ParseExpressionList());
                AssertAndAdvance(TokenID.RBracket);
            }
            return ParseSubexpression(1, expr);


            //
        // treat as type
        //
        foundType:
            TypeNode typeNode = new TypeNode(expr);
            if (hasQuestionMark)
                typeNode.IsNullableType = true;
            while (starCount-- > 0)
                typeNode = new TypePointerNode(typeNode);
            if (hasBracket)
            {
                while (true)
                {
                    int numCommas = 0;
                    while (curtok.ID == TokenID.Comma)
                    {
                        Advance();
                        numCommas++;
                    }
                    AssertAndAdvance(TokenID.RBracket);
                    typeNode.RankSpecifiers.Add(numCommas);

                    if (curtok.ID != TokenID.LBracket) break;
                    Advance();
                }
            }
            return typeNode;
        }
示例#4
0
        private ExpressionNode ParsePrimaryExpression()
        {
            Token tok = curtok;
            ExpressionNode result;	// TODO: handle error cases (result = null)
            switch (curtok.ID)
            {
                #region Literals
                case TokenID.Null:
                    result = new NullPrimitive(curtok);
                    Advance();
                    break;

                case TokenID.True:
                    result = new BooleanPrimitive(true, curtok);
                    Advance();
                    break;

                case TokenID.False:
                    result = new BooleanPrimitive(false, curtok);
                    Advance();
                    break;

                case TokenID.IntLiteral:
                    result = new IntegralPrimitive(strings[curtok.Data], IntegralType.Int, curtok);
                    Advance();
                    break;
                case TokenID.UIntLiteral:
                    result = new IntegralPrimitive(strings[curtok.Data], IntegralType.UInt, curtok);
                    Advance();
                    break;
                case TokenID.LongLiteral:
                    result = new IntegralPrimitive(strings[curtok.Data], IntegralType.Long, curtok);
                    Advance();
                    break;
                case TokenID.ULongLiteral:
                    result = new IntegralPrimitive(strings[curtok.Data], IntegralType.ULong, curtok);
                    Advance();
                    break;

                case TokenID.RealLiteral:
                    result = new RealPrimitive(strings[curtok.Data], curtok);
                    Advance();
                    break;

                case TokenID.CharLiteral:
                    result = new CharPrimitive(strings[curtok.Data], curtok);
                    Advance();
                    break;

                case TokenID.StringLiteral:
                    result = new StringPrimitive(strings[curtok.Data], curtok);
                    Advance();
                    break;
                #endregion

                #region Predefined Types

                case TokenID.Bool:
                case TokenID.Byte:
                case TokenID.Char:
                case TokenID.Decimal:
                case TokenID.Double:
                case TokenID.Float:
                case TokenID.Int:
                case TokenID.Long:
                case TokenID.Object:
                case TokenID.SByte:
                case TokenID.Short:
                case TokenID.String:
                case TokenID.UInt:
                case TokenID.ULong:
                case TokenID.UShort:
                    result = new PredefinedTypeNode(tok.ID, tok);
                    Advance();
                    result = ParseMemberAccess(result);
                    break;

                #endregion

                #region Keywords
                case TokenID.This:
                    {
                        Advance();
                        IdentifierExpression idExpr = new IdentifierExpression("this", tok);
                        idExpr.StartingPredefinedType = tok.ID;
                        result = idExpr;
                        break;
                    }

                case TokenID.Base:
                    Advance();   // over base
                    if (curtok.ID == TokenID.LBracket)         // base indexer expression
                    {
                        Advance();
                        result = new ElementAccessExpression(new IdentifierExpression("base", tok), ParseExpressionList());
                        AssertAndAdvance(TokenID.RBracket);
                        break;
                    }

                    if (curtok.ID != TokenID.Dot)
                    {
                        RecoverFromError(TokenID.Dot, TokenID.LBracket);
                        result = null;
                        break;
                    }

                    // base access expression
                    Advance();   // advance over dot
                    result = new BaseAccessExpression(ParseMember(false));
                    break;

                case TokenID.Checked:
                    Advance();
                    AssertAndAdvance(TokenID.LParen);
                    result = new CheckedExpression(ParseExpression());
                    AssertAndAdvance(TokenID.RParen);
                    break;

                case TokenID.Unchecked:
                    Advance();
                    AssertAndAdvance(TokenID.LParen);
                    result = new UncheckedExpression(ParseExpression());
                    AssertAndAdvance(TokenID.RParen);
                    break;

                case TokenID.Default:
                    Advance();
                    AssertAndAdvance(TokenID.LParen);
                    result = new DefaultConstantExpression(ParseType(false));
                    AssertAndAdvance(TokenID.RParen);
                    break;

                case TokenID.New:
                    Advance();

                    isNewStatement = true;

                    IType newType = ParseType(false);

                    //ApplyTypeParameters(newType); -> not sure, but a type pointer can not be generic!

                    if (curtok.ID == TokenID.LParen)
                    {
                        Advance();
                        result = new ObjectCreationExpression(newType, ParseArgumentList(), tok);
                        AssertAndAdvance(TokenID.RParen);
                    }
                    else if (curtok.ID == TokenID.LBracket)
                    {
                        result = ParseArrayCreation(newType);
                    }
                    else
                    {
                        RecoverFromError(TokenID.LParen, TokenID.LBracket);
                        result = null;
                    }

                    isNewStatement = false;
                    break;

                case TokenID.Typeof:
                    Advance();
                    AssertAndAdvance(TokenID.LParen);
                    result = new TypeOfExpression(ParseType(false));
                    CheckRankSpecifier(result);
                    AssertAndAdvance(TokenID.RParen);
                    break;

                case TokenID.Sizeof:
                    Advance();
                    AssertAndAdvance(TokenID.LParen);
                    result = new SizeOfExpression(ParseType(false));
                    AssertAndAdvance(TokenID.RParen);
                    break;

                case TokenID.Delegate:    //anonymous method
                    Advance();
                    result = ParseAnonymousMethod();
                    break;

                #endregion Keywords

                case TokenID.Ident:
                    result = ParseIdentifierOrKeyword(false, false, false, false, false);
                    if (curtok.ID == TokenID.ColonColon)
                    {
                        // id :: id type-parameter-list_opt . id type-parameter-list_opt

                        QualifiedIdentifierExpression qualID = new QualifiedIdentifierExpression(curtok);	// TODO: Replace by QualifiedAliasMember instance
                        qualID.IsNamespaceAliasQualifier = true;
                        qualID.Expressions.Add(result);

                        Advance(); // over ColonColon
                        qualID.Expressions.Add(ParseMember(false));

                        result = ParseMemberAccess(qualID);
                    }
                    else if (ParsePossibleTypeParameterNode(false, false, false, false))
                    {
                        result = new TypeNode(result);
                        ApplyTypeParameters((TypeNode)result);
                    }
                    break;

                case TokenID.LParen:
                    Advance();
                    result = ParseCastOrGroup();
                    break;

                default:
                    RecoverFromError("Unexpected token in primary expression");
                    return null;		// TODO: Invalid expression
            }
            return result;
        }
        public virtual object VisitElementAccessExpression(ElementAccessExpression elementAccessExpression, object data)
        {
            stackMap.Push(elementAccessExpression);
            elementAccessExpression.LeftSide.AcceptVisitor(this, data);

            elementAccessExpression.Expressions.AcceptVisitor(this, data);

            stackMap.Pop();
            return null;

        }