Check for parentheses match during lexing
This commit is contained in:
parent
ae90b27b41
commit
38da3ecf0b
@ -11,11 +11,13 @@ namespace Lexer
|
|||||||
private Token LastToken { get; set; }
|
private Token LastToken { get; set; }
|
||||||
private int TokensSinceNewLine { get; set; }
|
private int TokensSinceNewLine { get; set; }
|
||||||
private PureTokenFactory PureTokenFactory { get; }
|
private PureTokenFactory PureTokenFactory { get; }
|
||||||
|
private Stack<TokenKind> TokenStack { get; }
|
||||||
|
|
||||||
public MLexer(ITextWindow window, PureTokenFactory pureTokenFactory)
|
public MLexer(ITextWindow window, PureTokenFactory pureTokenFactory)
|
||||||
{
|
{
|
||||||
Window = window;
|
Window = window;
|
||||||
PureTokenFactory = pureTokenFactory;
|
PureTokenFactory = pureTokenFactory;
|
||||||
|
TokenStack = new Stack<TokenKind>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsEolOrEof(char c)
|
private static bool IsEolOrEof(char c)
|
||||||
@ -400,6 +402,7 @@ namespace Lexer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (TokensSinceNewLine == 1
|
if (TokensSinceNewLine == 1
|
||||||
|
&& !TokenStack.Any()
|
||||||
&& LastToken.Kind == TokenKind.Identifier
|
&& LastToken.Kind == TokenKind.Identifier
|
||||||
&& LastToken.TrailingTrivia.Any()
|
&& LastToken.TrailingTrivia.Any()
|
||||||
&& character != '='
|
&& character != '='
|
||||||
@ -408,8 +411,9 @@ namespace Lexer
|
|||||||
{
|
{
|
||||||
return ContinueParsingUnquotedStringLiteral();
|
return ContinueParsingUnquotedStringLiteral();
|
||||||
}
|
}
|
||||||
if (LastToken?.Kind == TokenKind.UnquotedStringLiteral &&
|
if (LastToken?.Kind == TokenKind.UnquotedStringLiteral
|
||||||
TokensSinceNewLine > 0)
|
&& !TokenStack.Any()
|
||||||
|
&& TokensSinceNewLine > 0)
|
||||||
{
|
{
|
||||||
return ContinueParsingUnquotedStringLiteral();
|
return ContinueParsingUnquotedStringLiteral();
|
||||||
}
|
}
|
||||||
@ -642,6 +646,47 @@ namespace Lexer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsOpeningToken(TokenKind tokenKind)
|
||||||
|
{
|
||||||
|
switch (tokenKind)
|
||||||
|
{
|
||||||
|
case TokenKind.OpeningBrace:
|
||||||
|
case TokenKind.OpeningBracket:
|
||||||
|
case TokenKind.OpeningSquareBracket:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsClosingToken(TokenKind tokenKind)
|
||||||
|
{
|
||||||
|
switch (tokenKind)
|
||||||
|
{
|
||||||
|
case TokenKind.ClosingBrace:
|
||||||
|
case TokenKind.ClosingBracket:
|
||||||
|
case TokenKind.ClosingSquareBracket:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TokenKind? OpeningFromClosing(TokenKind tokenKind)
|
||||||
|
{
|
||||||
|
switch (tokenKind)
|
||||||
|
{
|
||||||
|
case TokenKind.ClosingBrace:
|
||||||
|
return TokenKind.OpeningBrace;
|
||||||
|
case TokenKind.ClosingBracket:
|
||||||
|
return TokenKind.OpeningBracket;
|
||||||
|
case TokenKind.ClosingSquareBracket:
|
||||||
|
return TokenKind.OpeningSquareBracket;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Token NextToken()
|
public Token NextToken()
|
||||||
{
|
{
|
||||||
var leadingTrivia = LexTrivia(false);
|
var leadingTrivia = LexTrivia(false);
|
||||||
@ -656,6 +701,36 @@ namespace Lexer
|
|||||||
TokensSinceNewLine++;
|
TokensSinceNewLine++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsOpeningToken(token.Kind))
|
||||||
|
{
|
||||||
|
TokenStack.Push(token.Kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsClosingToken(token.Kind))
|
||||||
|
{
|
||||||
|
if (TokenStack.TryPeek(out var t))
|
||||||
|
{
|
||||||
|
if (t == OpeningFromClosing(token.Kind))
|
||||||
|
{
|
||||||
|
TokenStack.Pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ParsingException($"Unmatched \"{token.LiteralText}\" at {token.Position}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ParsingException($"Unmatched \"{token.LiteralText}\" at {token.Position}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.Kind == TokenKind.EndOfFile
|
||||||
|
&& TokenStack.Any())
|
||||||
|
{
|
||||||
|
throw new ParsingException($"Unmatched \"{TokenStack.Pop()}\" by the end of file.");
|
||||||
|
}
|
||||||
|
|
||||||
var result = new Token(token, leadingTrivia, trailingTrivia);
|
var result = new Token(token, leadingTrivia, trailingTrivia);
|
||||||
LastToken = result;
|
LastToken = result;
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user