UpdateToSpan() private method

private UpdateToSpan ( ISourceLocation sourceLocation ) : void
sourceLocation ISourceLocation
return void
示例#1
0
 private BlockStatement ParseStatementBlock(TokenSet followers) {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.CurrentSourceLocation);
   List<Statement> statements = new List<Statement>();
   this.ParseStatements(statements, followers);
   slb.UpdateToSpan(this.scanner.CurrentSourceLocation);
   return new BlockStatement(statements, slb);
 }
示例#2
0
 private Statement ParseDo(TokenSet followers)
   //^ requires this.currentToken == Token.Do;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.CurrentSourceLocation);
   this.GetNextToken();
   this.Skip(Token.While);
   Expression condition = this.ParseExpression(followers|Token.EndOfLine);
   this.Skip(Token.EndOfLine);
   BlockStatement body = this.ParseStatementBlock(followers|Token.Loop);
   slb.UpdateToSpan(this.scanner.CurrentSourceLocation);
   WhileDoStatement result = new WhileDoStatement(condition, body, slb);
   this.SkipClosingKeyword(Token.Loop, followers);
   return result;
 }
示例#3
0
 protected override List<Expression> ParseArgumentList(SourceLocationBuilder slb, TokenSet followers)
 {
     var result = new List<Expression>();
       this.Skip(Token.LeftParenthesis);
       while (this.currentToken != Token.RightParenthesis) {
     if (this.currentToken == Token.Specification) {
       result.Add(this.ParseSpecArgument(followers | Token.Comma | Token.Specification | Token.RightParenthesis));
       continue;
     }
     result.Add(this.ParseArgumentExpression(followers | Token.Comma | Token.Specification | Token.RightParenthesis));
     if (this.currentToken == Token.Comma) {
       this.GetNextToken();
       continue;
     }
     if (this.currentToken == Token.Specification)
       continue;
     break;
       }
       slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
       this.SkipOverTo(Token.RightParenthesis, followers);
       return result;
 }
示例#4
0
 private void ParseRestOfEnum(SourceLocationBuilder sctx, TypeDeclaration type, List<ITypeDeclarationMember> members, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   TypeExpression texpr = new NamedTypeExpression(new SimpleName(type.Name, type.Name.SourceLocation, false));
   this.Skip(Token.LeftBrace);
   while (this.currentToken == Token.LeftBracket || Parser.IdentifierOrNonReservedKeyword[this.currentToken]){
     this.ParseEnumMember(texpr, members, followers|Token.Comma|Token.RightBrace);
     if (this.currentToken == Token.RightBrace) break;
     this.Skip(Token.Comma);
     if (this.currentToken == Token.RightBrace) break;
   }
   sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   this.Skip(Token.RightBrace);
   if (this.currentToken == Token.Semicolon)
     this.GetNextToken();
   this.SkipTo(followers);
 }
示例#5
0
 private void ParseNestedDelegateDeclaration(List<ITypeDeclarationMember> typeMembers, List<SourceCustomAttribute>/*?*/ attributes, TypeDeclaration.Flags flags, SourceLocationBuilder sctx, TokenSet followers)
   //^ requires this.currentToken == Token.Delegate;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   TypeExpression returnType = this.ParseTypeExpression(false, false, followers|Token.LeftParenthesis|Token.Semicolon|Parser.IdentifierOrNonReservedKeyword);
   if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken])
     this.HandleError(Error.ExpectedIdentifier);
   NameDeclaration name = this.ParseNameDeclaration();
   List<Ast.GenericTypeParameterDeclaration> genericParameters = new List<Ast.GenericTypeParameterDeclaration>();
   List<Ast.ParameterDeclaration> parameters = new List<Ast.ParameterDeclaration>();
   SignatureDeclaration signature = new SignatureDeclaration(returnType, parameters, sctx);
   NestedDelegateDeclaration type = new NestedDelegateDeclaration(attributes, flags, name, genericParameters, signature, sctx);
   typeMembers.Add(type);
   this.ParseGenericTypeParameters(genericParameters, followers|Token.LeftParenthesis|Token.Where|Token.Semicolon);
   this.ParseParameters(parameters, Token.RightParenthesis, followers|Token.Where|Token.Semicolon, sctx);
   this.ParseGenericTypeParameterConstraintsClauses(genericParameters, followers|Token.Semicolon);
   sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   if (this.currentToken == Token.Semicolon)
     this.GetNextToken();
   this.SkipTo(followers);
 }
