Simplifying parsing optional semicolons/commas

This commit is contained in:
Alexander Luzgarev 2018-04-07 15:22:02 +02:00
parent 5e7a4840b5
commit 51a0cc863f
3 changed files with 50 additions and 57 deletions

View File

@ -676,15 +676,34 @@ namespace Parser
return lhs; return lhs;
} }
private SwitchCaseNode ParseSwitchCase() private List<TokenNode> ParseOptionalCommas()
{ {
var caseKeyword = EatIdentifier("case");
var caseId = ParseExpression();
var commas = new List<TokenNode>(); var commas = new List<TokenNode>();
while (CurrentToken.Kind == TokenKind.Comma) while (CurrentToken.Kind == TokenKind.Comma)
{ {
commas.Add(Factory.Token(EatToken())); commas.Add(Factory.Token(EatToken()));
} }
return commas;
}
private List<TokenNode> ParseOptionalSemicolonsOrCommas()
{
var commas = new List<TokenNode>();
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(); var statementList = ParseStatements();
return Factory.SwitchCase(Factory.Token(caseKeyword), caseId, statementList, commas); return Factory.SwitchCase(Factory.Token(caseKeyword), caseId, statementList, commas);
} }
@ -693,11 +712,7 @@ namespace Parser
{ {
var switchKeyword = EatIdentifier("switch"); var switchKeyword = EatIdentifier("switch");
var expression = ParseExpression(); var expression = ParseExpression();
var commas = new List<TokenNode>(); var commas = ParseOptionalCommas();
while (CurrentToken.Kind == TokenKind.Comma)
{
commas.Add(Factory.Token(EatToken()));
}
var casesList = new List<SwitchCaseNode>(); var casesList = new List<SwitchCaseNode>();
while (CurrentToken.Kind == TokenKind.Identifier while (CurrentToken.Kind == TokenKind.Identifier
&& CurrentToken.PureToken.LiteralText == "case") && CurrentToken.PureToken.LiteralText == "case")
@ -717,46 +732,30 @@ namespace Parser
public ExpressionStatementNode ParseExpressionStatement() public ExpressionStatementNode ParseExpressionStatement()
{ {
var statement = ParseExpression(); var statement = ParseExpression();
if (CurrentToken.Kind == TokenKind.Semicolon) var possibleSemicolonOrComma = PossibleSemicolonOrComma();
{ return Factory.ExpressionStatement(statement, possibleSemicolonOrComma);
var semicolon = EatToken();
return Factory.ExpressionStatement(statement, Factory.Token(semicolon));
}
return Factory.ExpressionStatement(statement);
} }
public WhileStatementNode ParseWhileStatement() public WhileStatementNode ParseWhileStatement()
{ {
var whileKeyword = EatToken(); var whileKeyword = EatToken();
var condition = ParseExpression(); var condition = ParseExpression();
var commas = new List<TokenNode>(); var commas = ParseOptionalCommas();
while (CurrentToken.Kind == TokenKind.Comma)
{
commas.Add(Factory.Token(EatToken()));
}
var body = ParseStatements(); var body = ParseStatements();
var endKeyword = EatIdentifier("end"); var endKeyword = EatIdentifier("end");
var semicolonOrComma = PossibleSemicolonOrComma();
return Factory.WhileStatement( return Factory.WhileStatement(
Factory.Token(whileKeyword), Factory.Token(whileKeyword),
condition, condition,
commas,
body, body,
Factory.Token(endKeyword), Factory.Token(endKeyword),
commas); semicolonOrComma);
} }
public StatementNode ParseStatement() public StatementNode ParseStatement()
{ {
var statement = ParseStatementCore(); var statement = ParseStatementCore();
if (statement != null)
{
if (CurrentToken.Kind == TokenKind.Semicolon
|| CurrentToken.Kind == TokenKind.Comma)
{
statement = Factory.AppendSemicolonOrComma(statement, Factory.Token(EatToken()));
}
}
return statement; return statement;
} }
@ -764,12 +763,7 @@ namespace Parser
{ {
var ifKeyword = Factory.Token(EatToken()); var ifKeyword = Factory.Token(EatToken());
var condition = ParseExpression(); var condition = ParseExpression();
var commas = new List<TokenNode>(); var commas = ParseOptionalSemicolonsOrCommas();
while (CurrentToken.Kind == TokenKind.Comma
|| CurrentToken.Kind == TokenKind.Semicolon)
{
commas.Add(Factory.Token(EatToken()));
}
var body = ParseStatements(); var body = ParseStatements();
TokenNode elseKeyword = null; TokenNode elseKeyword = null;
StatementListNode elseBody = null; StatementListNode elseBody = null;
@ -788,22 +782,25 @@ namespace Parser
return Factory.IfStatement( return Factory.IfStatement(
ifKeyword, ifKeyword,
condition, condition,
commas,
body, body,
null, null,
elseBody, elseBody,
null, null,
commas); null);
} }
var endKeyword = Factory.Token(EatIdentifier("end")); var endKeyword = Factory.Token(EatIdentifier("end"));
var possibleSemicolonOrComma = PossibleSemicolonOrComma();
return Factory.IfStatement( return Factory.IfStatement(
ifKeyword, ifKeyword,
condition, condition,
commas,
body, body,
elseKeyword, elseKeyword,
elseBody, elseBody,
endKeyword, endKeyword,
commas); possibleSemicolonOrComma);
} }
public ForStatementNode ParseForStatement() public ForStatementNode ParseForStatement()
@ -816,12 +813,7 @@ namespace Parser
} }
var forAssignment = (AssignmentExpressionNode) expression; var forAssignment = (AssignmentExpressionNode) expression;
var commas = new List<TokenNode>(); var commas = ParseOptionalSemicolonsOrCommas();
while (CurrentToken.Kind == TokenKind.Comma
|| CurrentToken.Kind == TokenKind.Semicolon)
{
commas.Add(Factory.Token(EatToken()));
}
var body = ParseStatements(); var body = ParseStatements();
var endKeyword = Factory.Token(EatIdentifier("end")); var endKeyword = Factory.Token(EatIdentifier("end"));

