From b695f4961adbfa7699deee6c857b223d272d934c Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Wed, 4 Apr 2018 12:55:17 +0200 Subject: [PATCH] Parse optional commas after switch case identifiers --- Parser/MParser.cs | 31 ++++++++++++++++++++++++++----- Parser/SyntaxFactory.cs | 35 +++++++++++++++++++++++++++++++---- Parser/SyntaxNode.cs | 5 ++++- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/Parser/MParser.cs b/Parser/MParser.cs index 021e8a1..6650842 100644 --- a/Parser/MParser.cs +++ b/Parser/MParser.cs @@ -680,8 +680,17 @@ namespace Parser { var caseKeyword = EatIdentifier("case"); var caseId = ParseExpression(); + var commas = new List(); + while (CurrentToken.Kind == TokenKind.Comma) + { + commas.Add(Factory.Token(EatToken())); + } + if (commas.Count == 0) + { + commas = null; + } var statementList = ParseStatements(); - return Factory.SwitchCase(Factory.Token(caseKeyword), caseId, statementList); + return Factory.SwitchCase(Factory.Token(caseKeyword), caseId, statementList, commas); } private SwitchStatementNode ParseSwitchStatement() @@ -829,10 +838,22 @@ namespace Parser { var tryKeyword = Factory.Token(EatIdentifier("try")); var tryBody = ParseStatements(); - var catchKeyword = Factory.Token(EatIdentifier("catch")); - var catchBody = ParseStatements(); - var endKeyword = Factory.Token(EatIdentifier("end")); - return Factory.TryCatchStatement(tryKeyword, tryBody, catchKeyword, catchBody, endKeyword); + if (CurrentToken.PureToken.LiteralText == "catch") + { + var catchKeyword = Factory.Token(EatIdentifier("catch")); + var catchBody = ParseStatements(); + var endKeyword = Factory.Token(EatIdentifier("end")); + return Factory.TryCatchStatement(tryKeyword, tryBody, catchKeyword, catchBody, endKeyword); + } + else if (CurrentToken.PureToken.LiteralText == "end") + { + var endKeyword = Factory.Token(EatIdentifier("end")); + return Factory.TryCatchStatement(tryKeyword, tryBody, endKeyword); + } + else + { + throw new ParsingException($"Unexpected token {CurrentToken.PureToken} while parsing try/catch statement at {CurrentToken.PureToken.Position}."); + } } public StatementNode ParseStatementCore() diff --git a/Parser/SyntaxFactory.cs b/Parser/SyntaxFactory.cs index 5695c24..ea65f14 100644 --- a/Parser/SyntaxFactory.cs +++ b/Parser/SyntaxFactory.cs @@ -154,15 +154,20 @@ namespace Parser public SwitchCaseNode SwitchCase( TokenNode caseKeyword, ExpressionNode caseIdentifier, - StatementListNode statementList) + StatementListNode statementList, + List optionalCommasAfterIdentifier) { var children = new List { caseKeyword, - caseIdentifier, - statementList + caseIdentifier }; - var result = new SwitchCaseNode(children, caseKeyword, caseIdentifier, statementList); + if (optionalCommasAfterIdentifier != null) + { + children.AddRange(optionalCommasAfterIdentifier); + } + children.Add(statementList); + var result = new SwitchCaseNode(children, caseKeyword, caseIdentifier, statementList, optionalCommasAfterIdentifier); SetParent(result); return result; } @@ -621,5 +626,27 @@ namespace Parser SetParent(result); return result; } + + public TryCatchStatementNode TryCatchStatement( + TokenNode tryKeyword, + StatementListNode tryBody, + TokenNode endKeyword) + { + var children = new List + { + tryKeyword, + tryBody, + endKeyword + }; + var result = new TryCatchStatementNode( + children, + tryKeyword, + tryBody, + null, + null, + endKeyword); + SetParent(result); + return result; + } } } \ No newline at end of file diff --git a/Parser/SyntaxNode.cs b/Parser/SyntaxNode.cs index 28aed0c..8c188bc 100644 --- a/Parser/SyntaxNode.cs +++ b/Parser/SyntaxNode.cs @@ -245,18 +245,21 @@ namespace Parser { public TokenNode CaseKeyword { get; } public ExpressionNode CaseIdentifier { get; } + public List OptionalCommasAfterIdentifier { get; } public StatementListNode StatementList { get; } public SwitchCaseNode( List children, TokenNode caseKeyword, ExpressionNode caseIdentifier, - StatementListNode statementList + StatementListNode statementList, + List optionalCommasAfterIdentifier = null ) : base(children) { CaseKeyword = caseKeyword; CaseIdentifier = caseIdentifier; StatementList = statementList; + OptionalCommasAfterIdentifier = optionalCommasAfterIdentifier; } }