Skip to content

Commit

Permalink
Add a LanguageParser.ParseOptional() method and get rid of some repea…
Browse files Browse the repository at this point in the history
…ted optional parsing logic.
  • Loading branch information
alexrp committed Feb 18, 2023
1 parent aac8645 commit b6ae575
Showing 1 changed file with 33 additions and 27 deletions.
60 changes: 33 additions & 27 deletions src/syntax/LanguageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ private static SeparatedSyntaxItemList<TElement, SyntaxToken> List<TElement>(
return new(List(elements), List(separators));
}

private T? ParseOptional<T>(SyntaxTokenKind kind, Func<LanguageParser, T> parser)
where T : SyntaxNode
{
return Peek1()?.Kind == kind ? parser(this) : null;
}

private (ImmutableArray<T>.Builder Elements, ImmutableArray<SyntaxToken>.Builder Separators) ParseSeparatedList<T>(
Func<LanguageParser, T> parser,
SyntaxTokenKind separator,
Expand Down Expand Up @@ -391,7 +397,7 @@ private AttributeSyntax ParseAttribute()
{
var at = Read();
var name = ExpectCodeIdentifier();
var value = Peek1()?.Kind == SyntaxTokenKind.Equals ? ParseAttributeValue() : null;
var value = ParseOptional(SyntaxTokenKind.Equals, static @this => @this.ParseAttributeValue());

return new(at, name, value);
}
Expand Down Expand Up @@ -455,7 +461,7 @@ private TypeDeclarationSyntax ParseTypeDeclaration(ImmutableArray<AttributeSynta
var opaque = pub != null ? Optional(SyntaxTokenKind.OpaqueKeyword) : null;
var kw = Expect(SyntaxTokenKind.TypeKeyword);
var name = Expect(SyntaxTokenKind.LowerIdentifier);
var parms = Peek1()?.Kind == SyntaxTokenKind.OpenParen ? ParseTypeParameterList() : null;
var parms = ParseOptional(SyntaxTokenKind.OpenParen, static @this => @this.ParseTypeParameterList());
var equals = Expect(SyntaxTokenKind.Equals);
var type = ParseType();

Expand Down Expand Up @@ -489,7 +495,7 @@ private ConstantDeclarationSyntax ParseConstantDeclaration(ImmutableArray<Attrib
var pub = Optional(SyntaxTokenKind.PubKeyword);
var @const = Expect(SyntaxTokenKind.ConstKeyword);
var name = ExpectCodeIdentifier();
var type = Peek1()?.Kind == SyntaxTokenKind.Colon ? ParseTypeAnnotation() : null;
var type = ParseOptional(SyntaxTokenKind.Colon, static @this => @this.ParseTypeAnnotation());
var equals = Expect(SyntaxTokenKind.Equals);
var body = ParseExpression();

Expand All @@ -504,7 +510,7 @@ private FunctionDeclarationSyntax ParseFunctionDeclaration(ImmutableArray<Attrib
var name = ExpectCodeIdentifier();
var parms = ParseFunctionParameterList();
var err = Optional(SyntaxTokenKind.ErrKeyword);
var type = Peek1()?.Kind == SyntaxTokenKind.MinusCloseAngle ? ParseReturnTypeAnnotation() : null;
var type = ParseOptional(SyntaxTokenKind.MinusCloseAngle, static @this => @this.ParseReturnTypeAnnotation());
var body = ext == null ? ParseBlockExpression() : null;

return new(List(attributes), pub, ext, fn, name, parms, err, type, body);
Expand All @@ -528,7 +534,7 @@ private FunctionParameterSyntax ParseFunctionParameter()
{
var attrs = ParseAttributes();
var name = ExpectBindingIdentifier();
var type = Peek1()?.Kind == SyntaxTokenKind.Colon ? ParseTypeAnnotation() : null;
var type = ParseOptional(SyntaxTokenKind.Colon, static @this => @this.ParseTypeAnnotation());

return new(List(attrs), name, type);
}
Expand Down Expand Up @@ -604,7 +610,7 @@ private BooleanTypeSyntax ParseBooleanType()
private IntegerTypeSyntax ParseIntegerType()
{
var @int = Read();
var range = Peek1()?.Kind == SyntaxTokenKind.OpenParen ? ParseIntegerTypeRange() : null;
var range = ParseOptional(SyntaxTokenKind.OpenParen, static @this => @this.ParseIntegerTypeRange());

return new(@int, range);
}
Expand Down Expand Up @@ -870,9 +876,9 @@ private AgentTypeMessageParameterSyntax ParseAgentTypeMessageParameter()

private NominalTypeSyntax ParseNominalType()
{
var path = Peek1()?.Kind == SyntaxTokenKind.UpperIdentifier ? ParseNominalTypePath() : null;
var path = ParseOptional(SyntaxTokenKind.UpperIdentifier, static @this => @this.ParseNominalTypePath());
var name = Expect(SyntaxTokenKind.LowerIdentifier);
var args = Peek1()?.Kind == SyntaxTokenKind.OpenParen ? ParseNominalTypeArgumentList() : null;
var args = ParseOptional(SyntaxTokenKind.OpenParen, static @this => @this.ParseNominalTypeArgumentList());

return new(path, name, args);
}
Expand Down Expand Up @@ -1433,7 +1439,7 @@ private IfExpressionSyntax ParseIfExpression()
var @if = Read();
var condition = ParseExpression();
var body = ParseBlockExpression();
var @else = Peek1()?.Kind == SyntaxTokenKind.ElseKeyword ? ParseExpressionElse() : null;
var @else = ParseOptional(SyntaxTokenKind.ElseKeyword, static @this => @this.ParseExpressionElse());

return new(@if, condition, body, @else);
}
Expand Down Expand Up @@ -1489,7 +1495,7 @@ private MatchExpressionSyntax ParseMatchExpression()
private ExpressionPatternArmSyntax ParseExpressionPatternArm()
{
var pat = ParsePattern();
var guard = Peek1()?.Kind == SyntaxTokenKind.IfKeyword ? ParseExpressionArmGuard() : null;
var guard = ParseOptional(SyntaxTokenKind.IfKeyword, static @this => @this.ParseExpressionArmGuard());
var arrow = Expect(SyntaxTokenKind.EqualsCloseAngle);
var body = ParseExpression();

Expand All @@ -1515,7 +1521,7 @@ private ReceiveExpressionSyntax ParseReceiveExpression()
allowEmpty: false,
allowTrailing: true);
var close = Expect(SyntaxTokenKind.CloseBrace);
var @else = Peek1()?.Kind == SyntaxTokenKind.ElseKeyword ? ParseExpressionElse() : null;
var @else = ParseOptional(SyntaxTokenKind.ElseKeyword, static @this => @this.ParseExpressionElse());

return new(recv, open, List(arms, seps), close, @else);
}
Expand All @@ -1524,7 +1530,7 @@ private ReceiveExpressionArmSyntax ParseReceiveExpressionArm()
{
var name = ExpectCodeIdentifier();
var parms = ParseReceiveParameterList();
var guard = Peek1()?.Kind == SyntaxTokenKind.IfKeyword ? ParseExpressionArmGuard() : null;
var guard = ParseOptional(SyntaxTokenKind.IfKeyword, static @this => @this.ParseExpressionArmGuard());
var arrow = Expect(SyntaxTokenKind.EqualsCloseAngle);
var body = ParseExpression();

Expand Down Expand Up @@ -1557,7 +1563,7 @@ private WhileExpressionSyntax ParseWhileExpression()
var @while = Read();
var condition = ParseExpression();
var body = ParseBlockExpression();
var @else = Peek1()?.Kind == SyntaxTokenKind.ElseKeyword ? ParseExpressionElse() : null;
var @else = ParseOptional(SyntaxTokenKind.ElseKeyword, static @this => @this.ParseExpressionElse());

return new(@while, condition, body, @else);
}
Expand All @@ -1569,7 +1575,7 @@ private ForExpressionSyntax ParseForExpression()
var @in = Expect(SyntaxTokenKind.InKeyword);
var collection = ParseExpression();
var body = ParseBlockExpression();
var @else = Peek1()?.Kind == SyntaxTokenKind.ElseKeyword ? ParseExpressionElse() : null;
var @else = ParseOptional(SyntaxTokenKind.ElseKeyword, static @this => @this.ParseExpressionElse());

return new(@for, pat, @in, collection, body, @else);
}
Expand Down Expand Up @@ -1601,7 +1607,7 @@ private NextExpressionSyntax ParseNextExpression()
private BreakExpressionSyntax ParseBreakExpression()
{
var @break = Read();
var result = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParseBreakExpressionResult() : null;
var result = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParseBreakExpressionResult());

return new(@break, result);
}
Expand Down Expand Up @@ -1674,7 +1680,7 @@ private IndexArgumentListSyntax ParseIndexArgumentList()
private CallExpressionSyntax ParseCallExpression(ExpressionSyntax subject)
{
var args = ParseCallArgumentList();
var @try = Peek1()?.Kind == SyntaxTokenKind.Question ? ParseCallExpressionTry() : null;
var @try = ParseOptional(SyntaxTokenKind.Question, static @this => @this.ParseCallExpressionTry());

return new(subject, args, @try);
}
Expand All @@ -1696,7 +1702,7 @@ private CallArgumentListSyntax ParseCallArgumentList()
private CallExpressionTrySyntax ParseCallExpressionTry()
{
var question = Read();
var @catch = Peek1()?.Kind == SyntaxTokenKind.CatchKeyword ? ParseCallExpressionTryCatch() : null;
var @catch = ParseOptional(SyntaxTokenKind.CatchKeyword, static @this => @this.ParseCallExpressionTryCatch());

return new(question, @catch);
}
Expand Down Expand Up @@ -1817,7 +1823,7 @@ private PatternSyntax ParseWildcardOrStringOrArrayPattern()
return ParseArrayPattern(binding);
}

