private TypeSignature ParseType()
 {
     TypeSignature type = ParseTypeName();
     while (true)
     {
         switch (CurrentToken.Kind)
         {
             case TokenKind.OpenBracket:
                 EatToken();
                 int rank = 1;
                 while (CurrentToken.Kind == TokenKind.Comma)
                 {
                     EatToken();
                     rank++;
                 }
                 if (CurrentToken.Kind != TokenKind.CloseBracket)
                 {
                     throw InvalidSignature();
                 }
                 EatToken();
                 type = new ArrayTypeSignature(type, rank);
                 break;
             case TokenKind.Asterisk:
                 EatToken();
                 type = new PointerTypeSignature(type);
                 break;
             case TokenKind.QuestionMark:
                 EatToken();
                 type = new GenericTypeSignature(
                     SpecialType.System_Nullable_T.GetTypeSignature(),
                     ImmutableArray.Create(type));
                 break;
             default:
                 return type;
         }
     }
 }
 private TypeSignature ParseTypeName()
 {
     TypeSignature signature = null;
     while (true)
     {
         switch (CurrentToken.Kind)
         {
             case TokenKind.Identifier:
                 {
                     var token = EatToken();
                     var name = token.Text;
                     signature = new QualifiedTypeSignature(signature, name);
                 }
                 break;
             case TokenKind.Keyword:
                 if (signature == null)
                 {
                     // Expand special type keywords (object, int, etc.) to qualified names.
                     // This is only done for the first identifier in a qualified name.
                     var specialType = GetSpecialType(CurrentToken.KeywordKind);
                     if (specialType != SpecialType.None)
                     {
                         EatToken();
                         signature = specialType.GetTypeSignature();
                         Debug.Assert(signature != null);
                     }
                     if (signature != null)
                     {
                         break;
                     }
                 }
                 throw InvalidSignature();
             default:
                 throw InvalidSignature();
         }
         if (CurrentToken.Kind == TokenKind.LessThan)
         {
             var typeArguments = ParseTypeArguments();
             signature = new GenericTypeSignature((QualifiedTypeSignature)signature, typeArguments);
         }
         if (CurrentToken.Kind != TokenKind.Dot)
         {
             return signature;
         }
         EatToken();
     }
 }