Search for functions & classes in subpackages

This commit is contained in:
Alexander Luzgarev 2018-10-06 11:24:22 +02:00
parent d8e3f862eb
commit 64d06ec02e
4 changed files with 74 additions and 14 deletions

View File

@ -34,6 +34,10 @@ namespace ConsoleDemo
{ {
Console.WriteLine("found."); Console.WriteLine("found.");
} }
else if (_context.FindClass(name))
{
Console.WriteLine("found class constructor.");
}
else else
{ {
Console.WriteLine("NOT FOUND."); Console.WriteLine("NOT FOUND.");

View File

@ -21,5 +21,16 @@ namespace Parser.Tests
Assert.IsInstanceOf<ExpressionStatementSyntaxNode>(assignment); Assert.IsInstanceOf<ExpressionStatementSyntaxNode>(assignment);
Assert.IsInstanceOf<AssignmentExpressionSyntaxNode>(((ExpressionStatementSyntaxNode)assignment).Expression); Assert.IsInstanceOf<AssignmentExpressionSyntaxNode>(((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<ExpressionStatementSyntaxNode>(assignment);
Assert.IsInstanceOf<AssignmentExpressionSyntaxNode>(((ExpressionStatementSyntaxNode)assignment).Expression);
}
} }
} }

View File

@ -11,11 +11,13 @@ namespace Parser.Internal
private Position CurrentPosition => Pairs[_index].position; private Position CurrentPosition => Pairs[_index].position;
private SyntaxToken PeekToken(int n) => Pairs[_index + n].token; private SyntaxToken PeekToken(int n) => Pairs[_index + n].token;
private SyntaxFactory Factory { get; } private SyntaxFactory Factory { get; }
private List<string> Errors { get; }
public MParserGreen(List<(SyntaxToken, Position)> pairs, SyntaxFactory factory) public MParserGreen(List<(SyntaxToken, Position)> pairs, SyntaxFactory factory)
{ {
Pairs = pairs; Pairs = pairs;
Factory = factory; Factory = factory;
Errors = new List<string>();
} }
private SyntaxToken EatToken() private SyntaxToken EatToken()
@ -30,7 +32,8 @@ namespace Parser.Internal
var token = CurrentToken; var token = CurrentToken;
if (token.Kind != kind) 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++; _index++;
return token; return token;
@ -38,13 +41,7 @@ namespace Parser.Internal
private SyntaxToken EatIdentifier() private SyntaxToken EatIdentifier()
{ {
var token = CurrentToken; return EatToken(TokenKind.Identifier);
if (token.Kind != TokenKind.Identifier)
{
throw new ParsingException($"Unexpected token \"{token}\" instead of identifier at {CurrentPosition}.");
}
_index++;
return token;
} }
private bool IsIdentifier(SyntaxToken token, string s) private bool IsIdentifier(SyntaxToken token, string s)
@ -57,12 +54,14 @@ namespace Parser.Internal
var token = CurrentToken; var token = CurrentToken;
if (token.Kind != TokenKind.Identifier) 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) 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++; _index++;
@ -143,7 +142,9 @@ namespace Parser.Internal
} }
else 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); return Factory.FunctionOutputDescriptionSyntax(builder.ToList(), assignmentSign);

View File

@ -20,7 +20,36 @@ namespace Semantics
public bool FindFunction(string name) 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) private void ScanFunction(PackageContext context, string fileName)
@ -114,10 +143,18 @@ namespace Semantics
foreach (var subDirectory in subDirectories) foreach (var subDirectory in subDirectories)
{ {
var lastName = subDirectory.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Last(); var lastName = subDirectory.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Last();
if (lastName == "specgraph")
{
Console.WriteLine("gotcha.");
}
var packageName = GetPackageNameFromFolder(lastName); var packageName = GetPackageNameFromFolder(lastName);
if (packageName != null) 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); ScanDirectory(currentContext.SubPackages[packageName], subDirectory);
continue; continue;
} }
@ -125,7 +162,14 @@ namespace Semantics
var className = GetClassNameFromFolder(lastName); var className = GetClassNameFromFolder(lastName);
if (className != null) 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); ScanClassDirectory(currentContext.Classes[className], subDirectory);
continue; continue;
} }