Example #1
0
 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));
     }
 }
Example #2
0
 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));
     }
 }
Example #3
0
        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);
            }
        }
Example #4
0
        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);
            }
        }
Example #5
0
 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;
 }
Example #6
0
        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);
        }
Example #7
0
        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);
            }
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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;
        }