abstract class Lexer

internal  
 

Split SQL into statements and tokens located in the original source.

Reading and skipping share one scanner. Tokens are only created as a parser reads them, so the unread remainder of a statement, and the body of a group whose source text is all a parser needs, cost a scan.

Constants

protected HIGH_BYTES

Bytes of multibyte characters, which unquoted identifiers may contain.

protected LETTERS

protected DIGITS

protected WHITESPACE

protected COMMENT_STARTS

Bytes that can begin a comment, so skipComment() is only called where one may start.

private WINDOW_LENGTH

The most source that runs are matched against at once.

private WINDOW_CUTS

The bytes a window can be cut before, as no unquoted token contains them.

Properties

protected int $length
protected int $position
protected int $statementStart
protected int $tokenStart

The start of the token or terminator most recently scanned.

protected bool $ended
protected int $windowStart

Methods

__construct(string $sql)

Create a lexer over the complete SQL input.

nextStatement()

Begin the next non-empty statement, or return null at the end of the input.

void
read(array $types, array $starts, array $ends, array $texts)

Append the next tokens of the current statement, through its terminator at most.

TokenType
type(string $text)

Get the type of a token appended without one, which follows from its upper-case text.

array|null
matchRun(string $pattern)

Match a run of tokens at the position, or return null where the scanner must read the next token.

array
skipStatement()

Skip the rest of the current statement and return the offsets of its terminator.

int|null
skipGroup(int $depth)

Skip to the parenthesis that closes the given number of open groups and return its start.

string
value(TokenType $type, int $start, int $end)

Decode a token's value.

int
line(int $offset)

Get the one-based line containing a source offset.

error(string $message, int $offset)

Create a parse error located at a source offset.

TokenType
scan()

Scan one token or the statement terminator.

void
finishStatement()

Mark the current statement as ended at its terminator.

TokenType
scanToken()

Scan the token starting at the current position, or a terminator as End.

void
skip()

Scan to the end of the current statement.

int
terminator()

Get the length of a statement terminator at the current position, or zero.

bool
skipCommand()

Consume a client command between statements.

void
startStatement()

Reset state tracked within one statement.

void
endStatement()

Handle input that belongs to a statement after its terminator.

void
skipWhitespace()

Skip whitespace and comments.

bool
skipComment()

Skip a comment at the current position.

void
skipLine()

Skip to the start of the next line.

void
scanQuoted(string $quote, bool $backslashes, string $description)

Scan a quoted run whose opening quote is at the position, escaped by doubling and optionally backslashes.

string
word(int $start, int $end)

Normalize an unquoted identifier or keyword.

string
identifier(int $start, int $end)

Decode a quoted identifier.

string
string(TokenType $type, int $start, int $end)

Decode a string literal whose quotes are escaped by doubling.

Details

at line 67
__construct(string $sql)

Create a lexer over the complete SQL input.

Parameters

string $sql

at line 77
TokenStream|null nextStatement()

Begin the next non-empty statement, or return null at the end of the input.

Return Value

TokenStream|null

at line 118
void read(array $types, array $starts, array $ends, array $texts)

Append the next tokens of the current statement, through its terminator at most.

Each token is appended with its start offset and upper-case source text; a token scanned on its own also records its type. A terminator has an empty text and its end recorded, as its span can include COPY data.

Parameters

array $types
array $starts
array $ends
array $texts

Return Value

void

at line 138
abstract TokenType type(string $text)

Get the type of a token appended without one, which follows from its upper-case text.

Tokens whose type depends on the lexer's state, such as string literals, always have it recorded.

Parameters

string $text

Return Value

TokenType

at line 149
protected array|null matchRun(string $pattern)

Match a run of tokens at the position, or return null where the scanner must read the next token.

Dialects read runs of ordinary tokens with one native match each, so only tokens that need boundary handling go through the scanner. A statement's first token is matched alone, as parsers skip most statements after it.

Parameters

string $pattern

Return Value

array|null

the upper-case texts and their offsets from $windowStart

at line 194
array skipStatement()

Skip the rest of the current statement and return the offsets of its terminator.

Return Value

array

at line 208
int|null skipGroup(int $depth)

Skip to the parenthesis that closes the given number of open groups and return its start.

Returns null when the statement ends first.

Parameters

int $depth

Return Value

int|null

at line 226
string value(TokenType $type, int $start, int $end)

Decode a token's value.

Parameters

TokenType $type
int $start
int $end

Return Value

string

at line 239
int line(int $offset)

Get the one-based line containing a source offset.

Parameters

int $offset

Return Value

int

at line 247
ParseException error(string $message, int $offset)

Create a parse error located at a source offset.

Parameters

string $message
int $offset

Return Value

ParseException

at line 255
protected TokenType scan()

Scan one token or the statement terminator.

Return Value

TokenType

at line 272
protected void finishStatement()

Mark the current statement as ended at its terminator.

Return Value

void

at line 281
abstract protected TokenType scanToken()

Scan the token starting at the current position, or a terminator as End.

Return Value

TokenType

at line 286
protected void skip()

Scan to the end of the current statement.

Return Value

void

at line 294
protected int terminator()

Get the length of a statement terminator at the current position, or zero.

Return Value

int

at line 302
protected bool skipCommand()

Consume a client command between statements.

Return Value

bool

at line 310
protected void startStatement()

Reset state tracked within one statement.

Return Value

void

at line 317
protected void endStatement()

Handle input that belongs to a statement after its terminator.

Return Value

void

at line 324
protected void skipWhitespace()

Skip whitespace and comments.

Return Value

void

at line 334
protected bool skipComment()

Skip a comment at the current position.

Return Value

bool

at line 363
protected void skipLine()

Skip to the start of the next line.

Return Value

void

at line 373
protected void scanQuoted(string $quote, bool $backslashes, string $description)

Scan a quoted run whose opening quote is at the position, escaped by doubling and optionally backslashes.

Parameters

string $quote
bool $backslashes
string $description

Return Value

void

at line 402
protected string word(int $start, int $end)

Normalize an unquoted identifier or keyword.

Parameters

int $start
int $end

Return Value

string

at line 410
protected string identifier(int $start, int $end)

Decode a quoted identifier.

Parameters

int $start
int $end

Return Value

string

at line 421
protected string string(TokenType $type, int $start, int $end)

Decode a string literal whose quotes are escaped by doubling.

Parameters

TokenType $type
int $start
int $end

Return Value

string