From d781f8a469e518bece54999621232fe6698791e7 Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Sat, 31 Mar 2018 22:44:51 +0200 Subject: [PATCH] Parse indirect member access --- Parser.Tests/MParserShould.cs | 12 ++++++++++++ Parser/MParser.cs | 9 +++++++++ Parser/SyntaxFactory.cs | 20 ++++++++++++++++++++ Parser/SyntaxNode.cs | 18 ++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/Parser.Tests/MParserShould.cs b/Parser.Tests/MParserShould.cs index 09f358e..840aaca 100644 --- a/Parser.Tests/MParserShould.cs +++ b/Parser.Tests/MParserShould.cs @@ -213,5 +213,17 @@ namespace Parser.Tests var a = (CellArrayLiteralExpressionNode) actual; Assert.AreEqual(3, a.Elements.Elements.Count); } + + [Test] + public void ParseIndirectMemberAccess() + { + var text = "abc.(def)"; + var sut = CreateParser(text); + var actual = sut.ParseExpression(); + Assert.IsInstanceOf(actual); + var a = (MemberAccessNode) actual; + Assert.IsInstanceOf(a.LeftOperand); + Assert.IsInstanceOf(a.RightOperand); + } } } \ No newline at end of file diff --git a/Parser/MParser.cs b/Parser/MParser.cs index 1b84aa9..1b0df26 100644 --- a/Parser/MParser.cs +++ b/Parser/MParser.cs @@ -255,6 +255,15 @@ namespace Parser if (CurrentToken.Kind == TokenKind.Identifier) { return Factory.IdentifierName(EatToken()); + } else if (CurrentToken.Kind == TokenKind.OpeningBracket) + { + var openingBracket = EatToken(); + var indirectMember = ParseExpression(); + var closingBracket = EatToken(TokenKind.ClosingBracket); + return Factory.IndirectMemberAccess( + Factory.Token(openingBracket), + indirectMember, + Factory.Token(closingBracket)); } throw new ParsingException($"Unexpected token {CurrentToken.PureToken} at {CurrentToken.PureToken.Position}."); } diff --git a/Parser/SyntaxFactory.cs b/Parser/SyntaxFactory.cs index 151bd29..af7f844 100644 --- a/Parser/SyntaxFactory.cs +++ b/Parser/SyntaxFactory.cs @@ -503,5 +503,25 @@ namespace Parser SetParent(result); return result; } + + public IndirectMemberAccessNode IndirectMemberAccess( + TokenNode openingBracket, + ExpressionNode indirectMemberName, + TokenNode closingBracket) + { + var children = new List + { + openingBracket, + indirectMemberName, + closingBracket + }; + var result = new IndirectMemberAccessNode( + children, + openingBracket, + indirectMemberName, + closingBracket); + SetParent(result); + return result; + } } } \ No newline at end of file diff --git a/Parser/SyntaxNode.cs b/Parser/SyntaxNode.cs index 628c960..80506b0 100644 --- a/Parser/SyntaxNode.cs +++ b/Parser/SyntaxNode.cs @@ -512,4 +512,22 @@ namespace Parser EndKeyword = endKeyword; } } + + public class IndirectMemberAccessNode : ExpressionNode + { + public TokenNode OpeningBracket { get; } + public ExpressionNode IndirectMemberName { get; } + public TokenNode ClosingBracket { get; } + + public IndirectMemberAccessNode( + List children, + TokenNode openingBracket, + ExpressionNode indirectMemberName, + TokenNode closingBracket) : base(children) + { + OpeningBracket = openingBracket; + IndirectMemberName = indirectMemberName; + ClosingBracket = closingBracket; + } + } } \ No newline at end of file