From 64d06ec02ec6f0f2e4c58173860752ed629cc31c Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Sat, 6 Oct 2018 11:24:22 +0200 Subject: [PATCH] Search for functions & classes in subpackages --- ConsoleDemo/UsageGathering.cs | 4 +++ Parser.Tests/MParserShould.cs | 11 ++++++++ Parser/Internal/MParserGreen.cs | 23 +++++++-------- Semantics/Context.cs | 50 +++++++++++++++++++++++++++++++-- 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/ConsoleDemo/UsageGathering.cs b/ConsoleDemo/UsageGathering.cs index 9ad4de3..53ea181 100644 --- a/ConsoleDemo/UsageGathering.cs +++ b/ConsoleDemo/UsageGathering.cs @@ -34,6 +34,10 @@ namespace ConsoleDemo { Console.WriteLine("found."); } + else if (_context.FindClass(name)) + { + Console.WriteLine("found class constructor."); + } else { Console.WriteLine("NOT FOUND."); diff --git a/Parser.Tests/MParserShould.cs b/Parser.Tests/MParserShould.cs index d351218..6cfe48e 100644 --- a/Parser.Tests/MParserShould.cs +++ b/Parser.Tests/MParserShould.cs @@ -21,5 +21,16 @@ namespace Parser.Tests Assert.IsInstanceOf(assignment); Assert.IsInstanceOf(((ExpressionStatementSyntaxNode)assignment).Expression); } + + [Test] + public void ParseAssignmentExpression_Incomplete() + { + var text = "a = "; + var sut = GetSut(text); + var actual = sut.Parse(); + var assignment = actual.StatementList[0].AsNode(); + Assert.IsInstanceOf(assignment); + Assert.IsInstanceOf(((ExpressionStatementSyntaxNode)assignment).Expression); + } } } \ No newline at end of file diff --git a/Parser/Internal/MParserGreen.cs b/Parser/Internal/MParserGreen.cs index bfeb144..0f55b55 100644 --- a/Parser/Internal/MParserGreen.cs +++ b/Parser/Internal/MParserGreen.cs @@ -11,11 +11,13 @@ namespace Parser.Internal private Position CurrentPosition => Pairs[_index].position; private SyntaxToken PeekToken(int n) => Pairs[_index + n].token; private SyntaxFactory Factory { get; } + private List Errors { get; } public MParserGreen(List<(SyntaxToken, Position)> pairs, SyntaxFactory factory) { Pairs = pairs; Factory = factory; + Errors = new List(); } private SyntaxToken EatToken() @@ -30,7 +32,8 @@ namespace Parser.Internal var token = CurrentToken; if (token.Kind != kind) { - throw new ParsingException($"Unexpected token \"{token.Text}\" instead of {kind} at {CurrentPosition}."); + Errors.Add($"Unexpected token \"{token.Text}\" instead of {kind} at {CurrentPosition}."); + return TokenFactory.CreateMissing(kind, null, null); } _index++; return token; @@ -38,13 +41,7 @@ namespace Parser.Internal private SyntaxToken EatIdentifier() { - var token = CurrentToken; - if (token.Kind != TokenKind.Identifier) - { - throw new ParsingException($"Unexpected token \"{token}\" instead of identifier at {CurrentPosition}."); - } - _index++; - return token; + return EatToken(TokenKind.Identifier); } private bool IsIdentifier(SyntaxToken token, string s) @@ -57,12 +54,14 @@ namespace Parser.Internal var token = CurrentToken; if (token.Kind != TokenKind.Identifier) { - throw new ParsingException($"Unexpected token \"{token}\" instead of identifier \"{s}\" at {CurrentPosition}."); + Errors.Add($"Unexpected token \"{token.Text}\" instead of {TokenKind.Identifier} at {CurrentPosition}."); + return TokenFactory.CreateMissing(TokenKind.Identifier, null, null); } if (token.Text != s) { - throw new ParsingException($"Unexpected identifier \"{token.Text}\" instead of \"{s}\" at {CurrentPosition}."); + Errors.Add($"Unexpected token \"{token.Text}\" instead of identifier {s} at {CurrentPosition}."); + return TokenFactory.CreateMissing(TokenKind.Identifier, null, null); } _index++; @@ -143,7 +142,9 @@ namespace Parser.Internal } else { - throw new ParsingException($"Unexpected token {CurrentToken} during parsing function output description at {CurrentPosition}."); + Errors.Add( + $"Unexpected token {CurrentToken} during parsing function output description at {CurrentPosition}."); + return null; } return Factory.FunctionOutputDescriptionSyntax(builder.ToList(), assignmentSign); diff --git a/Semantics/Context.cs b/Semantics/Context.cs index 21be9e8..f51a122 100644 --- a/Semantics/Context.cs +++ b/Semantics/Context.cs @@ -20,7 +20,36 @@ namespace Semantics public bool FindFunction(string name) { - return Root.Functions.ContainsKey(name); + var names = name.Split('.'); + var currentPackage = Root; + for (var i = 0; i < names.Length - 1; i++) + { + if (!currentPackage.SubPackages.ContainsKey(names[i])) + { + return false; + } + + currentPackage = currentPackage.SubPackages[names[i]]; + } + + return currentPackage.Functions.ContainsKey(names[names.Length - 1]); + } + + public bool FindClass(string name) + { + var names = name.Split('.'); + var currentPackage = Root; + for (var i = 0; i < names.Length - 1; i++) + { + if (!currentPackage.SubPackages.ContainsKey(names[i])) + { + return false; + } + + currentPackage = currentPackage.SubPackages[names[i]]; + } + + return currentPackage.Classes.ContainsKey(names[names.Length - 1]); } private void ScanFunction(PackageContext context, string fileName) @@ -114,10 +143,18 @@ namespace Semantics foreach (var subDirectory in subDirectories) { var lastName = subDirectory.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Last(); + if (lastName == "specgraph") + { + Console.WriteLine("gotcha."); + } var packageName = GetPackageNameFromFolder(lastName); if (packageName != null) { - currentContext.SubPackages[packageName] = new PackageContext(packageName); + if (!currentContext.SubPackages.ContainsKey(packageName)) + { + currentContext.SubPackages[packageName] = new PackageContext(packageName); + } + ScanDirectory(currentContext.SubPackages[packageName], subDirectory); continue; } @@ -125,7 +162,14 @@ namespace Semantics var className = GetClassNameFromFolder(lastName); if (className != null) { - currentContext.Classes[className] = new ClassContext(className); + if (currentContext.Classes.ContainsKey(className)) + { + //throw new Exception($"Re-definition of class {className}."); + } + else + { + currentContext.Classes[className] = new ClassContext(className); + } ScanClassDirectory(currentContext.Classes[className], subDirectory); continue; }