示例#1
0
 public virtual object VisitPredefinedTypeReference(PredefinedTypeNode predefinedTypeNode, object data)
 {
     stackMap.Push(predefinedTypeNode);
     if (predefinedTypeNode.Generic != null)
     {
         predefinedTypeNode.Generic.AcceptVisitor(this, data);
     }
     stackMap.Pop();
     return(null);
 }
示例#2
0
        /// <summary>
        /// this method parse the next token.
        /// </summary>
        /// <param name="checkIsType">
        /// if set to <c>true</c>, it will check that the identifier is a type. If it is a type, it converts it
        /// to a TypeNode.
        /// if set to <c>false</c>, it will not check that the identifier is a type.
        /// 
        /// Set it to <c>false</c> in the case of a type declaration while your are parsing the type's name
        /// 
        /// </param>
        /// <returns>
        /// Generally it returns identifier expression
        /// But in some cases ,it is possible to resolve the kind the expression, 
        /// so it might returns a TypeNode object.
        /// 
        /// For exemple in this case : System.Collections.Generic.List<int>
        /// 
        /// The first identifiers are really identifier.
        /// And the last identifier is a type, and now that because of the generic declaration
        /// 
        /// in the next case : 
        /// 
        /// System.Collections.ArrayList
        /// 
        /// All are returned as Identifier, because in the first stage of the parser, 
        /// we are not able to pronostic what is it the kind of the expression. The ArrayList type will
        /// be resolved in another parser stage
        /// </returns>
        private ExpressionNode ParseIdentifierOrKeyword(bool checkIsType, bool consumeTypeParameter, bool allowTypeParameterAttributes, bool inDeclaration)
        {
            ExpressionNode result = null;
            switch (curtok.ID)
            {
                case TokenID.Ident:
                    if (Lexer.IsKeyWord(curtok.ID))
                    {
                        // in this case a key word is used like a variable name.
                        result = new IdentifierExpression(curtok.ID.ToString().ToLower(), curtok);
                    }
                    else
                    {
                        result = new IdentifierExpression(strings[curtok.Data], curtok);
                    }
                    Advance();

                    while (curtok.ID == TokenID.BSlash)
                    {
                        Advance();
                        string c = char.ConvertFromUtf32( int.Parse(strings[curtok.Data].TrimStart('\\').TrimStart('u'), NumberStyles.HexNumber ) );
                        ((IdentifierExpression)result).Identifier += c ;
                        Advance();
                    }

                    break;


                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:
                case TokenID.Void:
                    result = new PredefinedTypeNode(curtok.ID, curtok);
                    Advance();
                    break;
                case TokenID.If:
                case TokenID.Else:
                case TokenID.This:
                case TokenID.Base:
                    string predef = Enum.GetName(TokenID.Invalid.GetType(), curtok.ID).ToLower();
                    result = new IdentifierExpression(predef, curtok);
                    ((IdentifierExpression)result).StartingPredefinedType = curtok.ID;
                    Advance();
                    break;

                default:
                    if (Lexer.IsKeyWord(curtok.ID))
                    {
                        // in this case a key word is used like a variable name.
                        goto case TokenID.Ident;
                    }
                    else
                    {
                        RecoverFromError(TokenID.Ident);
                    }
                    break;
            }

            if (checkIsType)
            {
                result = CheckIdentifierIsType(result, consumeTypeParameter, allowTypeParameterAttributes, inDeclaration);
            }

            //check if it is an array access
            // TODO

            return result;
        }
