antlr/antlr4 · error · ArgumentOutOfRangeException
LT(${i}) gives negative index
Error message
LT(${i}) gives negative index What it means
LT(i) maps positive lookahead to index p+i-1, and only i == -1 is special-cased to return the previous token. If the computed index is negative, the request looks before the beginning of the available token stream and is rejected. LT(0) and lookahead values below -1 are the usual causes.
Source
Thrown at runtime/CSharp/src/UnbufferedTokenStream.cs:137
int bufferStartIndex = GetBufferStartIndex();
if (i < bufferStartIndex || i >= bufferStartIndex + n)
{
throw new ArgumentOutOfRangeException("get(" + i + ") outside buffer: " + bufferStartIndex + ".." + (bufferStartIndex + n));
}
return tokens[i - bufferStartIndex];
}
public virtual IToken LT(int i)
{
if (i == -1)
{
return lastToken;
}
Sync(i);
int index = p + i - 1;
if (index < 0)
{
throw new ArgumentOutOfRangeException("LT(" + i + ") gives negative index");
}
if (index >= n)
{
System.Diagnostics.Debug.Assert(n > 0 && tokens[n - 1].Type == TokenConstants.EOF);
return tokens[n - 1];
}
return tokens[index];
}
public virtual int LA(int i)
{
return LT(i).Type;
}
public virtual ITokenSource TokenSource
{
get
{View on GitHub (pinned to 7d5770395b)
Solutions
- Use LT(1) for the current lookahead token and LT(-1) for the previous token.
- Do not call LT(0).
- Ensure lookahead loops start at i = 1.
Example fix
// before IToken current = tokens.LT(0); // after IToken current = tokens.LT(1);
Defensive patterns
Strategy: validation
Validate before calling
if (i != -1 && i < 1)
throw new ArgumentOutOfRangeException(nameof(i), "Use LT(1) or LT(-1).");
var token = tokens.LT(i); Try / catch
try { var t = tokens.LT(i); }
catch (ArgumentOutOfRangeException ex) when (ex.Message.StartsWith("LT(")) { /* correct lookahead index */ } Prevention
- Start lookahead loops at 1.
- Use LT(-1) only for the immediately preceding token.
- Do not assume LT(0) exists.
When it happens
Trigger: Calling LT(0) at the start of the stream; calling LT(-2) or smaller; generic loops that call LT(i) beginning at zero; or code that assumes LT(0) returns the current token or null.
Common situations: Token-iteration helpers written for a different API; lookahead loops using inclusive zero-based indexes; porting from another runtime whose LT semantics differ.
Related errors
- tokenSource cannot be null
- cannot consume EOF
- token index {i} out of range 0..{tokens.Count - 1}
- start {start} or stop {stop} not in 0..{tokens.Count - 1}
- {tokenIndex} not in 0..{tokens.Count - 1}
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/754daca4f1a00b5a.
Report an issue: GitHub.