示例#6
0
 private CompileTimeConstant ParseRealLiteral()
   //^ requires this.currentToken == Token.RealLiteral;
 {
   string tokStr = this.scanner.GetTokenSource();
   SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   TypeCode tc = this.scanner.ScanNumberSuffix();
   ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   CompileTimeConstant result;
   string/*?*/ typeName = null;
   switch (tc) {
     case TypeCode.Single:
       typeName = "float";
       float fVal;
       if (!Single.TryParse(tokStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out fVal))
         this.HandleError(ctx, Error.FloatOverflow, typeName);
       else if (fVal == 0f && tokStr.IndexOfAny(nonZeroDigits) >= 0)
         this.HandleError(ctx, Error.FloatOverflow, typeName);
       result = new CompileTimeConstant(fVal, false, ctx);
       break;
     case TypeCode.Empty:
     case TypeCode.Double:
       typeName = "double";
       double dVal;
       if (!Double.TryParse(tokStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out dVal))
         this.HandleError(ctx, Error.FloatOverflow, typeName);
       else if (dVal == 0d && tokStr.IndexOfAny(nonZeroDigits) >= 0)
         this.HandleError(ctx, Error.FloatOverflow, typeName);
       result = new CompileTimeConstant(dVal, tc == TypeCode.Empty, ctx);
       break;
     case TypeCode.Decimal:
       typeName = "decimal";
       decimal decVal;
       if (!Decimal.TryParse(tokStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out decVal))
         this.HandleError(ctx, Error.FloatOverflow, typeName);
       result = new CompileTimeConstant(decVal, false, ctx);
       break;
     default:
       this.HandleError(Error.ExpectedSemicolon);
       goto case TypeCode.Empty;
   }
   //^ assume this.currentToken == Token.RealLiteral; //follows from the precondition
   this.GetNextToken();
   return result;
 }
示例#7
0
 private CompileTimeConstant ParseHexLiteral()
   //^ requires this.currentToken == Token.HexLiteral;
 {
   string tokStr = this.scanner.GetTokenSource();
   //^ assume tokStr.StartsWith("0x") || tokStr.StartsWith("0X"); //The scanner should not return a Token.HexLiteral when this is not the case.
   SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   TypeCode tc = this.scanner.ScanNumberSuffix();
   ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   CompileTimeConstant result;
   switch (tc) {
     case TypeCode.Single:
     case TypeCode.Double:
     case TypeCode.Decimal:
       this.HandleError(Error.ExpectedSemicolon);
       goto default;
     default:
       ulong ul;
       //^ assume tokStr.Length >= 2;
       if (!UInt64.TryParse(tokStr.Substring(2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out ul)) {
         this.HandleError(ctx, Error.IntOverflow);
         ul = 0;
       }
       result = GetConstantOfSmallestIntegerTypeThatIncludes(ul, tc, ctx);
       break;
   }
   //^ assume this.currentToken == Token.HexLiteral; //follows from the precondition
   this.GetNextToken();
   return result;
 }
示例#8
0
 private Indexer ParseIndexer(Expression indexedObject, TokenSet followers)
   //^ requires this.currentToken == Token.LeftBracket;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(indexedObject.SourceLocation);
   this.GetNextToken();
   List<Expression> indices = new List<Expression>();
   while (this.currentToken != Token.RightBracket) {
     Expression index = this.ParseExpression(followers|Token.Comma|Token.RightBracket);
     indices.Add(index);
     if (this.currentToken != Token.Comma) break;
     this.GetNextToken();
   }
   indices.TrimExcess();
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   Indexer result = new Indexer(indexedObject, indices.AsReadOnly(), slb);
   this.SkipOverTo(Token.RightBracket, followers);
   return result;
 }
示例#9
0
 private List<Expression> ParseArgumentList(SourceLocationBuilder slb, TokenSet followers)
   //^ requires this.currentToken == Token.LeftParenthesis;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   TokenSet followersOrCommaOrRightParenthesis = followers|Token.Comma|Token.RightParenthesis;
   List<Expression> arguments = new List<Expression>();
   if (this.currentToken != Token.RightParenthesis) {
     Expression argument = this.ParseArgument(followersOrCommaOrRightParenthesis);
     arguments.Add(argument);
     while (this.currentToken == Token.Comma) {
       this.GetNextToken();
       argument = this.ParseArgument(followersOrCommaOrRightParenthesis);
       arguments.Add(argument);
     }
   }
   arguments.TrimExcess();
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   this.SkipOverTo(Token.RightParenthesis, followers);
   return arguments;
 }
示例#10
0
 private uint ParseRankSpecifier(SourceLocationBuilder sctx, TokenSet followers)
   //^ requires this.currentToken == Token.LeftBracket;
   //^ ensures result > 0;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   uint rank = 1;
   while (this.currentToken == Token.Comma) {
     rank++;
     this.GetNextToken();
   }
   ISourceLocation tokLoc = this.scanner.SourceLocationOfLastScannedToken;
   //^ assume tokLoc.SourceDocument == sctx.SourceDocument;
   sctx.UpdateToSpan(tokLoc);
   this.SkipOverTo(Token.RightBracket, followers);
   return rank;
 }
示例#11
0
 private Expression ParseGetValueOfTypedReference(TokenSet followers)
   //^ requires this.currentToken == Token.RefValue;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   this.Skip(Token.LeftParenthesis);
   Expression e = this.ParseExpression(followers|Token.Comma);
   this.Skip(Token.Comma);
   TypeExpression te = this.ParseTypeExpression(false, false, followers|Token.RightParenthesis);
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   Expression result = new GetValueOfTypedReference(e, te, slb);
   this.SkipOverTo(Token.RightParenthesis, followers);
   return result;
 }
