final class SourceCursor
Restricted visibility: declared "@visibility root". Code outside that scope must not name this declaration.

A moving read position over grammar source text.

Scanners share one cursor and advance it as they consume characters, so the position is a collaborator they are handed rather than a field each of them reaches into. That is what lets a single lexeme rule — a quoted literal, a block comment, a brace-delimited action — be exercised on its own: give it a cursor over the input it should read, and inspect where the cursor stopped.

Methods§

public function __construct(private string $source)

Parameters

$sourcestringText to read
Test cases 25
Calls 1
public function atEnd(): bool

Reports whether the whole source has been consumed.

Returns

bool True when no character remains
Test cases 14
Called from 4
public function offset(): int

Reports the position the next read starts at.

Returns

int Zero-based offset into the source
Test cases 9
Called from 12
public function peek(): string|null
public function startsWith(string $prefix): bool

Reports whether the cursor sits on the given text.

Parameters

$prefixstringText to compare against

Returns

bool True when the source continues with that text
Test cases 2
Calls 2
public function advance(int $characters = 1): void

Moves the cursor forward without returning what was skipped.

Parameters

$charactersintHow many characters to skip
Test cases 11
Called from 11
Calls 1
public function skipWhitespace(): void
public function takeUntil(string $terminator): string

Consumes text up to the terminator, and the terminator with it.

An absent terminator consumes the rest of the source, which is how an unterminated prologue or comment is reported as its content instead of as a failure.

Parameters

$terminatorstringText that closes the run

Returns

string The text before the terminator
Test cases 2
Called from 2
Calls 3
public function takeQuoted(string $quote): string

Consumes a quoted run, starting at its opening quote.

A backslash escapes the character after it, so an escaped quote does not close the run. An unterminated run consumes the rest of the source.

Parameters

$quotestringThe quote character that opens and closes the run

Returns

string The unescaped text between the quotes
Test cases 3
Called from 2
Calls 1
public function textBetween(int $start, int $end): string

Reads back text the cursor has already passed over.

A lexeme whose body is defined by delimiters — a brace-delimited action, for instance — is recognised by walking to its closing delimiter and then asking for the text in between, rather than by accumulating characters it may still turn out not to own.

Parameters

$startintOffset the text begins at
$endintOffset the text ends before

Returns

string The text between the two offsets, empty when they cross
Test cases 2
Called from 1
Calls 1
public function takeRest(): string

Consumes everything that is left.

Returns

string The remaining source, empty when the cursor is at the end
Test cases 28
Called from 1
Calls 1

Private surface 3§

Implementation details, listed for orientation only.

private int $length
private int $offset = 0
private string $source

Test cases 83§

Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.

Dedicated tests 25
Other tests reaching this symbol 58

Relations§

Instantiated in 1
Method calls 45
Type declarations 16