private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) { string labelText; LabelToken labelToken1 = labelToken; Token token = labelToken1; if (labelToken1 == null) { token = doToken; } IScriptExtent extent = token.Extent; IScriptExtent scriptExtent = null; Token token1 = null; Token token2 = null; PipelineBaseAst pipelineBaseAst = null; StatementBlockAst statementBlockAst = this.StatementBlockRule(); if (statementBlockAst != null) { this.SkipNewlines(); token2 = this.NextToken(); if (token2.Kind == TokenKind.While || token2.Kind == TokenKind.Until) { this.SkipNewlines(); Token token3 = this.NextToken(); if (token3.Kind == TokenKind.LParen) { this.SkipNewlines(); pipelineBaseAst = this.PipelineRule(); if (pipelineBaseAst == null) { scriptExtent = token3.Extent; object[] objArray = new object[1]; objArray[0] = token2.Kind.Text(); this.ReportIncompleteInput(Parser.After(scriptExtent), ParserStrings.MissingExpressionAfterKeyword, objArray); } this.SkipNewlines(); token1 = this.NextToken(); if (token1.Kind != TokenKind.RParen) { this.UngetToken(token1); if (pipelineBaseAst != null) { scriptExtent = pipelineBaseAst.Extent; object[] objArray1 = new object[1]; objArray1[0] = token2.Kind.Text(); this.ReportIncompleteInput(Parser.After(scriptExtent), ParserStrings.MissingEndParenthesisAfterStatement, objArray1); } } } else { this.UngetToken(token3); scriptExtent = token2.Extent; object[] objArray2 = new object[1]; objArray2[0] = token2.Kind.Text(); this.ReportIncompleteInput(Parser.After(scriptExtent), ParserStrings.MissingOpenParenthesisAfterKeyword, objArray2); } } else { this.UngetToken(token2); scriptExtent = statementBlockAst.Extent; this.ReportIncompleteInput(Parser.After(scriptExtent), ParserStrings.MissingWhileOrUntilInDoWhile, new object[0]); } } else { scriptExtent = doToken.Extent; object[] objArray3 = new object[1]; objArray3[0] = TokenKind.Do.Text(); this.ReportIncompleteInput(Parser.After(scriptExtent), ParserStrings.MissingLoopStatement, objArray3); } if (scriptExtent == null) { IScriptExtent scriptExtent1 = Parser.ExtentOf(extent, token1); if (labelToken != null) { labelText = labelToken.LabelText; } else { labelText = null; } string str = labelText; if (token2.Kind != TokenKind.Until) { return new DoWhileStatementAst(scriptExtent1, str, pipelineBaseAst, statementBlockAst); } else { return new DoUntilStatementAst(scriptExtent1, str, pipelineBaseAst, statementBlockAst); } } else { object[] objArray4 = new object[2]; objArray4[0] = statementBlockAst; objArray4[1] = pipelineBaseAst; return new ErrorStatementAst(Parser.ExtentOf(extent, scriptExtent), Parser.GetNestedErrorAsts(objArray4)); } }
private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToken) { IScriptExtent extent = null; Token token; string labelText; IEnumerable<Ast> nestedErrorAsts; LabelToken labelToken1 = labelToken; Token token1 = labelToken1; if (labelToken1 == null) { token1 = switchToken; } IScriptExtent scriptExtent = token1.Extent; bool flag = false; bool flag1 = false; this.SkipNewlines(); bool flag2 = false; PipelineBaseAst pipelineAst = null; Dictionary<string, Tuple<Token, Ast>> strs = null; Token token2 = this.PeekToken(); SwitchFlags switchFlag = SwitchFlags.None; while (token2.Kind == TokenKind.Parameter) { this.SkipToken(); extent = token2.Extent; Dictionary<string, Tuple<Token, Ast>> strs1 = strs; Dictionary<string, Tuple<Token, Ast>> strs2 = strs1; if (strs1 == null) { strs2 = new Dictionary<string, Tuple<Token, Ast>>(); } strs = strs2; if (!Parser.IsSpecificParameter(token2, "regex")) { if (!Parser.IsSpecificParameter(token2, "wildcard")) { if (!Parser.IsSpecificParameter(token2, "exact")) { if (!Parser.IsSpecificParameter(token2, "casesensitive")) { if (!Parser.IsSpecificParameter(token2, "parallel")) { if (!Parser.IsSpecificParameter(token2, "file")) { flag = true; object[] parameterName = new object[1]; parameterName[0] = ((ParameterToken)token2).ParameterName; this.ReportError(token2.Extent, ParserStrings.InvalidSwitchFlag, parameterName); } else { switchFlag = switchFlag | SwitchFlags.File; this.SkipNewlines(); ExpressionAst singleCommandArgument = this.GetSingleCommandArgument(Parser.CommandArgumentContext.FileName); if (singleCommandArgument != null) { extent = singleCommandArgument.Extent; pipelineAst = new PipelineAst(singleCommandArgument.Extent, new CommandExpressionAst(singleCommandArgument.Extent, singleCommandArgument, null)); if (!strs.ContainsKey("file")) { strs.Add("file", new Tuple<Token, Ast>(token2, pipelineAst)); } } else { flag = true; flag1 = this.ReportIncompleteInput(Parser.After(token2), ParserStrings.MissingFilenameOption, new object[0]); if (!strs.ContainsKey("file")) { strs.Add("file", new Tuple<Token, Ast>(token2, null)); } } } } else { switchFlag = switchFlag | SwitchFlags.Parallel; if (!strs.ContainsKey("parallel")) { strs.Add("parallel", new Tuple<Token, Ast>(token2, null)); } } } else { switchFlag = switchFlag | SwitchFlags.CaseSensitive; if (!strs.ContainsKey("casesensitive")) { strs.Add("casesensitive", new Tuple<Token, Ast>(token2, null)); } } } else { switchFlag = switchFlag & (SwitchFlags.File | SwitchFlags.Wildcard | SwitchFlags.Exact | SwitchFlags.CaseSensitive | SwitchFlags.Parallel); switchFlag = switchFlag & (SwitchFlags.File | SwitchFlags.Regex | SwitchFlags.Exact | SwitchFlags.CaseSensitive | SwitchFlags.Parallel); if (!strs.ContainsKey("exact")) { strs.Add("exact", new Tuple<Token, Ast>(token2, null)); } } } else { switchFlag = switchFlag | SwitchFlags.Wildcard; switchFlag = switchFlag & (SwitchFlags.File | SwitchFlags.Wildcard | SwitchFlags.Exact | SwitchFlags.CaseSensitive | SwitchFlags.Parallel); if (!strs.ContainsKey("wildcard")) { strs.Add("wildcard", new Tuple<Token, Ast>(token2, null)); } } } else { switchFlag = switchFlag | SwitchFlags.Regex; switchFlag = switchFlag & (SwitchFlags.File | SwitchFlags.Regex | SwitchFlags.Exact | SwitchFlags.CaseSensitive | SwitchFlags.Parallel); if (!strs.ContainsKey("regex")) { strs.Add("regex", new Tuple<Token, Ast>(token2, null)); } } token2 = this.PeekToken(); } if (token2.Kind == TokenKind.Minus) { Dictionary<string, Tuple<Token, Ast>> strs3 = strs; Dictionary<string, Tuple<Token, Ast>> strs4 = strs3; if (strs3 == null) { strs4 = new Dictionary<string, Tuple<Token, Ast>>(); } strs = strs4; strs.Add("--%", new Tuple<Token, Ast>(token2, null)); } Token token3 = this.PeekToken(); if (token3.Kind != TokenKind.LParen) { if (pipelineAst == null && (switchFlag & SwitchFlags.File) == SwitchFlags.None) { flag = true; flag1 = this.ReportIncompleteInput(Parser.After(extent), ParserStrings.PipelineValueRequired, new object[0]); } } else { extent = token3.Extent; this.SkipToken(); if ((switchFlag & SwitchFlags.File) == SwitchFlags.File) { flag = true; this.ReportError(token3.Extent, ParserStrings.PipelineValueRequired, new object[0]); } flag2 = true; this.SkipNewlines(); pipelineAst = this.PipelineRule(); if (pipelineAst != null) { extent = pipelineAst.Extent; } else { flag = true; flag1 = this.ReportIncompleteInput(Parser.After(token3), ParserStrings.PipelineValueRequired, new object[0]); } this.SkipNewlines(); Token token4 = this.NextToken(); if (token4.Kind == TokenKind.RParen) { extent = token4.Extent; } else { this.UngetToken(token4); if (!flag1) { flag = true; flag1 = this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingEndParenthesisInSwitchStatement, new object[0]); } } } this.SkipNewlines(); Token token5 = this.NextToken(); StatementBlockAst statementBlockAst = null; List<Tuple<ExpressionAst, StatementBlockAst>> tuples = new List<Tuple<ExpressionAst, StatementBlockAst>>(); List<Ast> asts = new List<Ast>(); Token token6 = null; if (token5.Kind == TokenKind.LCurly) { extent = token5.Extent; this.SkipNewlines(); do { ExpressionAst expressionAst = this.GetSingleCommandArgument(Parser.CommandArgumentContext.SwitchCondition); if (expressionAst != null) { asts.Add(expressionAst); extent = expressionAst.Extent; StatementBlockAst statementBlockAst1 = this.StatementBlockRule(); if (statementBlockAst1 != null) { asts.Add(statementBlockAst1); extent = statementBlockAst1.Extent; StringConstantExpressionAst stringConstantExpressionAst = expressionAst as StringConstantExpressionAst; if (stringConstantExpressionAst == null || stringConstantExpressionAst.StringConstantType != StringConstantType.BareWord || !stringConstantExpressionAst.Value.Equals("default", StringComparison.OrdinalIgnoreCase)) { tuples.Add(new Tuple<ExpressionAst, StatementBlockAst>(expressionAst, statementBlockAst1)); } else { if (statementBlockAst != null) { flag = true; this.ReportError(expressionAst.Extent, ParserStrings.MultipleSwitchDefaultClauses, new object[0]); } statementBlockAst = statementBlockAst1; } } else { flag = true; flag1 = this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingSwitchStatementClause, new object[0]); } this.SkipNewlinesAndSemicolons(); token = this.PeekToken(); if (token.Kind != TokenKind.RCurly) { continue; } token6 = token; this.SkipToken(); goto Label0; } else { flag = true; this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingSwitchConditionExpression, new object[0]); if (this.PeekToken().Kind != TokenKind.RCurly) { goto Label0; } this.SkipToken(); goto Label0; } } while (token.Kind != TokenKind.EndOfInput); if (!flag1) { flag = true; this.ReportIncompleteInput(token5.Extent, token.Extent, ParserStrings.MissingEndCurlyBrace, new object[0]); } } else { this.UngetToken(token5); if (!flag1) { flag = true; this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingCurlyBraceInSwitchStatement, new object[0]); } } Label0: if (!flag) { LabelToken labelToken2 = labelToken; Token token7 = labelToken2; if (labelToken2 == null) { token7 = switchToken; } IScriptExtent scriptExtent1 = Parser.ExtentOf(token7, token6); if (labelToken != null) { labelText = labelToken.LabelText; } else { labelText = null; } return new SwitchStatementAst(scriptExtent1, labelText, pipelineAst, switchFlag, tuples, statementBlockAst); } else { IScriptExtent scriptExtent2 = Parser.ExtentOf(scriptExtent, extent); Token token8 = switchToken; Dictionary<string, Tuple<Token, Ast>> strs5 = strs; if (flag2) { object[] objArray = new object[1]; objArray[0] = pipelineAst; nestedErrorAsts = Parser.GetNestedErrorAsts(objArray); } else { nestedErrorAsts = null; } object[] objArray1 = new object[1]; objArray1[0] = asts; return new ErrorStatementAst(scriptExtent2, token8, strs5, nestedErrorAsts, Parser.GetNestedErrorAsts(objArray1)); } }
private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) { string labelText; this.SkipNewlines(); Token token = this.NextToken(); if (token.Kind == TokenKind.LParen) { this.SkipNewlines(); PipelineBaseAst errorStatementAst = this.PipelineRule(); PipelineBaseAst pipelineBaseAst = null; if (errorStatementAst != null) { pipelineBaseAst = errorStatementAst; } else { IScriptExtent scriptExtent = Parser.After(token); object[] objArray = new object[1]; objArray[0] = whileToken.Kind.Text(); this.ReportIncompleteInput(scriptExtent, ParserStrings.MissingExpressionAfterKeyword, objArray); errorStatementAst = new ErrorStatementAst(scriptExtent, (IEnumerable<Ast>)null); } this.SkipNewlines(); Token token1 = this.NextToken(); if (token1.Kind == TokenKind.RParen) { this.SkipNewlines(); StatementBlockAst statementBlockAst = this.StatementBlockRule(); if (statementBlockAst != null) { LabelToken labelToken1 = labelToken; Token token2 = labelToken1; if (labelToken1 == null) { token2 = whileToken; } IScriptExtent scriptExtent1 = Parser.ExtentOf(token2, statementBlockAst); if (labelToken != null) { labelText = labelToken.LabelText; } else { labelText = null; } return new WhileStatementAst(scriptExtent1, labelText, errorStatementAst, statementBlockAst); } else { object[] objArray1 = new object[1]; objArray1[0] = whileToken.Kind.Text(); this.ReportIncompleteInput(Parser.After(token1), ParserStrings.MissingLoopStatement, objArray1); LabelToken labelToken2 = labelToken; Token token3 = labelToken2; if (labelToken2 == null) { token3 = whileToken; } object[] objArray2 = new object[1]; objArray2[0] = pipelineBaseAst; return new ErrorStatementAst(Parser.ExtentOf(token3, token1), Parser.GetNestedErrorAsts(objArray2)); } } else { this.UngetToken(token1); if (errorStatementAst as ErrorStatementAst == null) { object[] objArray3 = new object[1]; objArray3[0] = whileToken.Kind.Text(); this.ReportIncompleteInput(Parser.After(errorStatementAst), ParserStrings.MissingEndParenthesisAfterStatement, objArray3); } LabelToken labelToken3 = labelToken; Token token4 = labelToken3; if (labelToken3 == null) { token4 = whileToken; } object[] objArray4 = new object[1]; objArray4[0] = pipelineBaseAst; return new ErrorStatementAst(Parser.ExtentOf(token4, errorStatementAst), Parser.GetNestedErrorAsts(objArray4)); } } else { this.UngetToken(token); object[] text = new object[1]; text[0] = whileToken.Text; this.ReportIncompleteInput(Parser.After(whileToken), ParserStrings.MissingOpenParenthesisAfterKeyword, text); LabelToken labelToken4 = labelToken; Token token5 = labelToken4; if (labelToken4 == null) { token5 = whileToken; } return new ErrorStatementAst(Parser.ExtentOf(token5, whileToken), (IEnumerable<Ast>)null); } }
private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) { string labelText; IScriptExtent extent = null; this.SkipNewlines(); Token token = this.NextToken(); if (token.Kind == TokenKind.LParen) { this.SkipNewlines(); PipelineBaseAst pipelineBaseAst = this.PipelineRule(); if (pipelineBaseAst != null) { extent = pipelineBaseAst.Extent; } if (this.PeekToken().Kind == TokenKind.Semi) { extent = this.NextToken().Extent; } this.SkipNewlines(); PipelineBaseAst pipelineBaseAst1 = this.PipelineRule(); if (pipelineBaseAst1 != null) { extent = pipelineBaseAst1.Extent; } if (this.PeekToken().Kind == TokenKind.Semi) { extent = this.NextToken().Extent; } this.SkipNewlines(); PipelineBaseAst pipelineBaseAst2 = this.PipelineRule(); if (pipelineBaseAst2 != null) { extent = pipelineBaseAst2.Extent; } this.SkipNewlines(); Token token1 = this.NextToken(); StatementBlockAst statementBlockAst = null; if (token1.Kind == TokenKind.RParen) { statementBlockAst = this.StatementBlockRule(); if (statementBlockAst == null) { extent = token1.Extent; object[] objArray = new object[1]; objArray[0] = forToken.Kind.Text(); this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingLoopStatement, objArray); } } else { this.UngetToken(token1); if (extent == null) { extent = token.Extent; } object[] objArray1 = new object[1]; objArray1[0] = forToken.Kind.Text(); this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingEndParenthesisAfterStatement, objArray1); } if (statementBlockAst != null) { LabelToken labelToken1 = labelToken; Token token2 = labelToken1; if (labelToken1 == null) { token2 = forToken; } IScriptExtent scriptExtent = Parser.ExtentOf(token2, statementBlockAst); if (labelToken != null) { labelText = labelToken.LabelText; } else { labelText = null; } return new ForStatementAst(scriptExtent, labelText, pipelineBaseAst, pipelineBaseAst1, pipelineBaseAst2, statementBlockAst); } else { LabelToken labelToken2 = labelToken; Token token3 = labelToken2; if (labelToken2 == null) { token3 = forToken; } object[] objArray2 = new object[3]; objArray2[0] = pipelineBaseAst; objArray2[1] = pipelineBaseAst1; objArray2[2] = pipelineBaseAst2; return new ErrorStatementAst(Parser.ExtentOf(token3, extent), Parser.GetNestedErrorAsts(objArray2)); } } else { this.UngetToken(token); extent = forToken.Extent; object[] objArray3 = new object[1]; objArray3[0] = forToken.Kind.Text(); this.ReportIncompleteInput(Parser.After(extent), ParserStrings.MissingOpenParenthesisAfterKeyword, objArray3); LabelToken labelToken3 = labelToken; Token token4 = labelToken3; if (labelToken3 == null) { token4 = forToken; } return new ErrorStatementAst(Parser.ExtentOf(token4, extent), (IEnumerable<Ast>)null); } }
private StatementAst LabeledStatementRule(LabelToken label) { StatementAst statementAst; Token token = this.NextToken(); TokenKind kind = token.Kind; if (kind > TokenKind.Foreach) { if (kind == TokenKind.Switch) { statementAst = this.SwitchStatementRule(label, token); } else { if (kind != TokenKind.While) { this.Resync(label); statementAst = this.PipelineRule(); return statementAst; } statementAst = this.WhileStatementRule(label, token); } } else { if (kind == TokenKind.Do) { statementAst = this.DoWhileStatementRule(label, token); } else { if (kind == TokenKind.For) { statementAst = this.ForStatementRule(label, token); return statementAst; } else if (kind == TokenKind.Foreach) { statementAst = this.ForeachStatementRule(label, token); return statementAst; } this.Resync(label); statementAst = this.PipelineRule(); return statementAst; } } return statementAst; }
private StatementAst DoWhileStatementRule(LabelToken labelToken, Token doToken) { //G do-statement: //G 'do' statement-block new-lines:opt 'while' new-lines:opt '(' while-condition new-lines:opt ')' //G 'do' statement-block new-lines:opt 'until' new-lines:opt '(' while-condition new-lines:opt ')' //G //G while-condition: //G new-lines:opt pipeline IScriptExtent startExtent = (labelToken ?? doToken).Extent; IScriptExtent endErrorStatement = null; Token rParen = null; Token whileOrUntilToken = null; PipelineBaseAst condition = null; StatementBlockAst body = StatementBlockRule(); if (body == null) { // ErrorRecovery: Skip the keyword and stop trying to parse this statement, continue on whatever // comes next. endErrorStatement = doToken.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingLoopStatement, TokenKind.Do.Text()); } else { SkipNewlines(); whileOrUntilToken = NextToken(); if (whileOrUntilToken.Kind != TokenKind.While && whileOrUntilToken.Kind != TokenKind.Until) { // ErrorRecovery: Skip looking for a condition, continue on whatever comes next. UngetToken(whileOrUntilToken); endErrorStatement = body.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingWhileOrUntilInDoWhile); } else { SkipNewlines(); Token lParen = NextToken(); if (lParen.Kind != TokenKind.LParen) { // ErrorRecovery: Skip looking for the condition, return an error statement. UngetToken(lParen); endErrorStatement = whileOrUntilToken.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingOpenParenthesisAfterKeyword, whileOrUntilToken.Kind.Text()); } else { SkipNewlines(); condition = PipelineRule(); if (condition == null) { // ErrorRecovery: try to get the matching close paren, then return an error statement. endErrorStatement = lParen.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingExpressionAfterKeyword, whileOrUntilToken.Kind.Text()); } SkipNewlines(); rParen = NextToken(); if (rParen.Kind != TokenKind.RParen) { // ErrorRecovery: this is it, so just pretend we saw the paren, return an error statement. UngetToken(rParen); // If condition == null, we issue an error message already, don't bother with this one. if (condition != null) { endErrorStatement = condition.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingEndParenthesisAfterStatement, whileOrUntilToken.Kind.Text()); } } } } } if (endErrorStatement != null) { return new ErrorStatementAst(ExtentOf(startExtent, endErrorStatement), GetNestedErrorAsts(body, condition)); } IScriptExtent extent = ExtentOf(startExtent, rParen); string label = (labelToken != null) ? labelToken.LabelText : null; if (whileOrUntilToken.Kind == TokenKind.Until) { return new DoUntilStatementAst(extent, label, condition, body); } return new DoWhileStatementAst(extent, label, condition, body); }
private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachToken) { IScriptExtent extent; string labelText; if (labelToken != null) { extent = labelToken.Extent; } else { extent = forEachToken.Extent; } IScriptExtent scriptExtent = extent; IScriptExtent extent1 = null; this.SkipNewlines(); Token token = this.PeekToken(); ForEachFlags forEachFlag = ForEachFlags.None; while (token.Kind == TokenKind.Parameter) { this.SkipToken(); if (!Parser.IsSpecificParameter(token, "parallel")) { extent1 = token.Extent; object[] parameterName = new object[1]; parameterName[0] = ((ParameterToken)token).ParameterName; this.ReportError(token.Extent, ParserStrings.InvalidForeachFlag, parameterName); } else { forEachFlag = forEachFlag | ForEachFlags.Parallel; } this.SkipNewlines(); token = this.PeekToken(); } Token token1 = this.NextToken(); if (token1.Kind == TokenKind.LParen) { this.SkipNewlines(); Token token2 = this.NextToken(); if (token2.Kind == TokenKind.Variable || token2.Kind == TokenKind.SplattedVariable) { VariableExpressionAst variableExpressionAst = new VariableExpressionAst((VariableToken)token2); this.SkipNewlines(); PipelineBaseAst pipelineBaseAst = null; StatementBlockAst statementBlockAst = null; Token token3 = this.NextToken(); if (token3.Kind == TokenKind.In) { this.SkipNewlines(); pipelineBaseAst = this.PipelineRule(); if (pipelineBaseAst != null) { this.SkipNewlines(); Token token4 = this.NextToken(); if (token4.Kind == TokenKind.RParen) { statementBlockAst = this.StatementBlockRule(); if (statementBlockAst == null) { extent1 = token4.Extent; this.ReportIncompleteInput(Parser.After(extent1), ParserStrings.MissingForeachStatement, new object[0]); } } else { this.UngetToken(token4); extent1 = pipelineBaseAst.Extent; this.ReportIncompleteInput(Parser.After(extent1), ParserStrings.MissingEndParenthesisAfterForeach, new object[0]); } } else { extent1 = token3.Extent; this.ReportIncompleteInput(Parser.After(extent1), ParserStrings.MissingForeachExpression, new object[0]); } } else { this.UngetToken(token3); extent1 = variableExpressionAst.Extent; this.ReportIncompleteInput(Parser.After(extent1), ParserStrings.MissingInInForeach, new object[0]); } if (extent1 == null) { IScriptExtent scriptExtent1 = Parser.ExtentOf(scriptExtent, statementBlockAst); if (labelToken != null) { labelText = labelToken.LabelText; } else { labelText = null; } return new ForEachStatementAst(scriptExtent1, labelText, forEachFlag, variableExpressionAst, pipelineBaseAst, statementBlockAst); } else { object[] objArray = new object[3]; objArray[0] = variableExpressionAst; objArray[1] = pipelineBaseAst; objArray[2] = statementBlockAst; return new ErrorStatementAst(Parser.ExtentOf(scriptExtent, extent1), Parser.GetNestedErrorAsts(objArray)); } } else { this.UngetToken(token2); extent1 = token1.Extent; this.ReportIncompleteInput(Parser.After(extent1), ParserStrings.MissingVariableNameAfterForeach, new object[0]); return new ErrorStatementAst(Parser.ExtentOf(scriptExtent, extent1), (IEnumerable<Ast>)null); } } else { this.UngetToken(token1); extent1 = forEachToken.Extent; object[] objArray1 = new object[1]; objArray1[0] = forEachToken.Kind.Text(); this.ReportIncompleteInput(Parser.After(extent1), ParserStrings.MissingOpenParenthesisAfterKeyword, objArray1); return new ErrorStatementAst(Parser.ExtentOf(scriptExtent, extent1), (IEnumerable<Ast>)null); } }
private StatementAst WhileStatementRule(LabelToken labelToken, Token whileToken) { //G while-statement: //G 'while ' new-lines:opt '(' new-lines:opt while-condition new-lines:opt ')' statement-block SkipNewlines(); Token lParen = NextToken(); if (lParen.Kind != TokenKind.LParen) { // ErrorRecovery: assume user just typed 'while' and hadn't started typing anything // else yet. Next token is likely a newline, so just put it back and keep parsing. UngetToken(lParen); ReportIncompleteInput(After(whileToken), () => ParserStrings.MissingOpenParenthesisAfterKeyword, whileToken.Text); return new ErrorStatementAst(ExtentOf(labelToken ?? whileToken, whileToken)); } SkipNewlines(); PipelineBaseAst condition = PipelineRule(); PipelineBaseAst errorCondition = null; if (condition == null) { // ErrorRecovery: assume pipeline just hasn't been entered yet, continue hoping // to find a close paren and statement block. IScriptExtent errorPosition = After(lParen); ReportIncompleteInput(errorPosition, () => ParserStrings.MissingExpressionAfterKeyword, whileToken.Kind.Text()); condition = new ErrorStatementAst(errorPosition); } else { errorCondition = condition; } SkipNewlines(); Token rParen = NextToken(); if (rParen.Kind != TokenKind.RParen) { // ErrorRecovery: assume the next token is a newline or part of something else, // so stop parsing the statement and try parsing something else if possible. UngetToken(rParen); if (!(condition is ErrorStatementAst)) { ReportIncompleteInput(After(condition), () => ParserStrings.MissingEndParenthesisAfterStatement, whileToken.Kind.Text()); } return new ErrorStatementAst(ExtentOf(labelToken ?? whileToken, condition), GetNestedErrorAsts(errorCondition)); } SkipNewlines(); StatementBlockAst body = StatementBlockRule(); if (body == null) { // ErrorRecovery: assume the next token is a newline or part of something else. ReportIncompleteInput(After(rParen), () => ParserStrings.MissingLoopStatement, whileToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(labelToken ?? whileToken, rParen), GetNestedErrorAsts(errorCondition)); } return new WhileStatementAst(ExtentOf(labelToken ?? whileToken, body), labelToken != null ? labelToken.LabelText : null, condition, body); }
private StatementAst ForStatementRule(LabelToken labelToken, Token forToken) { //G for-statement: //G 'for' new-lines:opt '(' //G new-lines:opt for-initializer:opt statement-terminator //G new-lines:opt for-condition:opt statement-terminator //G new-lines:opt for-iterator:opt //G new-lines:opt ')' statement-block //G 'for' new-lines:opt '(' //G new-lines:opt for-initializer:opt statement-terminator //G new-lines:opt for-condition:opt //G new-lines:opt ')' statement-block //G 'for' new-lines:opt '(' //G new-lines:opt for-initializer:opt //G new-lines:opt ')' statement-block //G for-initializer: //G pipeline //G for-condition: //G pipeline //G for-iterator: //G pipeline IScriptExtent endErrorStatement = null; SkipNewlines(); Token lParen = NextToken(); if (lParen.Kind != TokenKind.LParen) { // ErrorRecovery: don't continue parsing the for statement. UngetToken(lParen); endErrorStatement = forToken.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingOpenParenthesisAfterKeyword, forToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(labelToken ?? forToken, endErrorStatement)); } SkipNewlines(); PipelineBaseAst initializer = PipelineRule(); if (initializer != null) { endErrorStatement = initializer.Extent; } if (PeekToken().Kind == TokenKind.Semi) { endErrorStatement = NextToken().Extent; } SkipNewlines(); PipelineBaseAst condition = PipelineRule(); if (condition != null) { endErrorStatement = condition.Extent; } if (PeekToken().Kind == TokenKind.Semi) { endErrorStatement = NextToken().Extent; } SkipNewlines(); PipelineBaseAst iterator = PipelineRule(); if (iterator != null) { endErrorStatement = iterator.Extent; } SkipNewlines(); Token rParen = NextToken(); StatementBlockAst body = null; if (rParen.Kind != TokenKind.RParen) { // ErrorRecovery: don't continue parsing the for statement. UngetToken(rParen); if (endErrorStatement == null) { endErrorStatement = lParen.Extent; } ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingEndParenthesisAfterStatement, forToken.Kind.Text()); } else { body = StatementBlockRule(); if (body == null) { // ErrorRecovery: return an error statement. endErrorStatement = rParen.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingLoopStatement, forToken.Kind.Text()); } } if (body == null) { return new ErrorStatementAst(ExtentOf(labelToken ?? forToken, endErrorStatement), GetNestedErrorAsts(initializer, condition, iterator)); } return new ForStatementAst(ExtentOf(labelToken ?? forToken, body), labelToken != null ? labelToken.LabelText : null, initializer, condition, iterator, body); }
private StatementAst ForeachStatementRule(LabelToken labelToken, Token forEachToken) { //G foreach-statement: //G 'foreach' new-lines:opt foreach-parameters:opt new-lines:opt '(' //G new-lines:opt variable new-lines:opt 'in' new-lines:opt pipeline //G new-lines:opt ')' statement-block //G foreach-parameters: //G foreach-parameter //G foreach-parameters foreach-parameter //G foreach-parameter: //G '-parallel' //G '-throttlelimit' new-lines:opt foreach-throttlelimit //G foreach-throttlelimit: //G command-argument //G primary-expression IScriptExtent startOfStatement = labelToken != null ? labelToken.Extent : forEachToken.Extent; IScriptExtent endErrorStatement = null; SkipNewlines(); // Process parameters on foreach Token foreachParameterToken = PeekToken(); ForEachFlags flags = ForEachFlags.None; ExpressionAst throttleLimit = null; while (foreachParameterToken.Kind == TokenKind.Parameter) { SkipToken(); if (IsSpecificParameter(foreachParameterToken, "parallel")) { flags |= ForEachFlags.Parallel; } else if (IsSpecificParameter(foreachParameterToken, "throttlelimit")) { SkipNewlines(); throttleLimit = GetSingleCommandArgument(CommandArgumentContext.CommandArgument); if (throttleLimit == null) { // ErrorRecovery: pretend we saw the throttle limit and continue. ReportIncompleteInput(After(foreachParameterToken), () => ParserStrings.MissingThrottleLimit); } } else { // ErrorRecovery: just ignore the token, continue parsing. endErrorStatement = foreachParameterToken.Extent; ReportError(foreachParameterToken.Extent, () => ParserStrings.InvalidForeachFlag, ((ParameterToken)foreachParameterToken).ParameterName); } SkipNewlines(); foreachParameterToken = PeekToken(); } Token lParen = NextToken(); if (lParen.Kind != TokenKind.LParen) { // ErrorRecovery: assume the rest of the statement is missing. UngetToken(lParen); endErrorStatement = forEachToken.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingOpenParenthesisAfterKeyword, forEachToken.Kind.Text()); return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement)); } SkipNewlines(); Token token = NextToken(); if (token.Kind != TokenKind.Variable && token.Kind != TokenKind.SplattedVariable) { // ErrorRecovery: assume the rest of the statement is missing. UngetToken(token); endErrorStatement = lParen.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingVariableNameAfterForeach); return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement)); } var variableAst = new VariableExpressionAst((VariableToken)token); SkipNewlines(); PipelineBaseAst pipeline = null; StatementBlockAst body = null; Token inToken = NextToken(); if (inToken.Kind != TokenKind.In) { // ErrorRecovery: assume the rest of the statement is missing. UngetToken(inToken); endErrorStatement = variableAst.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingInInForeach); } else { SkipNewlines(); pipeline = PipelineRule(); if (pipeline == null) { // ErrorRecovery: assume the rest of the statement is missing. endErrorStatement = inToken.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingForeachExpression); } else { SkipNewlines(); Token rParen = NextToken(); if (rParen.Kind != TokenKind.RParen) { // ErrorRecovery: assume the rest of the statement is missing. UngetToken(rParen); endErrorStatement = pipeline.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingEndParenthesisAfterForeach); } else { body = StatementBlockRule(); if (body == null) { // ErrorRecovery: nothing more to look for, so just return the error statement. endErrorStatement = rParen.Extent; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingForeachStatement); } } } } if (endErrorStatement != null) { return new ErrorStatementAst(ExtentOf(startOfStatement, endErrorStatement), GetNestedErrorAsts(variableAst, pipeline, body)); } return new ForEachStatementAst(ExtentOf(startOfStatement, body), labelToken != null ? labelToken.LabelText : null, flags, throttleLimit, variableAst, pipeline, body); }
private StatementAst SwitchStatementRule(LabelToken labelToken, Token switchToken) { //G switch-statement: //G 'switch' new-lines:opt switch-parameters:opt switch-condition switch-body //G switch-parameters: //G switch-parameter //G switch-parameters switch-parameter //G switch-parameter: //G '-regex' //G '-wildcard' //G '-exact' //G '-casesensitive' //G '-parallel' //G switch-condition: //G '(' new-lines:opt pipeline new-lines:opt ')' //G -file new-lines:opt switch-filename //G switch-filename: //G command-argument //G primary-expression //G switch-body: //G new-lines:opt '{' new-lines:opt switch-clauses '}' //G switch-clauses: //G switch-clause //G switch-clauses switch-clause //G switch-clause: //G switch-clause-condition statement-block statement-terminators:opt //G switch-clause-condition: //G command-argument //G primary-expression IScriptExtent startExtent = (labelToken ?? switchToken).Extent; IScriptExtent endErrorStatement = startExtent; bool isError = false; bool isIncompleteError = false; SkipNewlines(); bool needErrorCondition = false; // Only used to track if we need to include (condition) ast for the error statement. PipelineBaseAst condition = null; Dictionary<string, Tuple<Token, Ast>> specifiedFlags = null; // Only used to track all flags specified for the error ast Token switchParameterToken = PeekToken(); SwitchFlags flags = SwitchFlags.None; while (switchParameterToken.Kind == TokenKind.Parameter) { SkipToken(); endErrorStatement = switchParameterToken.Extent; specifiedFlags = specifiedFlags ?? new Dictionary<string, Tuple<Token, Ast>>(); if (IsSpecificParameter(switchParameterToken, "regex")) { flags |= SwitchFlags.Regex; flags &= ~SwitchFlags.Wildcard; if (!specifiedFlags.ContainsKey("regex")) { specifiedFlags.Add("regex", new Tuple<Token, Ast>(switchParameterToken, null)); } } else if (IsSpecificParameter(switchParameterToken, "wildcard")) { flags |= SwitchFlags.Wildcard; flags &= ~SwitchFlags.Regex; if (!specifiedFlags.ContainsKey("wildcard")) { specifiedFlags.Add("wildcard", new Tuple<Token, Ast>(switchParameterToken, null)); } } else if (IsSpecificParameter(switchParameterToken, "exact")) { flags &= ~SwitchFlags.Regex; flags &= ~SwitchFlags.Wildcard; if (!specifiedFlags.ContainsKey("exact")) { specifiedFlags.Add("exact", new Tuple<Token, Ast>(switchParameterToken, null)); } } else if (IsSpecificParameter(switchParameterToken, "casesensitive")) { flags |= SwitchFlags.CaseSensitive; if (!specifiedFlags.ContainsKey("casesensitive")) { specifiedFlags.Add("casesensitive", new Tuple<Token, Ast>(switchParameterToken, null)); } } else if (IsSpecificParameter(switchParameterToken, "parallel")) { flags |= SwitchFlags.Parallel; if (!specifiedFlags.ContainsKey("parallel")) { specifiedFlags.Add("parallel", new Tuple<Token, Ast>(switchParameterToken, null)); } } else if (IsSpecificParameter(switchParameterToken, "file")) { flags |= SwitchFlags.File; SkipNewlines(); ExpressionAst fileNameExpr = GetSingleCommandArgument(CommandArgumentContext.FileName); if (fileNameExpr == null) { // ErrorRecovery: pretend we saw the filename and continue. isError = true; isIncompleteError = ReportIncompleteInput(After(switchParameterToken), () => ParserStrings.MissingFilenameOption); if (!specifiedFlags.ContainsKey("file")) { specifiedFlags.Add("file", new Tuple<Token, Ast>(switchParameterToken, null)); } } else { endErrorStatement = fileNameExpr.Extent; condition = new PipelineAst(fileNameExpr.Extent, new CommandExpressionAst(fileNameExpr.Extent, fileNameExpr, null)); if (!specifiedFlags.ContainsKey("file")) { specifiedFlags.Add("file", new Tuple<Token, Ast>(switchParameterToken, condition)); } } } else { // ErrorRecovery: just ignore the token, continue parsing. isError = true; ReportError(switchParameterToken.Extent, () => ParserStrings.InvalidSwitchFlag, ((ParameterToken)switchParameterToken).ParameterName); } switchParameterToken = PeekToken(); } if (switchParameterToken.Kind == TokenKind.Minus) { specifiedFlags = specifiedFlags ?? new Dictionary<string, Tuple<Token, Ast>>(); specifiedFlags.Add(VERBATIM_ARGUMENT, new Tuple<Token, Ast>(switchParameterToken, null)); } Token lParen = PeekToken(); if (lParen.Kind == TokenKind.LParen) { endErrorStatement = lParen.Extent; SkipToken(); if ((flags & SwitchFlags.File) == SwitchFlags.File) { // ErrorRecovery: nothing special this is a semantic error. isError = true; ReportError(lParen.Extent, () => ParserStrings.PipelineValueRequired); } needErrorCondition = true; // need to add condition ast to the error statement if the parsing fails SkipNewlines(); condition = PipelineRule(); if (condition == null) { // ErrorRecovery: pretend we saw the condition and keep parsing. isError = true; isIncompleteError = ReportIncompleteInput(After(lParen), () => ParserStrings.PipelineValueRequired); } else { endErrorStatement = condition.Extent; } SkipNewlines(); Token rParen = NextToken(); if (rParen.Kind != TokenKind.RParen) { // ErrorRecovery: Try to parse the switch body, if we don't find a body, then bail. UngetToken(rParen); if (!isIncompleteError) { isError = true; isIncompleteError = ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingEndParenthesisInSwitchStatement); } } else { endErrorStatement = rParen.Extent; } } else if (condition == null) { if ((flags & SwitchFlags.File) == 0) { isError = true; isIncompleteError = ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.PipelineValueRequired); } else { Diagnostics.Assert(isError, "An error should already have been issued"); } } SkipNewlines(); Token lCurly = NextToken(); StatementBlockAst @default = null; List<SwitchClause> clauses = new List<SwitchClause>(); List<Ast> errorAsts = new List<Ast>(); // in case there is an error, we want the asts parsed up to the error. Token rCurly = null; if (lCurly.Kind != TokenKind.LCurly) { // ErrorRecovery: Assume we don't have any switch body to parse. UngetToken(lCurly); if (!isIncompleteError) { isError = true; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingCurlyBraceInSwitchStatement); } } else { endErrorStatement = lCurly.Extent; SkipNewlines(); while (true) { ExpressionAst clauseCondition = GetSingleCommandArgument(CommandArgumentContext.SwitchCondition); if (clauseCondition == null) { // ErrorRecovery: if we don't have anything that looks like a condition, we won't // find a body (because a body is just a script block, which works as a condition.) // So don't look for a body, hope we find the '}' next. isError = true; ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingSwitchConditionExpression); // Consume a closing curly, if there is one, to avoid an extra error if (PeekToken().Kind == TokenKind.RCurly) { SkipToken(); } break; } errorAsts.Add(clauseCondition); endErrorStatement = clauseCondition.Extent; StatementBlockAst clauseBody = StatementBlockRule(); if (clauseBody == null) { // ErrorRecovery: We might find another condition/body pair, so keep going. isError = true; isIncompleteError = ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingSwitchStatementClause); } else { errorAsts.Add(clauseBody); endErrorStatement = clauseBody.Extent; var clauseConditionString = clauseCondition as StringConstantExpressionAst; if (clauseConditionString != null && clauseConditionString.StringConstantType == StringConstantType.BareWord && clauseConditionString.Value.Equals("default", StringComparison.OrdinalIgnoreCase)) { if (@default != null) { // ErrorRecovery: just report the error and continue, forget the previous default clause. isError = true; ReportError(clauseCondition.Extent, () => ParserStrings.MultipleSwitchDefaultClauses); } @default = clauseBody; } else { clauses.Add(new SwitchClause(clauseCondition, clauseBody)); } } SkipNewlinesAndSemicolons(); Token token = PeekToken(); if (token.Kind == TokenKind.RCurly) { rCurly = token; SkipToken(); break; } if (token.Kind == TokenKind.EndOfInput) { if (!isIncompleteError) { isError = true; ReportIncompleteInput(lCurly.Extent, token.Extent, () => ParserStrings.MissingEndCurlyBrace); } break; } } } if (isError) { return new ErrorStatementAst(ExtentOf(startExtent, endErrorStatement), switchToken, specifiedFlags, needErrorCondition ? GetNestedErrorAsts(condition) : null, GetNestedErrorAsts(errorAsts)); } return new SwitchStatementAst(ExtentOf(labelToken ?? switchToken, rCurly), labelToken != null ? labelToken.LabelText : null, condition, flags, clauses, @default); }
private StatementAst LabeledStatementRule(LabelToken label) { //G statement: //G label:opt labeled-statement //G //G labeled-statement: //G switch-statement //G foreach-statement //G for-statement //G while-statement //G do-statement StatementAst statement; Token token = NextToken(); switch (token.Kind) { case TokenKind.Switch: statement = SwitchStatementRule(label, token); break; case TokenKind.Foreach: statement = ForeachStatementRule(label, token); break; case TokenKind.For: statement = ForStatementRule(label, token); break; case TokenKind.While: statement = WhileStatementRule(label, token); break; case TokenKind.Do: statement = DoWhileStatementRule(label, token); break; default: // We can only unget 1 token, but have 2 to unget, so resync on the label. Resync(label); statement = PipelineRule(); break; } return statement; }