示例#12
0
 private LambdaParameter ParseLambdaParameter(bool allowType, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   bool isOut = false;
   bool isRef = false;
   Token firstToken = this.currentToken;
   NameDeclaration parameterName = new NameDeclaration(this.GetNameFor(this.scanner.GetIdentifierString()), this.scanner.SourceLocationOfLastScannedToken);
   TypeExpression/*?*/ parameterType = null;
   if (allowType) {
     if (this.currentToken == Token.Out) { isOut = true; this.GetNextToken(); } 
     else if (this.currentToken == Token.Ref) { isRef = true; this.GetNextToken(); }
     parameterType = this.ParseTypeExpression(false, false, followers);
     if ((this.currentToken == Token.Comma || this.currentToken == Token.RightParenthesis) && Parser.IdentifierOrNonReservedKeyword[firstToken]) {
       parameterType = null;
     } else {
       parameterName = new NameDeclaration(this.GetNameFor(this.scanner.GetIdentifierString()), this.scanner.SourceLocationOfLastScannedToken);
     }
   }
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   LambdaParameter result = new LambdaParameter(isOut, isRef, parameterType, parameterName, slb);
   if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken])
     this.HandleError(Error.ExpectedIdentifier);
   else {
     //^ assume this.currentToken != Token.EndOfFile; //follows from definition of Parser.IdentifierOrNonReservedKeyword
     this.GetNextToken();
   }
   this.SkipTo(followers);
   return result;
 }
示例#13
0
    private Expression ParsePrimaryExpression(TokenSet followers)
      //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
    {
      ISourceLocation sctx = this.scanner.SourceLocationOfLastScannedToken;
      Expression expression = new DummyExpression(sctx);
      switch (this.currentToken) {
        case Token.ArgList:
          this.GetNextToken();
          expression = new RuntimeArgumentHandleExpression(sctx);
          break;
        case Token.Delegate:
          expression = this.ParseAnonymousMethod(followers);
          break;
        case Token.New:
          expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow);
          break;
        case Token.Identifier:
          expression = this.ParseSimpleName(followers|Token.Dot|Token.DoubleColon|Token.Lambda|Token.LeftParenthesis);
          if (this.currentToken == Token.DoubleColon) {
            if (((SimpleName)expression).Name == this.nameTable.global)
              expression = new RootNamespaceExpression(expression.SourceLocation);
            expression = this.ParseQualifiedName(expression, followers|Token.Dot|Token.LessThan|Token.LeftParenthesis|Token.AddOne|Token.SubtractOne);
          } else if (this.currentToken == Token.Lambda) {
            expression = this.ParseLambda((SimpleName)expression, followers);
          }
          break;
        case Token.Null:
          expression = new NullLiteral(sctx);
          this.GetNextToken();
          break;
        case Token.True:
          expression = new CompileTimeConstant(true, false, sctx);
          this.GetNextToken();
          break;
        case Token.False:
          expression = new CompileTimeConstant(false, false, sctx);
          this.GetNextToken();
          break;
        case Token.CharLiteral:
          expression = new CompileTimeConstant(this.scanner.charLiteralValue, false, sctx);
          this.GetNextToken();
          break;
        case Token.HexLiteral:
          expression = this.ParseHexLiteral();
          break;
        case Token.IntegerLiteral:
          expression = this.ParseIntegerLiteral();
          break;
        case Token.RealLiteral:
          expression = this.ParseRealLiteral();
          break;
        case Token.StringLiteral:
          expression = new CompileTimeConstant(this.scanner.GetString(), false, sctx);
          this.GetNextToken();
          break;
        case Token.This:
          expression = new ThisReference(sctx);
          this.GetNextToken();
          break;
        case Token.Base:
          expression = new BaseClassReference(sctx);
          this.GetNextToken();
          break;
        case Token.Typeof:
        case Token.Sizeof:
        case Token.Default: 
          expression = this.ParseTypeofSizeofOrDefault(followers);
          break;
        case Token.Stackalloc:
          return this.ParseStackalloc(followers);
        case Token.Checked:
        case Token.MakeRef:
        case Token.RefType:
        case Token.Unchecked:
          expression = this.ParseCheckedOrMakeRefOrRefTypeOrUnchecked(followers);
          break;
        case Token.RefValue:
          expression = this.ParseGetValueOfTypedReference(followers);
          break;
        case Token.Bool:
        case Token.Decimal:
        case Token.Sbyte:
        case Token.Byte:
        case Token.Short:
        case Token.Ushort:
        case Token.Int:
        case Token.Uint:
        case Token.Long:
        case Token.Ulong:
        case Token.Char:
        case Token.Float:
        case Token.Double:
        case Token.Object:
        case Token.String:
          expression = this.RootQualifiedNameFor(this.currentToken, sctx);
          this.GetNextToken();
          break;
        case Token.LeftParenthesis:
          expression = this.ParseCastExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow);
          break;
        default:
          if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier;
          if (Parser.InfixOperators[this.currentToken]) {
            this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource());
            //^ assume this.currentToken != Token.EndOfFile; //should not be a member of InfixOperators
            this.GetNextToken();
          } else
            this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource());
          if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers);
          goto done;
      }

      expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne);
      for (; ; ) {
        switch (this.currentToken) {
          case Token.AddOne:
            SourceLocationBuilder slb = new SourceLocationBuilder(expression.SourceLocation);
            slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
            this.GetNextToken();
            expression = new PostfixIncrement(new TargetExpression(expression), slb);
            break;
          case Token.SubtractOne:
            slb = new SourceLocationBuilder(expression.SourceLocation);
            slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
            this.GetNextToken();
            expression = new PostfixDecrement(new TargetExpression(expression), slb);
            break;
          case Token.Arrow:
          case Token.Dot:
          case Token.LeftBracket:
            expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne);
            break;
          default:
            goto done;
        }
      }
    done:
      this.SkipTo(followers);
      return expression;
    }
