Parse multi-line comments

This commit is contained in:
Alexander Luzgarev 2018-04-07 11:19:51 +02:00
parent 578d590bed
commit e54c01a243
4 changed files with 81 additions and 2 deletions

View File

@ -234,5 +234,22 @@ namespace Lexer.Tests
Assert.AreEqual(2, tokens.Count);
Assert.AreEqual(TokenKind.NumberLiteral, tokens[0].Kind);
}
[TestCase("%{\nabc\n%}", true)]
[TestCase("%{ a\nabc\n%}", false)]
[TestCase("if %{\nabc\n%}", false)]
public void ParseMultilineComments(string text, bool isMultiline)
{
var sut = CreateLexer(text);
var tokens = sut.ParseAll();
if (isMultiline)
{
Assert.AreEqual(1, tokens.Count);
}
else
{
Assert.Less(1, tokens.Count);
}
}
}
}

View File

@ -27,6 +27,10 @@ namespace Lexer
private Trivia LexComment()
{
if (TokensSinceNewLine == 0 && Window.PeekChar(1) == '{')
{
return LexMultilineComment();
}
var n = 1;
while (!IsEolOrEof(Window.PeekChar(n)))
{
@ -36,6 +40,52 @@ namespace Lexer
return new Trivia(TriviaType.Comment, Window.GetAndConsumeChars(n));
}
private Trivia LexMultilineComment()
{
var n = 2;
var metPercentSign = false;
var atFirstLine = true;
while (true)
{
var c = Window.PeekChar(n);
if (c == '\0')
{
throw new ParsingException($"Unexpected end of file while parsing multi-line comment.");
}
if (c == '\n')
{
atFirstLine = false;
}
if (atFirstLine && !IsWhitespace(c)) // this is a one-line comment
{
while (!IsEolOrEof(Window.PeekChar(n)))
{
n++;
}
return new Trivia(TriviaType.Comment, Window.GetAndConsumeChars(n));
}
if (metPercentSign && c == '}')
{
return new Trivia(TriviaType.MultiLineComment, Window.GetAndConsumeChars(n+1));
}
if (c == '%')
{
metPercentSign = true;
}
else
{
metPercentSign = false;
}
n++;
}
}
private List<Trivia> LexCommentAfterDotDotDot()
{
var n = 0;

View File

@ -52,8 +52,19 @@
public void ConsumeChars(int n)
{
for (var i = 0; i < n; i++)
{
if (PeekChar(i) == '\n' || PeekChar(i) == '\r')
{
_position.Line++;
_position.Column = 0;
}
else
{
_position.Column++;
}
}
Offset += n;
_position.Column += n;
}
public char GetAndConsumeChar()

View File

@ -4,6 +4,7 @@
{
Whitespace,
NewLine,
Comment
Comment,
MultiLineComment
}
}