Exemple #1
0
		private ExpressionNode ConsumeBinary(TokenID startOp)				
		{
			ExpressionNode result = null;

            if ((exprStack.Count == 0 || precedence[(int)curTokNode.Previous.Previous.Value.ID] > 0))
			{
				// assert +,-,!,~,++,--,cast
				Advance();
				ParseExpressionSegment();
				while (precedence[(int)curtok.ID] > precedence[(int)startOp])
				{
					ParseExpressionSegment();
				}
				result = exprStack.Pop(); // this signals it was a unary operation
			}
			else
			{
                BinaryExpression bNode = new BinaryExpression(startOp, curtok);
				Advance();
				bNode.Left = exprStack.Pop();
				exprStack.Push(bNode); // push node
				ParseExpressionSegment(); // right side
				// consume now or let next op consume?
				while (precedence[(int)curtok.ID] > precedence[(int)startOp])
				{
					ParseExpressionSegment();
				}
                
                
                bNode.Right = exprStack.Pop();
           }
			return result;
		}
Exemple #2
0
        private void ParsePreprocessorExpressionSegment(int oldLine)
        {
            int startStackCount = exprStack.Count;
            TokenID startToken = curtok.ID;
            switch (curtok.ID)
            {
                case TokenID.True:
                    exprStack.Push(new BooleanPrimitive(true, curtok));
                    Advance();
                    break;

                case TokenID.False:
                    exprStack.Push(new BooleanPrimitive(false, curtok));
                    Advance();
                    break;

                case TokenID.And:
                case TokenID.Or:
                    Advance();
                    if (!SameLine(oldLine)) return;

                    BinaryExpression bNode = new BinaryExpression(startToken, curtok);
                    bNode.Left = exprStack.Pop();
                    exprStack.Push(bNode); // push node
                    ParsePreprocessorExpressionSegment(oldLine); // right side
                    // consume now or let next op consume?
                    while (precedence[(int)curtok.ID] > precedence[(int)startToken] && curtok.Line == oldLine)
                    {
                        ParsePreprocessorExpressionSegment(oldLine);
                    }

                    bNode.Right = exprStack.Pop();
                    break;

                case TokenID.Not:
                    Advance();
                    do
                    {
                        if (!SameLine(oldLine)) return;
                        ParsePreprocessorExpressionSegment(oldLine);
                    }
                    while (precedence[(int)curtok.ID] >= precedence[(int)TokenID.LParen]);      // LParen for precedence of unary operator

                    ExpressionNode node = exprStack.Pop();
                    UnaryExpression uNode = new UnaryExpression(startToken, node.RelatedToken);
                    uNode.Child = node;
                    exprStack.Push(uNode);
                    break;

                case TokenID.LParen:
                    Advance();
                    if (!SameLine(oldLine)) return;
                    exprStack.Push(new ParenthesizedExpression(ParsePreprocessorExpression()));
                    if (!SameLine(oldLine)) return;
                    AssertAndAdvance(TokenID.RParen);
                    break;


                case TokenID.Ident:
                    exprStack.Push(ParseIdentifierOrKeyword(false, false, false, false, false));
                    break;

                default:
                    if (Lexer.IsKeyWord(curtok.ID))
                    {
                        // in this case a key word is used like a variable name.
                        goto case TokenID.Ident;
                    }
                    else
                    {
                        ReportError("Unexpected token", curtok);
                    }
                    break;
            }
        }
Exemple #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;
        }
Exemple #4
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;
        }
        public virtual object VisitBinaryOperatorExpression(BinaryExpression binaryOperatorExpression, object data)
        {
            stackMap.Push(binaryOperatorExpression);
            binaryOperatorExpression.Left.AcceptVisitor(this, data);
            binaryOperatorExpression.Right.AcceptVisitor(this, data);

            stackMap.Pop();
            return null;

        }