示例#14
0
 private Expression ParseUnaryExpression(TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   switch (this.currentToken) {
     case Token.AddOne:
     case Token.BitwiseAnd:
     case Token.BitwiseNot:
     case Token.LogicalNot:
     case Token.Multiply:
     case Token.Plus:
     case Token.Subtract:
     case Token.SubtractOne:
       SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
       Token operatorToken = this.currentToken;
       this.GetNextToken();
       Expression operand = this.ParseUnaryExpression(followers);
       slb.UpdateToSpan(operand.SourceLocation);
       Expression result = AllocateUnaryExpression(operatorToken, operand, slb);
       //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
       return result;
     //case Token.LeftParenthesis:
     //  return this.ParseCastExpression(followers);
     default:
       return this.ParsePrimaryExpression(followers);
   }
 }
示例#15
0
 private Expression ParseConditional(Expression condition, TokenSet followers) 
   //^ requires this.currentToken == Token.Conditional;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   SourceLocationBuilder slb = new SourceLocationBuilder(condition.SourceLocation);
   Expression resultIfTrue = this.ParseExpression(followers|Token.Colon);
   Expression resultIfFalse;
   if (this.currentToken == Token.Colon) {
     this.GetNextToken();
     resultIfFalse = this.ParseExpression(followers);
   } else {
     this.Skip(Token.Colon); //gives appropriate error message
     if (!followers[this.currentToken])
       //Assume that only the : is missing. Go ahead as if it were specified.
       resultIfFalse = this.ParseExpression(followers);
     else
       resultIfFalse = this.ParseDummyExpression();
   }
   slb.UpdateToSpan(resultIfFalse.SourceLocation);
   Expression result = new Conditional(condition, resultIfTrue, resultIfFalse, slb);
   this.SkipTo(followers);
   return result;
 }
示例#16
0
 private Expression ParseQualifiedName(Expression qualifier, TokenSet followers)
   //^ requires this.currentToken == Token.Arrow || this.currentToken == Token.Dot || this.currentToken == Token.DoubleColon;
   //^ requires this.currentToken == Token.DoubleColon ==> qualifier is SimpleName || qualifier is RootNamespaceExpression;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   Token tok = this.currentToken;
   SourceLocationBuilder slb = new SourceLocationBuilder(qualifier.SourceLocation);
   this.GetNextToken();
   SimpleName name = this.ParseSimpleName(followers);
   slb.UpdateToSpan(name.SourceLocation);
   Expression result;
   if (tok == Token.Arrow) 
     result = new PointerQualifiedName(qualifier, name, slb);
   else if (tok == Token.DoubleColon) 
     result = new AliasQualifiedName(qualifier, name, slb);
   else {
     //^ assert tok == Token.Dot;
     result = new QualifiedName(qualifier, name, slb);
   }
   //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   return result;
 }
示例#17
0
 private Expression ParseTypeofSizeofOrDefault(TokenSet followers)
   //^ requires this.currentToken == Token.Typeof || this.currentToken == Token.Sizeof || this.currentToken == Token.Default;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   Token tok = this.currentToken;
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   this.Skip(Token.LeftParenthesis);
   TypeExpression type = this.ParseTypeExpression(false, true, followers|Token.RightParenthesis);
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   this.SkipOverTo(Token.RightParenthesis, followers);
   Expression result;
   if (tok == Token.Typeof) 
     result = new TypeOf(type, slb);
   else if (tok == Token.Sizeof)
     result = new SizeOf(type, slb);
   else {
     //^ assert tok == Token.Default;
     result = new DefaultValue(type, slb);
   }
   //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   return result;
 }
示例#18
0
 private Expression ParseStackalloc(TokenSet followers)
   //^ requires this.currentToken == Token.Stackalloc;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   TypeExpression elementType = this.ParseBaseTypeExpression(false, followers|Token.LeftBracket);
   Token openingDelimiter = this.currentToken;
   if (this.currentToken != Token.LeftBracket) {
     this.HandleError(Error.BadStackAllocExpr);
     if (this.currentToken == Token.LeftParenthesis) this.GetNextToken();
   } else
     this.GetNextToken();
   Expression size = this.ParseExpression(followers|Token.RightBracket|Token.RightParenthesis);
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   if (this.currentToken == Token.RightParenthesis && openingDelimiter == Token.LeftParenthesis)
     this.GetNextToken();
   else
     this.Skip(Token.RightBracket);
   Expression result = new CreateStackArray(elementType, size, slb);
   this.SkipTo(followers);
   return result;
 }
示例#19
0
 private Expression ParseArgument(TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   switch (this.currentToken) {
     case Token.Ref:
       SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
       this.GetNextToken();
       Expression expr = this.ParseExpression(followers);
       slb.UpdateToSpan(expr.SourceLocation);
       Expression refArg = new RefArgument(new AddressableExpression(expr), slb);
       //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
       return refArg;
     case Token.Out:
       slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
       this.GetNextToken();
       expr = this.ParseExpression(followers);
       slb.UpdateToSpan(expr.SourceLocation);
       Expression outArg = new OutArgument(new TargetExpression(expr), slb);
       //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
       return outArg;
     //case Token.ArgList:
     //  slb = new SourceLocationBuilder(this.scanner.CurrentSourceContext);
     //  this.GetNextToken();
     //  if (this.currentToken == Token.LeftParenthesis) {
     //    ExpressionList el = this.ParseExpressionList(followers, ref sctx);
     //    return new ArglistArgumentExpression(el, sctx);
     //  }
     //  return new ArglistExpression(sctx);
     default:
       return this.ParseExpression(followers);
   }
 }