var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new WildcardPatternSyntax(binding, alias);
}
Expand All @@ -1826,7 +1832,7 @@ private LiteralPatternSyntax ParseLiteralPattern()
{
var minus = OptionalMinus();
var literal = minus != null ? ExpectNumericLiteral() : Read();
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(minus, literal, alias);
}
Expand Down Expand Up @@ -1860,15 +1866,15 @@ private StringPatternSyntax ParseStringPattern(PatternBindingSyntax? binding)
}
}

var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(leftLit, leftSep, binding, rightSep, rightLit, alias);
}

private ModulePatternSyntax ParseModulePattern()
{
var path = ParseModulePath();
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(path, alias);
}
Expand All @@ -1884,7 +1890,7 @@ private RecordPatternSyntax ParseRecordPattern()
allowEmpty: true,
allowTrailing: true);
var close = Expect(SyntaxTokenKind.CloseBrace);
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(rec, open, List(fields, seps), close, alias);
}
Expand All @@ -1901,7 +1907,7 @@ private ErrorPatternSyntax ParseErrorPattern()
allowEmpty: true,
allowTrailing: true);
var close = Expect(SyntaxTokenKind.CloseBrace);
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(err, name, open, List(fields, seps), close, alias);
}
Expand Down Expand Up @@ -1932,7 +1938,7 @@ private TuplePatternSyntax ParseTuplePattern()
}

var close = Expect(SyntaxTokenKind.CloseParen);
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(open, List(comps, seps), close, alias);
}
Expand Down Expand Up @@ -1966,7 +1972,7 @@ private ArrayPatternSyntax ParseArrayPattern(PatternBindingSyntax? binding)
}
}

var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(leftClause, leftSep, binding, rightSep, rightClause, alias);
}
Expand Down Expand Up @@ -1996,7 +2002,7 @@ private MapPatternSyntax ParseMapPattern()
allowEmpty: true,
allowTrailing: true);
var close = Expect(SyntaxTokenKind.CloseBracket);
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(hash, open, List(pairs, seps), close, alias);
}
Expand All @@ -2021,7 +2027,7 @@ private SetPatternSyntax ParseSetPattern()
allowEmpty: true,
allowTrailing: true);
var close = Expect(SyntaxTokenKind.CloseBrace);
var alias = Peek1()?.Kind == SyntaxTokenKind.AsKeyword ? ParsePatternAlias() : null;
var alias = ParseOptional(SyntaxTokenKind.AsKeyword, static @this => @this.ParsePatternAlias());

return new(hash, open, List(elems, seps), close, alias);
}
Expand Down

0 comments on commit b6ae575

Please sign in to comment.