diff --git a/Parser/MParser.cs b/Parser/MParser.cs index 27a63b6..205d4a5 100644 --- a/Parser/MParser.cs +++ b/Parser/MParser.cs @@ -676,15 +676,34 @@ namespace Parser return lhs; } - private SwitchCaseNode ParseSwitchCase() + private List ParseOptionalCommas() { - var caseKeyword = EatIdentifier("case"); - var caseId = ParseExpression(); var commas = new List(); while (CurrentToken.Kind == TokenKind.Comma) { commas.Add(Factory.Token(EatToken())); } + + return commas; + } + + private List ParseOptionalSemicolonsOrCommas() + { + var commas = new List(); + while (CurrentToken.Kind == TokenKind.Comma + || CurrentToken.Kind == TokenKind.Semicolon) + { + commas.Add(Factory.Token(EatToken())); + } + + return commas; + } + + private SwitchCaseNode ParseSwitchCase() + { + var caseKeyword = EatIdentifier("case"); + var caseId = ParseExpression(); + var commas = ParseOptionalCommas(); var statementList = ParseStatements(); return Factory.SwitchCase(Factory.Token(caseKeyword), caseId, statementList, commas); } @@ -693,11 +712,7 @@ namespace Parser { var switchKeyword = EatIdentifier("switch"); var expression = ParseExpression(); - var commas = new List(); - while (CurrentToken.Kind == TokenKind.Comma) - { - commas.Add(Factory.Token(EatToken())); - } + var commas = ParseOptionalCommas(); var casesList = new List(); while (CurrentToken.Kind == TokenKind.Identifier && CurrentToken.PureToken.LiteralText == "case") @@ -717,46 +732,30 @@ namespace Parser public ExpressionStatementNode ParseExpressionStatement() { var statement = ParseExpression(); - if (CurrentToken.Kind == TokenKind.Semicolon) - { - var semicolon = EatToken(); - return Factory.ExpressionStatement(statement, Factory.Token(semicolon)); - } - - return Factory.ExpressionStatement(statement); + var possibleSemicolonOrComma = PossibleSemicolonOrComma(); + return Factory.ExpressionStatement(statement, possibleSemicolonOrComma); } public WhileStatementNode ParseWhileStatement() { var whileKeyword = EatToken(); var condition = ParseExpression(); - var commas = new List(); - while (CurrentToken.Kind == TokenKind.Comma) - { - commas.Add(Factory.Token(EatToken())); - } + var commas = ParseOptionalCommas(); var body = ParseStatements(); var endKeyword = EatIdentifier("end"); + var semicolonOrComma = PossibleSemicolonOrComma(); return Factory.WhileStatement( Factory.Token(whileKeyword), condition, + commas, body, Factory.Token(endKeyword), - commas); + semicolonOrComma); } public StatementNode ParseStatement() { var statement = ParseStatementCore(); - if (statement != null) - { - if (CurrentToken.Kind == TokenKind.Semicolon - || CurrentToken.Kind == TokenKind.Comma) - { - statement = Factory.AppendSemicolonOrComma(statement, Factory.Token(EatToken())); - } - } - return statement; } @@ -764,12 +763,7 @@ namespace Parser { var ifKeyword = Factory.Token(EatToken()); var condition = ParseExpression(); - var commas = new List(); - while (CurrentToken.Kind == TokenKind.Comma - || CurrentToken.Kind == TokenKind.Semicolon) - { - commas.Add(Factory.Token(EatToken())); - } + var commas = ParseOptionalSemicolonsOrCommas(); var body = ParseStatements(); TokenNode elseKeyword = null; StatementListNode elseBody = null; @@ -788,22 +782,25 @@ namespace Parser return Factory.IfStatement( ifKeyword, condition, + commas, body, null, elseBody, null, - commas); + null); } var endKeyword = Factory.Token(EatIdentifier("end")); + var possibleSemicolonOrComma = PossibleSemicolonOrComma(); return Factory.IfStatement( ifKeyword, condition, + commas, body, elseKeyword, elseBody, endKeyword, - commas); + possibleSemicolonOrComma); } public ForStatementNode ParseForStatement() @@ -816,12 +813,7 @@ namespace Parser } var forAssignment = (AssignmentExpressionNode) expression; - var commas = new List(); - while (CurrentToken.Kind == TokenKind.Comma - || CurrentToken.Kind == TokenKind.Semicolon) - { - commas.Add(Factory.Token(EatToken())); - } + var commas = ParseOptionalSemicolonsOrCommas(); var body = ParseStatements(); var endKeyword = Factory.Token(EatIdentifier("end")); diff --git a/Parser/SyntaxFactory.cs b/Parser/SyntaxFactory.cs index fd7461a..298ac5c 100644 --- a/Parser/SyntaxFactory.cs +++ b/Parser/SyntaxFactory.cs @@ -219,16 +219,13 @@ namespace Parser return new UnquotedStringLiteralNode(stringLiteral); } - public ExpressionStatementNode ExpressionStatement(ExpressionNode expression) - { - var children = new List {expression}; - return new ExpressionStatementNode(children, expression, null); - } - public ExpressionStatementNode ExpressionStatement(ExpressionNode expression, TokenNode semicolonOrComma) { var children = new List {expression, semicolonOrComma}; - return new ExpressionStatementNode(children, expression, semicolonOrComma); + return new ExpressionStatementNode( + RemoveNulls(children), + expression, + semicolonOrComma); } public CellArrayElementAccessExpressionNode CellArrayElementAccessExpression( @@ -356,10 +353,10 @@ namespace Parser public WhileStatementNode WhileStatement( TokenNode whileKeyword, ExpressionNode condition, + List optionalCommasAfterCondition, StatementListNode body, TokenNode end, - List optionalCommasAfterCondition = null, - TokenNode semicolonOrComma = null) + TokenNode semicolonOrComma) { var children = new List { @@ -391,11 +388,12 @@ namespace Parser public IfStatementNode IfStatement( TokenNode ifKeyword, ExpressionNode condition, + List optionalCommasAfterCondition, StatementListNode body, TokenNode elseKeyword, StatementListNode elseBody, TokenNode endKeyword, - List optionalCommasAfterCondition = null) + TokenNode possibleSemicolonOrComma) { var children = new List { @@ -407,6 +405,7 @@ namespace Parser children.Add(elseKeyword); children.Add(elseBody); children.Add(endKeyword); + children.Add(possibleSemicolonOrComma); return new IfStatementNode( RemoveNulls(children), @@ -416,7 +415,8 @@ namespace Parser body, elseKeyword, elseBody, - endKeyword); + endKeyword, + possibleSemicolonOrComma); } public ParenthesizedExpressionNode ParenthesizedExpression( diff --git a/Parser/SyntaxNode.cs b/Parser/SyntaxNode.cs index 35c1123..f6476e8 100644 --- a/Parser/SyntaxNode.cs +++ b/Parser/SyntaxNode.cs @@ -572,8 +572,9 @@ namespace Parser StatementListNode body, TokenNode elseKeyword, StatementListNode elseBody, - TokenNode endKeyword - ) : base(children) + TokenNode endKeyword, + TokenNode possibleSemicolonOrComma + ) : base(children, possibleSemicolonOrComma) { IfKeyword = ifKeyword; Condition = condition;