示例#20
0
 private Expression ParseAnonymousMethod(TokenSet followers)
   //^ requires this.currentToken == Token.Delegate;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   List<Ast.ParameterDeclaration> parameters = new List<Ast.ParameterDeclaration>();
   if (this.currentToken == Token.LeftParenthesis)
     this.ParseParameters(parameters, Token.RightParenthesis, followers);
   BlockStatement body = this.ParseBody(followers); //TODO: just parse a block
   //^ assert followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   slb.UpdateToSpan(body.SourceLocation);
   Expression result = new AnonymousMethod(parameters, body, slb);
   //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   return result;
 }
示例#21
0
 private Expression ParseParenthesizedExpression(bool keepParentheses, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder sctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   if (this.currentToken == Token.LeftBrace) {
     Expression dummy = new DummyExpression(sctx);
     this.SkipTo(followers, Error.SyntaxError, "(");
     return dummy;
   }
   this.Skip(Token.LeftParenthesis);
   Expression result = this.ParseExpression(followers|Token.RightParenthesis|Token.Colon);
   if (keepParentheses) {
     sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     result = new Parenthesis(result, sctx);
   }
   this.SkipOverTo(Token.RightParenthesis, followers);
   return result;
 }
示例#22
0
 private Expression ParseNew(TokenSet followers) 
   //^ requires this.currentToken == Token.New;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   if (this.currentToken == Token.LeftBracket)
     return this.ParseNewImplicitlyTypedArray(ctx, followers);
   if (this.currentToken == Token.LeftBrace)
     return this.ParseNewAnonymousTypeInstance(ctx, followers);
   TypeExpression t = this.ParseBaseTypeExpression(false, followers|Parser.InfixOperators|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
   if (this.currentToken == Token.Conditional) {
     SourceLocationBuilder slb = new SourceLocationBuilder(t.SourceLocation);
     slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     //^ assume this.currentToken == Token.Conditional; //no side effects from the methods can touch this.currentToken
     this.GetNextToken();
     t = new NullableTypeExpression(t, slb);
   //} else if (this.currentToken == Token.LogicalNot) {
   //  TypeExpression type = t;
   //  t = new NonNullableTypeExpression(type);
   //  t.SourceContext = type.SourceContext;
   //  t.SourceContext.EndPos = this.scanner.endPos;
   //  this.GetNextToken();
   } else if (this.currentToken == Token.Multiply) {
     SourceLocationBuilder slb = new SourceLocationBuilder(t.SourceLocation);
     slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     //^ assume this.currentToken == Token.Multiply; //no side effects from the methods can touch this.currentToken
     this.GetNextToken();
     t = new PointerTypeExpression(t, slb);
   }
   ctx.UpdateToSpan(t.SourceLocation);
   TypeExpression et = t;
   uint rank = 0;
   while (this.currentToken == Token.LeftBracket) {
     Token nextTok = this.PeekNextToken();
     if (nextTok != Token.Comma && nextTok != Token.RightBracket) break; //not a rank specifier, but a size specifier
     rank = this.ParseRankSpecifier(ctx, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
     et = t;
     t = new ArrayTypeExpression(et, rank, ctx);
   }
   if (rank > 0) {
     //new T[] {...} or new T[,] {{..} {...}...}, etc where T can also be an array type
     List<Expression> initializers;
     if (this.currentToken == Token.LeftBrace)
       initializers = this.ParseArrayInitializers(rank, et, followers, false, ctx);
     else {
       initializers = new List<Expression>(0);
       if (Parser.UnaryStart[this.currentToken])
         this.HandleError(Error.ExpectedLeftBrace);
       else
         this.HandleError(Error.MissingArraySize);
       while (Parser.UnaryStart[this.currentToken]) {
         this.ParseExpression(followers|Token.Comma|Token.RightBrace);
         if (this.currentToken != Token.Comma) break;
         this.GetNextToken();
       }
       ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
       this.SkipOverTo(Token.RightBrace, followers);
     }
     return new CreateArray(et, initializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank, new List<Expression>(0).AsReadOnly(), ctx);
   }
   if (this.currentToken == Token.LeftBracket) {
     //new T[x] or new T[x,y] etc. possibly followed by an initializer or element type rank specifier
     this.GetNextToken();
     List<Expression> sizes = this.ParseExpressionList(ctx, followers|Token.LeftBrace|Token.LeftBracket);
     rank = (uint)sizes.Count;
     List<Expression> initializers;
     if (this.currentToken == Token.LeftBrace)
       initializers = this.ParseArrayInitializers(rank, t, followers, false, ctx);
     else {
       uint elementRank = 0;
     tryAgain:
       while (this.currentToken == Token.LeftBracket) {
         Token nextTok = this.PeekNextToken();
         if (nextTok != Token.Comma && nextTok != Token.RightBracket) break; //not a rank specifier, but a size specifier
         elementRank = this.ParseRankSpecifier(ctx, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
         t = new ArrayTypeExpression(t, elementRank, ctx);
       }
       if (this.currentToken == Token.LeftBrace)
         initializers = this.ParseArrayInitializers(rank, t, followers, false, ctx);
       else {
         if (this.currentToken == Token.LeftBracket) { //new T[x][y] or something like that
           this.GetNextToken();
           this.HandleError(Error.InvalidArray);
           elementRank = (uint)this.ParseExpressionList(ctx, followers).Count;
           goto tryAgain;
         } else {
           initializers = new List<Expression>(0);
           ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
           this.SkipTo(followers);
         }
       }
     }
     return new CreateArray(t, initializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank, sizes.AsReadOnly(), ctx);
   }
   //new T(...)
   IEnumerable<Expression> arguments = Expression.EmptyCollection;
   IEnumerable<Expression> elementValues = Expression.EmptyCollection;
   IEnumerable<NamedArgument> namedArguments = NamedArgument.EmptyCollection;
   if (this.currentToken == Token.LeftParenthesis) {
     //if (t is NonNullableTypeExpression) {
     //  this.SkipTo(followers, Error.BadNewExpr);
     //  return null;
     //}
     arguments = this.ParseArgumentList(ctx, followers|Token.LeftBrace).AsReadOnly();
   } else if (this.currentToken != Token.LeftBrace) {
     this.SkipTo(followers, Error.BadNewExpr);
   }
   Expression result = new CreateObjectInstance(t, arguments, ctx.GetSourceLocation());
   if (this.currentToken == Token.LeftBrace) {
     this.ParseElementValuesOrNamedArguments(ref elementValues, ref namedArguments, ctx, followers);
     if (elementValues != Expression.EmptyCollection)
       return new PopulateCollection(result, elementValues, ctx);
     else if (namedArguments != NamedArgument.EmptyCollection)
       return new InitializeObject(result, namedArguments, ctx);
     else {
       this.HandleError(Error.SyntaxError); //TODO: better error
     }
   }
   return result;
 }
示例#23
0
 private CompileTimeConstant ParseIntegerLiteral() 
   //^ requires this.currentToken == Token.IntegerLiteral;
 {
   string tokStr = this.scanner.GetTokenSource();
   SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   TypeCode tc = this.scanner.ScanNumberSuffix();
   ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   CompileTimeConstant result;
   switch (tc) {
     case TypeCode.Single:
       float f;
       if (!Single.TryParse(tokStr, System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, out f)) {
         this.HandleError(ctx, Error.FloatOverflow);
         f = float.NaN;
       }
       result = new CompileTimeConstant(f, false, ctx);
       break;
     case TypeCode.Double:
       double d;
       if (!Double.TryParse(tokStr, System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, out d)) {
         this.HandleError(ctx, Error.FloatOverflow);
         d = double.NaN;
       }
       result = new CompileTimeConstant(d, false, ctx);
       break;
     case TypeCode.Decimal:
       decimal m;
       if (!decimal.TryParse(tokStr, System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, out m)) {
         this.HandleError(ctx, Error.IntOverflow);
         m = decimal.Zero;
       }
       result = new CompileTimeConstant(m, false, ctx);
       break;
     default:
       ulong ul;
       if (!UInt64.TryParse(tokStr, System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, out ul)) {
         this.HandleError(ctx, Error.IntOverflow);
         ul = 0;
       }
       result = GetConstantOfSmallestIntegerTypeThatIncludes(ul, tc, ctx);
       break;
   }
   //^ assume this.currentToken == Token.IntegerLiteral; //follows from the precondition
   this.GetNextToken();
   return result;
 }
示例#24
0
 private Expression ParseNewAnonymousTypeInstance(SourceLocationBuilder slb, TokenSet followers)
   //^ requires this.currentToken == Token.LeftBrace;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   TokenSet followersOrCommaOrRightBrace = followers|Token.Comma|Token.RightBrace;
   List<Expression> initializers = new List<Expression>();
   while (Parser.UnaryStart[this.currentToken]) 
     // ^ invariant forall{IExpression initializer in initializers; initializer is NamedArgument || initializer is SimpleName || initializer is QualifiedName};
   {
     SourceLocationBuilder eslb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
     Expression e = this.ParseUnaryExpression(followersOrCommaOrRightBrace|Parser.InfixOperators);
     SimpleName/*?*/ id = e as SimpleName;
     if (this.currentToken == Token.Assign) {
       this.GetNextToken();
       if (id == null) this.HandleError(e.SourceLocation, Error.ExpectedIdentifier);
       e = this.ParseExpression(followersOrCommaOrRightBrace);
       eslb.UpdateToSpan(e.SourceLocation);
       if (id != null) initializers.Add(new NamedArgument(id, e, eslb));
     } else {
       if (id != null)
         initializers.Add(id);
       else {
         QualifiedName/*?*/ qualId = e as QualifiedName;
         if (qualId != null)
           initializers.Add(qualId);
         else {
           this.HandleError(e.SourceLocation, Error.SyntaxError);
         }
       }
     }
     if (this.currentToken != Token.Comma) break;
     this.GetNextToken();
   }
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   Expression result = new CreateAnonymousObject(initializers, slb);
   this.SkipOverTo(Token.RightBracket, followers);
   return result;
 }
示例#25
0
 private void ParseNestedNamespaceDeclaration(List<INamespaceDeclarationMember> parentMembers, TokenSet followers)
   //^ requires this.currentToken == Token.Namespace;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder nsCtx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]) 
     this.HandleError(Error.ExpectedIdentifier);
   NameDeclaration nsName = this.ParseNameDeclaration();
   nsCtx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   List<INamespaceDeclarationMember> nestedMembers = new List<INamespaceDeclarationMember>();
   List<Ast.SourceCustomAttribute> nestedSourceAttributes = new List<Ast.SourceCustomAttribute>();
   NestedNamespaceDeclaration nestedNamespace = new NestedNamespaceDeclaration(nsName, nestedMembers, nestedSourceAttributes, nsCtx);
   parentMembers.Add(nestedNamespace);
   while (this.currentToken == Token.Dot) {
     this.GetNextToken();
     if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken])
       this.HandleError(Error.ExpectedIdentifier);
     nsName = this.ParseNameDeclaration();
     parentMembers = nestedMembers;
     nestedMembers = new List<INamespaceDeclarationMember>();
     nestedSourceAttributes = new List<SourceCustomAttribute>();
     nestedNamespace = new NestedNamespaceDeclaration(nsName, nestedMembers, nestedSourceAttributes, nsCtx);
     parentMembers.Add(nestedNamespace);
   }
   this.Skip(Token.LeftBrace);
   this.ParseNamespaceBody(nestedMembers, null, followers|Token.RightBrace);
   nsCtx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   this.SkipOverTo(Token.RightBrace, followers);
 }