View File

@ -219,16 +219,13 @@ namespace Parser
return new UnquotedStringLiteralNode(stringLiteral); return new UnquotedStringLiteralNode(stringLiteral);
} }
public ExpressionStatementNode ExpressionStatement(ExpressionNode expression)
{
var children = new List<SyntaxNode> {expression};
return new ExpressionStatementNode(children, expression, null);
}
public ExpressionStatementNode ExpressionStatement(ExpressionNode expression, TokenNode semicolonOrComma) public ExpressionStatementNode ExpressionStatement(ExpressionNode expression, TokenNode semicolonOrComma)
{ {
var children = new List<SyntaxNode> {expression, semicolonOrComma}; var children = new List<SyntaxNode> {expression, semicolonOrComma};
return new ExpressionStatementNode(children, expression, semicolonOrComma); return new ExpressionStatementNode(
RemoveNulls(children),
expression,
semicolonOrComma);
} }
public CellArrayElementAccessExpressionNode CellArrayElementAccessExpression( public CellArrayElementAccessExpressionNode CellArrayElementAccessExpression(
@ -356,10 +353,10 @@ namespace Parser
public WhileStatementNode WhileStatement( public WhileStatementNode WhileStatement(
TokenNode whileKeyword, TokenNode whileKeyword,
ExpressionNode condition, ExpressionNode condition,
List<TokenNode> optionalCommasAfterCondition,
StatementListNode body, StatementListNode body,
TokenNode end, TokenNode end,
List<TokenNode> optionalCommasAfterCondition = null, TokenNode semicolonOrComma)
TokenNode semicolonOrComma = null)
{ {
var children = new List<SyntaxNode> var children = new List<SyntaxNode>
{ {
@ -391,11 +388,12 @@ namespace Parser
public IfStatementNode IfStatement( public IfStatementNode IfStatement(
TokenNode ifKeyword, TokenNode ifKeyword,
ExpressionNode condition, ExpressionNode condition,
List<TokenNode> optionalCommasAfterCondition,
StatementListNode body, StatementListNode body,
TokenNode elseKeyword, TokenNode elseKeyword,
StatementListNode elseBody, StatementListNode elseBody,
TokenNode endKeyword, TokenNode endKeyword,
List<TokenNode> optionalCommasAfterCondition = null) TokenNode possibleSemicolonOrComma)
{ {
var children = new List<SyntaxNode> var children = new List<SyntaxNode>
{ {
@ -407,6 +405,7 @@ namespace Parser
children.Add(elseKeyword); children.Add(elseKeyword);
children.Add(elseBody); children.Add(elseBody);
children.Add(endKeyword); children.Add(endKeyword);
children.Add(possibleSemicolonOrComma);
return new IfStatementNode( return new IfStatementNode(
RemoveNulls(children), RemoveNulls(children),
@ -416,7 +415,8 @@ namespace Parser
body, body,
elseKeyword, elseKeyword,
elseBody, elseBody,
endKeyword); endKeyword,
possibleSemicolonOrComma);
} }
public ParenthesizedExpressionNode ParenthesizedExpression( public ParenthesizedExpressionNode ParenthesizedExpression(

View File

@ -572,8 +572,9 @@ namespace Parser
StatementListNode body, StatementListNode body,
TokenNode elseKeyword, TokenNode elseKeyword,
StatementListNode elseBody, StatementListNode elseBody,
TokenNode endKeyword TokenNode endKeyword,
) : base(children) TokenNode possibleSemicolonOrComma
) : base(children, possibleSemicolonOrComma)
{ {
IfKeyword = ifKeyword; IfKeyword = ifKeyword;
Condition = condition; Condition = condition;