-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTokenStream.cs
More file actions
57 lines (42 loc) · 1.73 KB
/
TokenStream.cs
File metadata and controls
57 lines (42 loc) · 1.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
namespace Lexepars
{
using System;
using System.Collections.Generic;
public class TokenStream
{
private readonly Lazy<TokenStream> _rest;
public TokenStream(IEnumerable<Token> tokens)
{
var enumerator = tokens.GetEnumerator();
Current = enumerator.MoveNext()
? enumerator.Current
: new Token(TokenKind.EndOfInput, new Position(1, 1), "");
_rest = new Lazy<TokenStream>(() => LazyAdvance(enumerator));
}
protected TokenStream(Token current, IEnumerator<Token> enumerator)
{
Current = current;
_rest = enumerator == null
? new Lazy<TokenStream>(() => this)
: new Lazy<TokenStream>(() => LazyAdvance(enumerator));
}
public Token Current { get; }
public virtual TokenStream Advance()
{
return _rest.Value;
}
public Position Position => Current.Position;
public override string ToString() => $">{Current}";
private TokenStream LazyAdvance(IEnumerator<Token> enumerator)
{
if (enumerator.MoveNext())
return CreateInstance(enumerator.Current, enumerator);
if (Current.Kind == TokenKind.EndOfInput)
return this;
var endPosition = new Position(Position.Line, Position.Column + Current.Lexeme?.Length ?? 0);
var endToken = new Token(TokenKind.EndOfInput, endPosition, string.Empty);
return CreateInstance(endToken, null);
}
protected virtual TokenStream CreateInstance(Token current, IEnumerator<Token> enumerator) => new TokenStream(current, enumerator);
}
}