示例#26
0
 private List<Expression> ParseExpressionList(SourceLocationBuilder slb, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   TokenSet followersOrCommaOrRightBracket = followers|Token.Comma|Token.RightBracket;
   List<Expression> result = new List<Expression>();
   if (this.currentToken != Token.RightBracket) {
     Expression expression = this.ParseExpression(followersOrCommaOrRightBracket);
     result.Add(expression);
     while (this.currentToken == Token.Comma) {
       this.GetNextToken();
       expression = this.ParseExpression(followersOrCommaOrRightBracket);
       result.Add(expression);
     }
   }
   slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   this.Skip(Token.RightBracket);
   this.SkipTo(followers);
   return result;
 }
示例#27
0
 private void ParseRestOfTypeDeclaration(SourceLocationBuilder sctx, TypeDeclaration type, List<Ast.GenericTypeParameterDeclaration> genericParameters,
   List<TypeExpression> baseTypes, List<ITypeDeclarationMember> members, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.ParseGenericTypeParameters(genericParameters, followers|Token.Colon|Token.LeftBrace|Token.Where);
   this.ParseBaseTypes(baseTypes, followers|Token.LeftBrace|Token.Where);
   this.ParseGenericTypeParameterConstraintsClauses(genericParameters, followers|Token.LeftBrace);
   this.Skip(Token.LeftBrace);
   this.ParseTypeMembers(sctx, type.Name, members, followers|Token.RightBrace);
   ISourceLocation tokLoc = this.scanner.SourceLocationOfLastScannedToken;
   //^ assume tokLoc.SourceDocument == sctx.SourceDocument;
   sctx.UpdateToSpan(tokLoc);
   this.Skip(Token.RightBrace);
   if (this.currentToken == Token.Semicolon)
     this.GetNextToken();
   this.SkipTo(followers);
 }
