public Token LookAhead(params TokenType[] expectedtokens)
{
int startPos = StartPos;
int endPos = EndPos;
int currentline = CurrentLine;
string currentFile = CurrentFile;
Token tok;
List<TokenType> scantokens;
// this prevents double scanning and matching
// increased performance
if (_lookAheadToken != null
&& _lookAheadToken.Type != TokenType._UNDETERMINED_
&& _lookAheadToken.Type != TokenType._NONE_) return _lookAheadToken;
// if no scantokens specified, then scan for all of them (= backward compatible)
if (expectedtokens.Length == 0)
scantokens = _tokens;
else
{
scantokens = new List<TokenType>(expectedtokens);
scantokens.AddRange(_skipList);
}
do
{
int len = -1;
TokenType index = (TokenType) int.MaxValue;
string input = Input.Substring(startPos);
tok = new Token(startPos, endPos);
int i;
for (i = 0; i < scantokens.Count; i++)
{
Regex r = Patterns[scantokens[i]];
Match m = r.Match(input);
if (m.Success && m.Index == 0 && ((m.Length > len) || (scantokens[i] < index && m.Length == len)))
{
len = m.Length;
index = scantokens[i];
}
}
if (index >= 0 && len >= 0)
{
tok.EndPos = startPos + len;
tok.Text = Input.Substring(tok.StartPos, len);
tok.Type = index;
}
else if (tok.StartPos == tok.EndPos)
{
tok.Text = tok.StartPos < Input.Length ? Input.Substring(tok.StartPos, 1) : "EOF";
}
// Update the line and column count for error reporting.
tok.File = currentFile;
tok.Line = currentline;
if (tok.StartPos < Input.Length)
tok.Column = tok.StartPos - Input.LastIndexOf('\n', tok.StartPos);
if (_skipList.Contains(tok.Type))
{
startPos = tok.EndPos;
endPos = tok.EndPos;
currentline = tok.Line + (tok.Text.Length - tok.Text.Replace("\n", "").Length);
currentFile = tok.File;
Skipped.Add(tok);
}
else
{
// only assign to non-skipped tokens
tok.Skipped = Skipped; // assign prior skips to this token
Skipped = new List<Token>(); //reset skips
}
} while (_skipList.Contains(tok.Type));
_lookAheadToken = tok;
return tok;
}
}