Lex unquoted string literals

This commit is contained in:
Alexander Luzgarev 2018-04-05 08:53:43 +02:00
parent 4c2f37b000
commit 215e0b52ed
5 changed files with 59 additions and 9 deletions

View File

@ -1,8 +1,7 @@
using System.Linq; using System.Linq;
using Lexer;
using NUnit.Framework; using NUnit.Framework;
namespace Parser.Tests namespace Lexer.Tests
{ {
public class MLexerShould public class MLexerShould
{ {
@ -22,8 +21,9 @@ namespace Parser.Tests
new[] {"undefined", "is", "not", "a", "function"}, new[] {"undefined", "is", "not", "a", "function"},
tokens.Take(5).Select(token => token.PureToken.LiteralText)); tokens.Take(5).Select(token => token.PureToken.LiteralText));
CollectionAssert.AreEqual( CollectionAssert.AreEqual(
Enumerable.Repeat(TokenKind.Identifier, 5), new[] { TokenKind.Identifier, TokenKind.UnquotedStringLiteral, TokenKind.UnquotedStringLiteral,
tokens.Take(5).Select(token => token.PureToken.Kind)); TokenKind.Identifier, TokenKind.UnquotedStringLiteral },
tokens.Take(5).Select(token => token.Kind));
} }
[Test] [Test]

View File

@ -1,7 +1,6 @@
using Lexer;
using NUnit.Framework; using NUnit.Framework;
namespace Parser.Tests namespace Lexer.Tests
{ {
[TestFixture] [TestFixture]
public class TestWindowShould public class TestWindowShould

View File

@ -1,7 +1,6 @@
using Lexer;
using NUnit.Framework; using NUnit.Framework;
namespace Parser.Tests namespace Lexer.Tests
{ {
[TestFixture] [TestFixture]
public class TestWindowWithNullShould public class TestWindowWithNullShould

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -363,9 +364,55 @@ namespace Lexer
return PureTokenFactory.CreateDoubleQuotedStringLiteral(literal); return PureTokenFactory.CreateDoubleQuotedStringLiteral(literal);
} }
private PureToken ContinueParsingUnquotedStringLiteral()
{
var n = 0;
while (true)
{
var c = Window.PeekChar(n);
if (c == ' ' || c == '\n' || c == '\0')
{
var literal = Window.GetAndConsumeChars(n);
return PureTokenFactory.CreateUnquotedStringLiteral(literal);
}
n++;
}
}
private static readonly HashSet<string> Keywords;
static MLexer()
{
Keywords = new HashSet<string>
{
"for", "if", "function", "while", "case", "try", "catch", "end",
"switch", "classdef", "elseif", "persistent",
};
}
private PureToken LexTokenWithoutTrivia(List<Trivia> leadingTrivia) private PureToken LexTokenWithoutTrivia(List<Trivia> leadingTrivia)
{ {
var character = Window.PeekChar(); var character = Window.PeekChar();
if (character == '\0')
{
return PureTokenFactory.CreateEndOfFileToken();
}
if (TokensSinceNewLine == 1
&& LastToken.Kind == TokenKind.Identifier
&& LastToken.TrailingTrivia.Any()
&& character != '='
&& character != '('
&& !Keywords.Contains(LastToken.PureToken.LiteralText))
{
return ContinueParsingUnquotedStringLiteral();
}
if (LastToken?.Kind == TokenKind.UnquotedStringLiteral &&
TokensSinceNewLine > 0)
{
return ContinueParsingUnquotedStringLiteral();
}
switch (character) switch (character)
{ {
case 'a': case 'a':

View File

@ -93,6 +93,11 @@
return new PureToken(TokenKind.DoubleQuotedStringLiteral, "\"" + s + "\"", s, Window.Position); return new PureToken(TokenKind.DoubleQuotedStringLiteral, "\"" + s + "\"", s, Window.Position);
} }
public PureToken CreateUnquotedStringLiteral(string s)
{
return new PureToken(TokenKind.UnquotedStringLiteral, s, s, Window.Position);
}
public PureToken CreateEndOfFileToken() public PureToken CreateEndOfFileToken()
{ {
return new PureToken(TokenKind.EndOfFile, "", null, Window.Position); return new PureToken(TokenKind.EndOfFile, "", null, Window.Position);