From e5d0b0fe2e5637e8fa1b085d3ee3c9587ff7a26e Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Sun, 1 Apr 2018 20:00:16 +0200 Subject: [PATCH] Parse compound names in function handles --- Parser.Tests/MParserShould.cs | 15 ++++++++++++++- Parser/MParser.cs | 21 +++++++++++++++++++-- Parser/SyntaxFactory.cs | 17 ++++++++++++++--- Parser/SyntaxNode.cs | 19 ++++++++++++++++--- ProjectConsole/Program.cs | 2 +- 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/Parser.Tests/MParserShould.cs b/Parser.Tests/MParserShould.cs index f04d4c7..6f0f235 100644 --- a/Parser.Tests/MParserShould.cs +++ b/Parser.Tests/MParserShould.cs @@ -358,7 +358,20 @@ namespace Parser.Tests var actual = sut.ParseExpression(); Assert.IsInstanceOf(actual); var f = (NamedFunctionHandleNode) actual; - Assert.AreEqual("sqrt", f.IdentifierName.Token.PureToken.LiteralText); + Assert.AreEqual(1, f.FunctionName.Names.Count); + Assert.AreEqual("sqrt", f.FunctionName.Names[0].Token.PureToken.LiteralText); + Assert.AreEqual(text, actual.FullText); + } + + [Test] + public void ParseFunctionHandleWithCompoundName() + { + var text = "@a.b.c"; + var sut = CreateParser(text); + var actual = sut.ParseExpression(); + Assert.IsInstanceOf(actual); + var f = (NamedFunctionHandleNode) actual; + Assert.AreEqual(3, f.FunctionName.Names.Count); Assert.AreEqual(text, actual.FullText); } diff --git a/Parser/MParser.cs b/Parser/MParser.cs index 68c1179..c690fa2 100644 --- a/Parser/MParser.cs +++ b/Parser/MParser.cs @@ -554,15 +554,32 @@ namespace Parser } } + private CompoundNameNode ParseCompoundName() + { + var lastToken = EatToken(TokenKind.Identifier); + var firstName = Factory.IdentifierName(lastToken); + var nodes = new List {firstName}; + while (CurrentToken.Kind == TokenKind.Dot + && !lastToken.TrailingTrivia.Any()) + { + var dot = Factory.Token(EatToken()); + nodes.Add(dot); + lastToken = EatToken(TokenKind.Identifier); + nodes.Add(Factory.IdentifierName(lastToken)); + } + + return Factory.CompoundName(nodes); + } + private FunctionHandleNode ParseFunctionHandle() { var atSign = EatToken(); if (CurrentToken.Kind == TokenKind.Identifier) { - var identifierName = EatToken(TokenKind.Identifier); + var compoundName = ParseCompoundName(); return Factory.NamedFunctionHandle( Factory.Token(atSign), - Factory.IdentifierName(identifierName)); + compoundName); } else if (CurrentToken.Kind == TokenKind.OpeningBracket) { var inputs = ParseFunctionInputDescription(); diff --git a/Parser/SyntaxFactory.cs b/Parser/SyntaxFactory.cs index 571d9be..d026366 100644 --- a/Parser/SyntaxFactory.cs +++ b/Parser/SyntaxFactory.cs @@ -323,6 +323,17 @@ namespace Parser return result; } + public CompoundNameNode CompoundName(List nodes) + { + var result = new CompoundNameNode( + nodes, + nodes + .OfType() + .ToList()); + SetParent(result); + return result; + } + public ArrayLiteralExpressionNode ArrayLiteralExpression( TokenNode openingSquareBracket, ArrayElementListNode elements, @@ -544,17 +555,17 @@ namespace Parser public NamedFunctionHandleNode NamedFunctionHandle( TokenNode atSign, - IdentifierNameNode identifierName) + CompoundNameNode functionName) { var children = new List { atSign, - identifierName + functionName }; var result = new NamedFunctionHandleNode( children, atSign, - identifierName); + functionName); SetParent(result); return result; } diff --git a/Parser/SyntaxNode.cs b/Parser/SyntaxNode.cs index cf1dd7c..27d5616 100644 --- a/Parser/SyntaxNode.cs +++ b/Parser/SyntaxNode.cs @@ -451,6 +451,19 @@ namespace Parser } + public class CompoundNameNode : ExpressionNode + { + public List Names; + + public CompoundNameNode( + List children, + List names + ) : base(children) + { + Names = names; + } + } + public class MemberAccessNode : ExpressionNode { public SyntaxNode LeftOperand { get; } @@ -598,15 +611,15 @@ namespace Parser public class NamedFunctionHandleNode : FunctionHandleNode { public TokenNode AtSign { get; } - public IdentifierNameNode IdentifierName { get; } + public CompoundNameNode FunctionName { get; } public NamedFunctionHandleNode( List children, TokenNode atSign, - IdentifierNameNode identifierName) : base(children) + CompoundNameNode functionName) : base(children) { AtSign = atSign; - IdentifierName = identifierName; + FunctionName = functionName; } } diff --git a/ProjectConsole/Program.cs b/ProjectConsole/Program.cs index f9f4192..fc66c76 100644 --- a/ProjectConsole/Program.cs +++ b/ProjectConsole/Program.cs @@ -11,7 +11,7 @@ namespace ProjectConsole class Program { //private const string BaseDirectory = @"C:\Program Files\MATLAB\R2018a\toolbox\matlab\"; - private const string BaseDirectory = @"/Applications/MATLAB_R2017b.app/toolbox/matlab/guide/"; + private const string BaseDirectory = @"/Applications/MATLAB_R2017b.app/toolbox/matlab/"; private static HashSet skipFiles = new HashSet {