private StatementNode parseStatement() { saveScannerState(); switch (lexicalUnit) { case OpenBrace: return parseBlockStatement(); case SemiColon: var emptyStatement = new EmptyStatementNode { EndPosition = scanner.EndPosition }; setScannerState(emptyStatement); nextLexicalUnit(false); return emptyStatement; case Keyword: case ContextualKeyword: switch (scanner.Keyword) { case Byte: case Char: case Short: case Int: case Long: case Boolean: case Double: case Float: case Void: case String: return parseLabeledOrLocalDeclarationOrExpressionStatement(); case Yield: { var yieldStatement = new YieldStatementNode(); setScannerState(yieldStatement); switch (nextLexicalUnit(true)) { case Keyword: switch (scanner.Keyword) { case Return: nextLexicalUnit(true); yieldStatement.Value = parseExpression(); break; case Break: nextLexicalUnit(true); break; default: throw error(ParseErrorId.ReturnOrBreakExpected); } break; default: throw error(ParseErrorId.ReturnOrBreakExpected); } yieldStatement.EndPosition = parseSemiColon(false, false); return yieldStatement; } case Try: { var tryStatement = new TryStatementNode(); setScannerState(tryStatement); nextLexicalUnit(true); tryStatement.Block = parseBlockStatement(); var hasCatch = false; var done = false; int endPosition = 0; do { switch (lexicalUnit) { case Keyword: switch (scanner.Keyword) { case Catch: var catchClause = new CatchClauseNode(); setScannerState(catchClause); if (nextLexicalUnit(true) == LexicalUnit.OpenParenthesis) { nextLexicalUnit(true); catchClause.ExceptionType = parseType(true); if (isIdentifier(lexicalUnit)) { catchClause.NameOffset = scanner.StartPosition; catchClause.NameLength = getLexicalUnitLength(); nextLexicalUnit(true); } if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); } catchClause.Block = parseBlockStatement(); tryStatement.CatchClauses.add(catchClause); endPosition = catchClause.Block.EndPosition; catchClause.EndPosition = endPosition; hasCatch = true; break; case Finally: nextLexicalUnit(true); tryStatement.Finally = parseBlockStatement(); endPosition = tryStatement.Finally.EndPosition; done = true; break; default: if (!hasCatch) { throw error(ParseErrorId.FinallyExpected); } done = true; break; } break; default: if (!hasCatch) { throw error(ParseErrorId.FinallyExpected); } done = true; break; } } while (!done); tryStatement.EndPosition = endPosition; return tryStatement; } case Using: { var usingStatement = new UsingStatementNode(); setScannerState(usingStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); if (lexicalUnit == LexicalUnit.ContextualKeyword && scanner.Keyword == Keyword.Var) { var restorePoint = this.createRestorePoint(); saveScannerState(); if (isIdentifier(nextLexicalUnit(true))) { usingStatement.ResourceAcquisition = parseLocalDeclarationStatement(null, false); } else { this.restore(restorePoint); } } if (usingStatement.ResourceAcquisition == null) { var restorePoint = this.createRestorePoint(); saveScannerState(); var type = parseType(false); if (type != null && isIdentifier(lexicalUnit)) { usingStatement.ResourceAcquisition = parseLocalDeclarationStatement(type, false); if (lexicalUnit != LexicalUnit.CloseParenthesis) { this.restore(restorePoint); usingStatement.ResourceAcquisition = null; } } else { this.restore(restorePoint); } } if (usingStatement.ResourceAcquisition == null) { var exp = new ExpressionStatementNode(); setScannerState(exp); exp.Expression = parseExpression(); usingStatement.ResourceAcquisition = exp; } if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); usingStatement.Statement = parseEmbeddedStatement(); usingStatement.EndPosition = usingStatement.Statement.EndPosition; return usingStatement; } case Return: { var returnStatement = new ReturnStatementNode(); setScannerState(returnStatement); if (nextLexicalUnit(true) != LexicalUnit.SemiColon) { returnStatement.Value = parseExpression(); } returnStatement.EndPosition = parseSemiColon(false, false); return returnStatement; } case Throw: { var throwStatement = new ThrowStatementNode(); setScannerState(throwStatement); if (nextLexicalUnit(true) != LexicalUnit.SemiColon) { throwStatement.Exception = parseExpression(); } throwStatement.EndPosition = parseSemiColon(false, false); return throwStatement; } case If: { var ifStatement = new IfStatementNode(); setScannerState(ifStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); ifStatement.Condition = parseExpression(); if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); ifStatement.IfTrue = parseEmbeddedStatement(); if (lexicalUnit == LexicalUnit.Keyword && scanner.Keyword == Keyword.Else) { nextLexicalUnit(true); ifStatement.IfFalse = parseEmbeddedStatement(); ifStatement.EndPosition = ifStatement.IfFalse.EndPosition; } else { ifStatement.EndPosition = ifStatement.IfTrue.EndPosition; } return ifStatement; } case While: { var whileStatement = new WhileStatementNode(); setScannerState(whileStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); whileStatement.Condition = parseExpression(); if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); whileStatement.Statement = parseEmbeddedStatement(); whileStatement.EndPosition = whileStatement.Statement.EndPosition; return whileStatement; } case Do: { var doStatement = new DoStatementNode(); setScannerState(doStatement); nextLexicalUnit(true); doStatement.Statement = parseEmbeddedStatement(); if (lexicalUnit != LexicalUnit.Keyword || scanner.Keyword != Keyword.While) { throw error(ParseErrorId.WhileExpected); } if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); doStatement.Condition = parseExpression(); if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } doStatement.EndPosition = parseSemiColon(true, false); return doStatement; } case Switch: { var switchStatement = new SwitchStatementNode(); setScannerState(switchStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); switchStatement.Selector = parseExpression(); if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } if (nextLexicalUnit(true) != LexicalUnit.OpenBrace) { throw error(ParseErrorId.OpenBraceExpected); } nextLexicalUnit(true); var done = false; int endPosition = 0; do { switch (lexicalUnit) { case Keyword: var filename = scanner.Filename; var line = scanner.StartLine; var column = scanner.StartColumn; var disabledWarnings = scanner.CodeErrorManager.DisabledWarnings; int startPosition = scanner.StartPosition; ExpressionNode expr = null; switch (scanner.Keyword) { case Case: nextLexicalUnit(true); expr = parseExpression(); break; case Default: nextLexicalUnit(true); break; default: throw error(ParseErrorId.CloseBraceExpected); } if (lexicalUnit != LexicalUnit.Colon) { throw error(ParseErrorId.ColonExpected); } var switchSection = new SwitchSectionNode { Filename = filename, Line = line, Column = column, DisabledWarnings = disabledWarnings, StartPosition = startPosition }; switchSection.CaseExpression = expr; switchStatement.Sections.add(switchSection); int end = scanner.EndPosition; nextLexicalUnit(true); var caseDone = false; do { switch (lexicalUnit) { case Keyword: switch (scanner.Keyword) { case Case: case Default: switchSection.EndPosition = end; caseDone = true; break; default: var statement = parseStatement(); switchSection.Statements.add(statement); endPosition = statement.EndPosition; switchSection.EndPosition = endPosition; break; } break; case CloseBrace: endPosition = scanner.EndPosition; switchSection.EndPosition = end; caseDone = true; break; default: var statement = parseStatement(); switchSection.Statements.add(statement); endPosition = statement.EndPosition; switchSection.EndPosition = endPosition; break; } } while (!caseDone); break; case CloseBrace: done = true; endPosition = scanner.EndPosition; nextLexicalUnit(false); break; default: throw error(ParseErrorId.CloseBraceExpected); } } while (!done); switchStatement.EndPosition = endPosition; return switchStatement; } case Foreach: { var foreachStatement = new ForeachStatementNode(); setScannerState(foreachStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); if (lexicalUnit == LexicalUnit.ContextualKeyword && scanner.Keyword == Keyword.Var) { var restorePoint = this.createRestorePoint(); if (isIdentifier(nextLexicalUnit(true))) { foreachStatement.NameOffset = scanner.StartPosition; foreachStatement.NameLength = getLexicalUnitLength(); } else { this.restore(restorePoint); } } if (foreachStatement.NameLength == 0) { var t = parseType(true); if (!isIdentifier(lexicalUnit)) { throw error(ParseErrorId.IdentifierExpected); } foreachStatement.Type = t; foreachStatement.NameOffset = scanner.StartPosition; foreachStatement.NameLength = getLexicalUnitLength(); } if (nextLexicalUnit(true) != LexicalUnit.Keyword && scanner.Keyword != Keyword.In) { throw error(ParseErrorId.InExpected); } nextLexicalUnit(true); foreachStatement.Source = parseExpression(); if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); foreachStatement.Statement = parseEmbeddedStatement(); foreachStatement.EndPosition = foreachStatement.Statement.EndPosition; return foreachStatement; } case For: { var forStatement = new ForStatementNode(); setScannerState(forStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } StatementNode statement = null; nextLexicalUnit(true); if (lexicalUnit == LexicalUnit.ContextualKeyword && scanner.Keyword == Keyword.Var) { var restorePoint = this.createRestorePoint(); saveScannerState(); if (isIdentifier(nextLexicalUnit(true))) { statement = parseLocalDeclarationStatement(null, false); } else { this.restore(restorePoint); } } if (statement == null && lexicalUnit != LexicalUnit.SemiColon) { statement = parseLocalDeclarationOrExpressionStatement(false); } if (statement != null) { forStatement.Initializer.add(statement); if (statement.StatementKind != StatementKind.LocalDeclaration) { while (lexicalUnit == LexicalUnit.Comma) { nextLexicalUnit(true); forStatement.Initializer.add(parseExpressionStatement(false)); } } } parseSemiColon(false, true); if (lexicalUnit != LexicalUnit.SemiColon) { forStatement.Condition = parseExpression(); } parseSemiColon(false, true); if (lexicalUnit != LexicalUnit.CloseParenthesis) { forStatement.Iterator.add(parseExpressionStatement(false)); while (lexicalUnit == LexicalUnit.Comma) { nextLexicalUnit(true); forStatement.Iterator.add(parseExpressionStatement(false)); } } if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); forStatement.Statement = parseEmbeddedStatement(); forStatement.EndPosition = forStatement.Statement.EndPosition; return forStatement; } case Synchronized: { var syncStatement = new SynchronizedStatementNode(); setScannerState(syncStatement); if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } nextLexicalUnit(true); syncStatement.Lock = parseExpression(); if (lexicalUnit != LexicalUnit.CloseParenthesis) { throw error(ParseErrorId.CloseParenthesisExpected); } nextLexicalUnit(true); syncStatement.Statement = parseEmbeddedStatement(); syncStatement.EndPosition = syncStatement.Statement.EndPosition; return syncStatement; } case Goto: { saveScannerState(); switch (nextLexicalUnit(true)) { case Keyword: switch (scanner.Keyword) { case Case: { var result = new GotoCaseStatementNode(); setSavedScannerState(result); nextLexicalUnit(true); result.Expression = parseExpression(); result.EndPosition = parseSemiColon(false, false); return result; } case Default: { var result = new GotoCaseStatementNode(); setSavedScannerState(result); result.EndPosition = parseSemiColon(true, false); return result; } default: throw error(ParseErrorId.IdentifierExpected); } case Identifier: case ContextualKeyword: var gotoStatement = new GotoStatementNode(); setSavedScannerState(gotoStatement); gotoStatement.LabelOffset = scanner.StartPosition; gotoStatement.LabelLength = getLexicalUnitLength(); gotoStatement.EndPosition = parseSemiColon(true, false); return gotoStatement; default: throw error(ParseErrorId.IdentifierExpected); } } case Continue: { var continueStatement = new ContinueStatementNode(); setScannerState(continueStatement); continueStatement.EndPosition = parseSemiColon(true, false); return continueStatement; } case Break: { var breakStatement = new BreakStatementNode(); setScannerState(breakStatement); breakStatement.EndPosition = parseSemiColon(true, false); return breakStatement; } case Var: { var restorePoint = this.createRestorePoint(); saveScannerState(); if (isIdentifier(nextLexicalUnit(true))) { return parseLocalDeclarationStatement(null, true); } else { this.restore(restorePoint); return parseLabeledOrLocalDeclarationOrExpressionStatement(); } } default: return parseLabeledOrLocalDeclarationOrExpressionStatement(); } default: return parseLabeledOrLocalDeclarationOrExpressionStatement(); } }
protected virtual TResult handleGoto(GotoStatementNode gotoStatement, TSource source) { return(defaultHandler()); }