示例#28
0
 private List<Expression> ParseArrayInitializers(uint rank, TypeExpression elementType, TokenSet followers, bool doNotSkipClosingBrace, SourceLocationBuilder ctx)
   //^ requires this.currentToken == Token.LeftBrace;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   List<Expression> initialValues = new List<Expression>();
   if (this.currentToken == Token.RightBrace) {
     ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     this.GetNextToken();
     initialValues.TrimExcess();
     return initialValues;
   }
   while (true) {
     if (rank > 1) {
       List<Expression> elemArrayInitializers;
       SourceLocationBuilder ectx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
       if (this.currentToken == Token.LeftBrace) {
         elemArrayInitializers = this.ParseArrayInitializers(rank-1, elementType, followers|Token.Comma|Token.LeftBrace, false, ectx);
       } else {
         elemArrayInitializers = new List<Expression>(0);
         this.SkipTo(followers|Token.Comma|Token.LeftBrace, Error.ExpectedLeftBrace);
       }
       CreateArray elemArr = new CreateArray(elementType, elemArrayInitializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank-1, new List<Expression>(0).AsReadOnly(), ectx);
       initialValues.Add(elemArr);
     } else {
       if (this.currentToken == Token.LeftBrace) {
         this.HandleError(Error.ArrayInitInBadPlace);
         SourceLocationBuilder ectx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
         //^ assume this.currentToken == Token.LeftBrace;
         List<Expression> elemArrayInitializers = this.ParseArrayInitializers(1, elementType, followers|Token.Comma|Token.LeftBrace, false, ectx);
         CreateArray elemArr = new CreateArray(elementType, elemArrayInitializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), 1, new List<Expression>(0).AsReadOnly(), ectx);
         initialValues.Add(elemArr);
       } else
         initialValues.Add(this.ParseExpression(followers|Token.Comma|Token.RightBrace));
     }
     if (this.currentToken != Token.Comma) break;
     this.GetNextToken();
     if (this.currentToken == Token.RightBrace) break;
   }
   ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   if (!doNotSkipClosingBrace) {
     this.Skip(Token.RightBrace);
     this.SkipTo(followers);
   }
   initialValues.TrimExcess();
   return initialValues;
 }