示例#3
0
        // statements		
        private StatementNode ParseStatement()
        {
            // label		ident	: colon
            // localDecl	type	: ident
            // block		LCurly
            // empty		Semi
            // expression	
            //	-invoke		pexpr	: LParen
            //	-objCre		new		: type
            //	-assign		uexpr	: assignOp
            //	-postInc	pexpr	: ++
            //	-postDec	pexpr	: --
            //	-preInc		++		: uexpr
            //	-preDec		--		: uexpr
            //
            // selection	if		: LParen
            //				switch	: LParen
            //
            // iteration	while	: LParen
            //				do		: LParen
            //				for		: LParen
            //				foreach	: LParen
            //
            // jump			break	: Semi
            //				continue: Semi
            //				goto	: ident | case | default
            //				return	: expr
            //				throw	: expr
            //
            // try			try		: block
            // checked		checked	: block
            // unchecked	unchecked : block
            // lock			lock	: LParen
            // using		using	: LParen

            StatementNode node;
            mayBeLocalDecl = false;
            switch (curtok.ID)
            {
                case TokenID.LCurly:	// block
                    BlockStatement newBlock = new BlockStatement(isUnsafe > 0, curtok);
                    newBlock.IsUnsafe = isUnsafe > 0;
                    node = newBlock;
                    ParseBlock(newBlock);
                    break;
                case TokenID.Semi:		// empty statement
                    node = new StatementNode(curtok);
                    Advance(); // over semi
                    break;
                case TokenID.If:		// If statement
                    node = ParseIf();
                    break;
                case TokenID.Switch:	// Switch statement
                    node = ParseSwitch();
                    break;
                case TokenID.While:		// While statement
                    node = ParseWhile();
                    break;
                case TokenID.Do:		// Do statement
                    node = ParseDo();
                    break;
                case TokenID.For:		// For statement
                    node = ParseFor();
                    break;
                case TokenID.Foreach:	// Foreach statement
                    node = ParseForEach();
                    break;
                case TokenID.Break:		// Break statement
                    node = ParseBreak();
                    break;
                case TokenID.Continue:	// Continue statement
                    node = ParseContinue();
                    break;
                case TokenID.Goto:		// Goto statement
                    node = ParseGoto();
                    break;
                case TokenID.Return:	// Return statement
                    node = ParseReturn();
                    break;
                case TokenID.Throw:		// Throw statement
                    node = ParseThrow();
                    break;
                case TokenID.Try:		// Try statement
                    node = ParseTry();
                    break;
                case TokenID.Checked:	// Checked statement
                    node = ParseChecked();
                    break;
                case TokenID.Unchecked:	// Unchecked statement
                    node = ParseUnchecked();
                    break;
                case TokenID.Lock:		// Lock statement
                    node = ParseLock();
                    break;
                case TokenID.Using:		// Using statement
                    node = ParseUsing();
                    break;

                case TokenID.Const:
                    node = null;
                    isLocalConst = true;
                    Advance(); // over const
                    break;

                case TokenID.StringLiteral:
                case TokenID.HexLiteral:
                case TokenID.IntLiteral:
                case TokenID.UIntLiteral:
                case TokenID.LongLiteral:
                case TokenID.ULongLiteral:
                case TokenID.True:
                case TokenID.False:
                case TokenID.Null:
                case TokenID.LParen:
                case TokenID.DecimalLiteral:
                case TokenID.RealLiteral:
                case TokenID.CharLiteral:
                case TokenID.PlusPlus:	// PreInc statement
                case TokenID.MinusMinus:// PreDec statement
                case TokenID.This:
                case TokenID.Base:
                case TokenID.New:		// creation statement
                    node = new ExpressionStatement(ParseExpression());
                    AssertAndAdvance(TokenID.Semi);
                    break;

                case TokenID.Void:			// TODO: Special case void
                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:
                    {
                        TypeNode type = new PredefinedTypeNode(curtok.ID, curtok);
                        Advance();
                        bool mustBeDecl = false;
                        if (curtok.ID == TokenID.Question)
                        {
                            Advance();
                            type.IsNullableType = true;
                            mustBeDecl = true;
                        }
                        else if (curtok.ID == TokenID.Star)
                        {
                            do
                            {
                                Advance();
                                type = new TypePointerNode(type);
                            }
                            while (curtok.ID == TokenID.Star);
                            mustBeDecl = true;
                        }
                        if (curtok.ID == TokenID.LBracket)
                        {
                            do
                            {
                                Advance();   // over lbracket
                                int commaCount = 0;
                                while (curtok.ID == TokenID.Comma)
                                {
                                    Advance();
                                    commaCount++;
                                }
                                type.RankSpecifiers.Add(commaCount);
                                AssertAndAdvance(TokenID.RBracket);
                            }
                            while (curtok.ID == TokenID.LBracket);
                            mustBeDecl = true;
                        }

                        if (curtok.ID == TokenID.Ident)
                        {
                            node = ParseLocalDeclarationStatement(type);
                        }
                        else if (mustBeDecl)
                        {
                            RecoverFromError(TokenID.Ident);
                            node = new StatementNode(curtok);
                        }
                        else
                        {
                            ExpressionNode expr = ParseSubexpression(1, type);
                            if (!(expr is InvocationExpression))
                            {
                                ReportError("Statement must be an invocation", expr.RelatedToken);
                            }
                            node = new ExpressionStatement(expr);
                        }
                        AssertAndAdvance(TokenID.Semi);
                        break;
                    }

                case TokenID.Ident:
                    {
                        if (strings[curtok.Data] == "yield")
                        {
                            node = ParseYieldStatement();
                            break;
                        }

                        ExpressionNode expr = ParseExpressionOrType(true);
                        if (expr is IdentifierExpression && curtok.ID == TokenID.Colon)
                        {
                            Advance(); // advance over colon
                            LabeledStatement lsnode = new LabeledStatement(curtok);
                            lsnode.Name = (IdentifierExpression)expr;
                            lsnode.Statement = ParseStatement();
                            node = lsnode;
                        }
                        else
                        {
                            if (expr is TypeNode)
                                node = ParseLocalDeclarationStatement((IType)expr);
                            else
                                node = new ExpressionStatement(expr);
                            AssertAndAdvance(TokenID.Semi);
                        }

                        /*					ExpressionNode expr = ParseIdentifierOrKeyword(false, true, false, false);
                                            IdentifierExpression idExpr = expr as IdentifierExpression;
                                            if(idExpr != null && curtok.ID == TokenID.Colon)
                                            {
                                                Advance(); // advance over colon
                                                LabeledStatement lsnode = new LabeledStatement(curtok);
                                                lsnode.Name = idExpr;
                                                lsnode.Statement = ParseStatement();
                                                node = lsnode;
                                            }
                                            else
                                            {
                                                mayBeLocalDecl = true;

                                                if(curtok.ID == TokenID.ColonColon)
                                                {
                                                    Advance();
                                                    if(curtok.ID != TokenID.Ident)
                                                    {
                                                        RecoverFromError(TokenID.Ident);
                                                        node = null;
                                                        break;
                                                    }
                                                    expr = new MemberAccessExpression(expr, new IdentifierExpression(strings[curtok.Data], curtok), TokenID.ColonColon);
                                                    Advance(); // over ident
                                                }

                                                while(curtok.ID == TokenID.Dot)
                                                {
                                                    Advance();
                                                    if(curtok.ID != TokenID.Ident)
                                                    {
                                                        RecoverFromError(TokenID.Ident);
                                                        node = null;
                                                        break;
                                                    }
                                                    expr = new MemberAccessExpression(expr, new IdentifierExpression(strings[curtok.Data], curtok), TokenID.Dot);
                                                    Advance(); // over ident
                                                }

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

                                                if(curtok.ID == TokenID.LBracket)
                                                {
                                                    Advance();
                                                    if(curtok.ID == TokenID.Comma || curtok.ID == TokenID.RBracket)
                                                    {
                                                        TypeNode typeNode = expr as TypeNode;
                                                        if(typeNode == null)
                                                            expr = typeNode = new TypeNode(expr);
                                                        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();
                                                        }
                                                    }
                                                    else
                                                    {
                                                        ExpressionList exprList = ParseExpressionList();
                                                        expr = new ElementAccessExpression(expr, exprList);
                                                        AssertAndAdvance(TokenID.RBracket);
                                                    }
                                                }

                                                if(curtok.ID == TokenID.Question)
                                                {
                                                    Advance();
                                                    TypeNode typeNode = expr as TypeNode;
                                                    if(typeNode == null)
                                                        expr = typeNode = new TypeNode(expr);
                                                    typeNode.IsNullableType = true;
                                                }
                                                else
                                                {
                                                    while(curtok.ID == TokenID.Star)
                                                    {
                                                        Advance();
                                                        expr = new TypePointerNode(expr);
                                                    }
                                                }*/


                        //						expr = ParseSubexpression(PRECEDENCE_PRIMARY, expr);
                        /*						exprStack.Push(expr);
                                                ParseContinuingPrimary();
                                                expr = exprStack.Pop();*/
                        /*						if((expr is IdentifierExpression || expr is MemberAccessExpression || expr is TypeNode)
                                                        && (curtok.ID == TokenID.Ident || curtok.ID == TokenID.Star || curtok.ID == TokenID.Question))
                                                {
                                                    node = ParseLocalDeclarationStatement((IType) expr);
                                                }
                                                else
                                                    node = new ExpressionStatement(ParseSubexpression(1, expr));
                                                AssertAndAdvance(TokenID.Semi);
                                            }*/
                        break;
                    }

                case TokenID.Unsafe:
                    // preprocessor directives
                    node = ParseUnsafeCode();
                    break;

                case TokenID.Fixed:
                    // preprocessor directives
                    node = ParseFixedStatement();
                    break;


                case TokenID.Star:
                    // dereference variable 
                    // introduced because of the mono file test-406.cs
                    //private static uint DoOp2 (uint *u) {
                    //    *(u) += 100;
                    //    return *u;
                    //}
                    node = new ExpressionStatement(ParseExpression());
                    AssertAndAdvance(TokenID.Semi);
                    break;

                case TokenID.SingleComment:
                case TokenID.MultiComment:
                case TokenID.DocComment:
                    node = new CommentStatement(curtok, strings[curtok.Data], curtok.ID != TokenID.SingleComment);
                    Advance(); // over comment token
                    break;
                default:
                    {
                        Console.WriteLine("Unhandled case in statement parsing: \"" + curtok.ID + "\" in line: " + lineCount);
                        // this is almost always an expression
                        ExpressionStatement dnode = new ExpressionStatement(ParseExpression());
                        node = dnode;
                        if (curtok.ID == TokenID.Semi)
                        {
                            Advance();
                        }
                        break;
                    }
            }
            return node;
        }
示例#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 VisitPredefinedTypeReference(PredefinedTypeNode predefinedTypeNode, object data)
        {
            stackMap.Push(predefinedTypeNode);
            if (predefinedTypeNode.Generic != null)
            {
                 predefinedTypeNode.Generic.AcceptVisitor(this, data);
            }
            stackMap.Pop();
            return null;

        }