classSqliteTokenizer
final class SqliteTokenizer
Reads SQLite text back into the parser tokens the server would produce.
This is the inverse of realization and the reason realization can be trusted: SQL written from a terminal sequence is read back here, and the two sequences must agree. SQLite's rules are its own — an identifier may be quoted four ways, a digit-separated number is a token of its own, and a parameter may be written with any of five sigils — so a tokenizer that merely looked plausible would agree with a generator that was equally wrong.
Methods§
public function __construct(private array<string, string> $keywordTokens)Parameters
$keywordTokens | array<string, string> | Terminal name by upper-cased keyword |
public function tokenize(string $sql): list<string>Reads SQL text into the tokens SQLite's own lexer would produce.
Parameters
$sql | string | Text to read |
Returns
list<string> Parser token names, in orderThrows
LexicalException When the text holds something the lexer cannot readTest cases 3
Called from 1
Calls 5
- function-call
strlenline 74 - method-call SqliteTokenizer::skipTrivia() line 79
- static-call LexicalException::noProgress() line 81
- method-call SqliteTokenizer::tokenAt() line 87
- static-call LexicalException::unsupportedInput() line 89
public function tokenAt(string $sql, int &$offset): string|nullReads the one token that starts at the offset, advancing past it.
Parameters
$sql | string | Text being read |
$offset | int | Where to read from; moved past what was consumed |
Returns
string|null The token name, or null when nothing here is a tokenThrows
LexicalException When a quoted or bracketed run never closesTest cases 1
Called from 1
Calls 4
- method-call SqliteTokenizer::quotedTokenAt() line 114
- method-call SqliteTokenizer::literalTokenAt() line 115
- method-call SqliteTokenizer::wordTokenAt() line 116
- method-call SqliteTokenizer::operatorTokenAt() line 117
public function quotedTokenAt(string $sql, int &$offset): string|nullReads a quoted string or a quoted identifier in any of SQLite's spellings.
Parameters
$sql | string | Text being read |
$offset | int | Where to read from; moved past what was consumed |
Returns
string|null The token name, or null when no quoted run opens hereThrows
LexicalException When the run never closesTest cases 1
Called from 1
Calls 3
- method-call SqliteTokenizer::skipQuoted() line 135
- function-call
strposline 150 - static-call LexicalException::unterminatedBracketIdentifier() line 152
public function literalTokenAt(string $sql, int &$offset): string|nullReads a blob, a bound parameter, or a numeric literal.
Parameters
$sql | string | Text being read |
$offset | int | Where to read from; moved past what was consumed |
Returns
string|null The token name, or null when none of these start hereTest cases 1
Called from 1
public function wordTokenAt(string $sql, int &$offset): string|nullReads a keyword or an unquoted identifier.
Parameters
$sql | string | Text being read |
$offset | int | Where to read from; moved past what was consumed |
Returns
string|null The token name, or null when no word starts hereTest cases 1
Called from 1
public function operatorTokenAt(string $sql, int &$offset): string|nullReads an operator or a single punctuation character.
Parameters
$sql | string | Text being read |
$offset | int | Where to read from; moved past what was consumed |
Returns
string|null The token name, or null when nothing operator-like starts hereTest cases 1
Called from 1
Calls 2
- method-call SqliteTokenizer::operatorAt() line 223
- function-call
strlenline 228
public function skipTrivia(string $sql, int &$offset): boolConsumes whitespace or one comment.
Parameters
$sql | string | Text being read |
$offset | int | Where to read from; moved past what was consumed |
Returns
bool True when something was skippedThrows
LexicalException When a block comment never closesTest cases 2
Called from 1
public function skipQuoted(string $sql, int &$offset, string $quote): voidConsumes a quoted run, doubling being the way a quote escapes itself.
Parameters
$sql | string | Text being read |
$offset | int | Offset of the opening quote; moved past the closing one |
$quote | string | The quote character |
Throws
LexicalException When the run never closesTest cases 2
Called from 2
- method-call SqlFaker\Sqlite\Generation\Tokenization\SqliteTokenizer::quotedTokenAt() packages/sql-faker/src/Sqlite/Generation/Tokenization/SqliteTokenizer.php:135
- method-call SqlFaker\Sqlite\Generation\Tokenization\SqliteTokenizer::quotedTokenAt() packages/sql-faker/src/Sqlite/Generation/Tokenization/SqliteTokenizer.php:141
Calls 2
- function-call
strlenline 282 - static-call LexicalException::unterminatedQuotedToken() line 299
public function operatorAt(string $sql, int $offset): array{string, string}|nullReports the operator written at the offset and the token it stands for.
Parameters
$sql | string | Text being read |
$offset | int | Where to look |
Returns
array{string, string}|null The operator and its token, or null when there is noneTest cases 2
Called from 1
Calls 4
- class-const SqliteTokenizer::OPERATORS() line 312
- function-call
str_starts_withline 313 - function-call
substrline 313 - class-const SqliteTokenizer::PUNCTUATION() line 318
public function normalizedSourceTokens(list<string> $tokens): list<string>Strips the TK_ prefix and the spacing tokens SQLite's own lexer emits.
Witnesses record what SQLite's lexer produced, which names tokens with a prefix and reports whitespace as a token of its own. Neither belongs in the parser-token sequence this tokenizer is compared against.
Parameters
$tokens | list<string> | Tokens as the upstream lexer named them |
Returns
list<string> The same tokens as the parser names themTest cases 2
Private surface 3§
Implementation details, listed for orientation only.
private const OPERATORS = ['->>' => 'PTR', '->' => 'PTR', '||' => 'CONCAT', '==' => 'EQ', '<=' => 'LE', '…private const PUNCTUATION = ['(' => 'LP', ')' => 'RP', ';' => 'SEMI', ',' => 'COMMA', '.' => 'DOT', '=' => …private array<string, string> $keywordTokensTest cases 22§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 16
SqliteTokenizerTest::testLiteralTokenAtLeavesTextThatIsNoLiteralcallsSqliteTokenizerTest::testNormalizedSourceTokensLeavesUnprefixedNamesAlonecallsSqliteTokenizerTest::testNormalizedSourceTokensStripsThePrefixAndTheSpacingcallsSqliteTokenizerTest::testOperatorAtPrefersTheLongestOperatorcallsSqliteTokenizerTest::testOperatorAtReportsNothingForAWordcallsSqliteTokenizerTest::testOperatorTokenAtLeavesTextThatIsNoOperatorcallsSqliteTokenizerTest::testQuotedTokenAtLeavesAnythingThatOpensNoQuotecallsSqliteTokenizerTest::testSkipQuotedReportsARunThatNeverClosescallsSqliteTokenizerTest::testSkipQuotedTreatsADoubledQuoteAsAnEscapecallsSqliteTokenizerTest::testSkipTriviaReportsAnUnterminatedBlockCommentcallsSqliteTokenizerTest::testSkipTriviaReportsWhenNothingWasSkippedcallsSqliteTokenizerTest::testTokenAtReadsTheFirstTokenAndAdvancesPastItcallsSqliteTokenizerTest::testTokenizeReadsTextAsTheServerWouldcallsSqliteTokenizerTest::testTokenizeReportsAnUnterminatedBracketIdentifiercallsSqliteTokenizerTest::testTokenizeReportsTextItCannotReadcallsSqliteTokenizerTest::testWordTokenAtLeavesTextThatIsNoWordcalls
Other tests reaching this symbol 6
MySqlProviderTestcallsPostgreSqlProviderTestcallsGenerationContextTestcallsLexicalGrammarTestcallsSqlGeneratorFactoryTestcallsSqliteProviderTestcalls