示例#29
0
 private void ParseTypeMembers(SourceLocationBuilder sctx, IName typeName, List<ITypeDeclarationMember> members, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   TokenSet followersOrTypeMemberStart = followers|Parser.TypeMemberStart;
   for (; ; ) {
     SourceLocationBuilder tctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
     List<SourceCustomAttribute>/*?*/ attributes = this.ParseAttributes(followersOrTypeMemberStart);
     List<ModifierToken> modifiers = this.ParseModifiers();
     switch (this.currentToken) {
       case Token.Class:
         this.ParseNestedClassDeclaration(members, attributes, this.ConvertToTypeDeclarationFlags(modifiers), tctx, followersOrTypeMemberStart);
         break;
       case Token.Interface:
         this.ParseNestedInterfaceDeclaration(members, attributes, this.ConvertToTypeDeclarationFlags(modifiers), tctx, followersOrTypeMemberStart);
         break;
       case Token.Struct:
         this.ParseNestedStructDeclaration(members, attributes, this.ConvertToTypeDeclarationFlags(modifiers), tctx, followersOrTypeMemberStart);
         break;
       case Token.Enum:
         this.ParseNestedEnumDeclaration(members, attributes, this.ConvertToTypeDeclarationFlags(modifiers), tctx, followersOrTypeMemberStart);
         break;
       case Token.Delegate:
         this.ParseNestedDelegateDeclaration(members, attributes, this.ConvertToTypeDeclarationFlags(modifiers), tctx, followersOrTypeMemberStart);
         break;
       case Token.Const:
         this.ParseConst(members, attributes, modifiers, tctx, followersOrTypeMemberStart);
         break;
       case Token.Invariant:
         goto default;
         //this.ParseInvariant(attributes, modifierTokens, modifierContexts, tctx, followersOrTypeMemberStart);
         //break;
       case Token.Bool:
       case Token.Decimal:
       case Token.Sbyte:
       case Token.Byte:
       case Token.Short:
       case Token.Ushort:
       case Token.Int:
       case Token.Uint:
       case Token.Long:
       case Token.Ulong:
       case Token.Char:
       case Token.Float:
       case Token.Double:
       case Token.Object:
       case Token.String:
       case Token.Void:
       case Token.Identifier:
         this.ParseConstructorOrFieldOrMethodOrPropertyOrStaticInitializer(typeName, members, attributes, modifiers, tctx, followersOrTypeMemberStart);
         break;
       case Token.Event:
         this.ParseEvent(members, attributes, modifiers, tctx, followersOrTypeMemberStart); 
         break;
       case Token.Operator:
       case Token.Explicit:
       case Token.Implicit:
         this.ParseOperator(members, attributes, modifiers, null, tctx, followersOrTypeMemberStart); 
         break;
       case Token.BitwiseNot:
         this.ParseDestructor(typeName, members, attributes, modifiers, tctx, followersOrTypeMemberStart); 
         break;
       default:
         if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier;
         sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
         this.SkipTo(followers);
         return;
     }
   }
 }
示例#30
0
 private Expression ParseCastExpression(TokenSet followers)
   //^ requires this.currentToken == Token.LeftParenthesis;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   int position = this.scanner.CurrentDocumentPosition();
   this.GetNextToken();
   List<IErrorMessage> savedErrors = this.scannerAndParserErrors;
   this.scannerAndParserErrors = new List<IErrorMessage>(0);
   TypeExpression targetType = this.ParseTypeExpression(false, false, followers|Token.RightParenthesis);
   bool isCast = false;
   bool isLambda = false;
   if (this.currentToken == Token.RightParenthesis && this.scannerAndParserErrors.Count == 0) {
     if (targetType is NamedTypeExpression) {
       Token nextTok = this.PeekNextToken();
       isCast = Parser.CastFollower[nextTok];
       isLambda = nextTok == Token.Lambda;
     } else
       //Parsed a type expression that cannot also be a value expression.
       isCast = true;
   }
   this.scannerAndParserErrors = savedErrors;
   Expression expression;
   if (!isCast) {
     //Encountered an error while trying to parse (type expr) and there is some reason to be believe that this might not be a type argument list at all.
     //Back up the scanner and let the caller carry on as if it knew that < is the less than operator
     this.scanner.RestoreDocumentPosition(position);
     this.currentToken = Token.None;
     this.GetNextToken();
     if (isLambda)
       expression = this.ParseLambda(followers);
     else
       expression = this.ParseParenthesizedExpression(true, followers);
   } else {
     this.Skip(Token.RightParenthesis);
     Expression valueToCast = this.ParseUnaryExpression(followers);
     slb.UpdateToSpan(valueToCast.SourceLocation);
     expression = new Cast(valueToCast, targetType, slb);
   }
   for (; ; ) {
     switch (this.currentToken) {
       case Token.Arrow:
       case Token.Dot:
       case Token.LeftBracket:
         expression = this.ParseIndexerCallOrSelector(expression, followers);
         break;
       default:
         goto done;
     }
   }
 done:
   this.SkipTo(followers);
   return expression;
 }