classPgLookahead
final class PgLookahead
The token substitutions PostgreSQL's parser frontend makes by looking ahead.
A few words mean different things depending on what follows them: NOT before NULL is not the NOT of an expression, WITH before TIME is not the WITH of a CTE. PostgreSQL resolves this between its lexer and its parser by rewriting the first token once the second is known.
Generation and tokenizing both have to apply the same rewriting or they would disagree about what the same text means, and realization has to be able to walk it backwards to find the keyword a substituted token is spelled as.
Type Aliases§
LookaheadRule = array{token: string, followed_by: list<string>}Methods§
public static function definitions(): array<string, LookaheadRule>Declares the token substitutions from PostgreSQL 17.2 parser.c/base_yylex.
Returns
array<string, LookaheadRule>Test cases 1
Called from 3
- static-call SqlFaker\PostgreSql\Generation\Lexeme\KeywordLexemeGenerator::generate() packages/sql-faker/src/PostgreSql/Generation/Lexeme/KeywordLexemeGenerator.php:37
- static-call SqlFaker\PostgreSql\Generation\LexicalGrammar::__construct() packages/sql-faker/src/PostgreSql/Generation/LexicalGrammar.php:72
- static-call SqlFaker\PostgreSql\Generation\Rewrite\LookaheadRule::rewrite() packages/sql-faker/src/PostgreSql/Generation/Rewrite/LookaheadRule.php:35
public function __construct(private array<string, LookaheadRule> $rules)Parameters
$rules | array<string, LookaheadRule> | Substitution by the token that triggers it |
Test cases 1
public function applied(list<string> $tokens): list<string>Applies the substitutions to a token sequence.
Parameters
$tokens | list<string> | Tokens as read or as generated |
Returns
list<string> The sequence with each triggered substitution appliedTest cases 9
PgLookaheadTest::testAppliedFindsNothingToDoWithoutRulescovers and callsPgLookaheadTest::testAppliedLeavesATokenThatTriggersNothingcallsPgLookaheadTest::testAppliedLeavesATokenThatTriggersNothing#NOT before NULLcoversPgLookaheadTest::testAppliedLeavesTheLastTokenAloneBecauseNothingFollowsItcallsPgLookaheadTest::testAppliedLeavesTheLastTokenAloneBecauseNothingFollowsIt#NOT before NULLcoversPgLookaheadTest::testAppliedLeavesTheTokenAloneForAnotherFollowercallsPgLookaheadTest::testAppliedLeavesTheTokenAloneForAnotherFollower#NOT before NULLcoversPgLookaheadTest::testAppliedSubstitutesWhenTheFollowerCallsForItcallsPgLookaheadTest::testAppliedSubstitutesWhenTheFollowerCallsForIt#NOT before NULLcovers
Called from 1
Calls 1
- function-call
in_arrayline 58
public function normalized(list<string> $terminals): list<string>Settles each terminal on the spelling its neighbour calls for.
Unlike applied(), this also walks a substitution backwards: a plan that asked for the substituted token where the follower does not call for it gets the base token, because that is what the text would read back as.
Parameters
$terminals | list<string> | Terminals a derivation produced |
Returns
list<string> The terminals with each substitution settledTest cases 6
PgLookaheadTest::testNormalizedLeavesATerminalThatTriggersNothingcallsPgLookaheadTest::testNormalizedLeavesATerminalThatTriggersNothing#NOT before NULLcoversPgLookaheadTest::testNormalizedSettlesTheBaseTokenOnItsSubstitutecallsPgLookaheadTest::testNormalizedSettlesTheBaseTokenOnItsSubstitute#NOT before NULLcoversPgLookaheadTest::testNormalizedWalksASubstitutionBackWhenTheFollowerDoesNotCallForItcallsPgLookaheadTest::testNormalizedWalksASubstitutionBackWhenTheFollowerDoesNotCallForIt#NOT before NULLcovers
Called from 1
Calls 1
- function-call
in_arrayline 85
public function baseOf(string $terminal): string|nullReports the token a substituted one is spelled as.
A substituted token has no keyword of its own; it borrows the spelling of the token it replaced, so realization has to ask which that was.
Parameters
$terminal | string | Terminal to look up |
Returns
string|null The token it substitutes for, or null when it substitutes for noneTest cases 4
PgLookaheadTest::testBaseOfReportsNothingForATokenThatSubstitutesForNonecallsPgLookaheadTest::testBaseOfReportsNothingForATokenThatSubstitutesForNone#NOT before NULLcoversPgLookaheadTest::testBaseOfReportsTheTokenASubstituteIsSpelledAscallsPgLookaheadTest::testBaseOfReportsTheTokenASubstituteIsSpelledAs#NOT before NULLcovers
Private surface 1§
Implementation details, listed for orientation only.
private array<string, LookaheadRule> $rulesTest cases 50§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 21
PgLookaheadTest::providerLookaheadcallsPgLookaheadTest::testAppliedFindsNothingToDoWithoutRulescovers and callsPgLookaheadTest::testAppliedLeavesATokenThatTriggersNothingcallsPgLookaheadTest::testAppliedLeavesATokenThatTriggersNothing#NOT before NULLcoversPgLookaheadTest::testAppliedLeavesTheLastTokenAloneBecauseNothingFollowsItcallsPgLookaheadTest::testAppliedLeavesTheLastTokenAloneBecauseNothingFollowsIt#NOT before NULLcoversPgLookaheadTest::testAppliedLeavesTheTokenAloneForAnotherFollowercallsPgLookaheadTest::testAppliedLeavesTheTokenAloneForAnotherFollower#NOT before NULLcoversPgLookaheadTest::testAppliedSubstitutesWhenTheFollowerCallsForItcallsPgLookaheadTest::testAppliedSubstitutesWhenTheFollowerCallsForIt#NOT before NULLcoversPgLookaheadTest::testBaseOfReportsNothingForATokenThatSubstitutesForNonecallsPgLookaheadTest::testBaseOfReportsNothingForATokenThatSubstitutesForNone#NOT before NULLcoversPgLookaheadTest::testBaseOfReportsTheTokenASubstituteIsSpelledAscallsPgLookaheadTest::testBaseOfReportsTheTokenASubstituteIsSpelledAs#NOT before NULLcoversPgLookaheadTest::testDefinitionsKeepsTheParserLookaheadFollowersExplicitcovers and callsPgLookaheadTest::testNormalizedLeavesATerminalThatTriggersNothingcallsPgLookaheadTest::testNormalizedLeavesATerminalThatTriggersNothing#NOT before NULLcoversPgLookaheadTest::testNormalizedSettlesTheBaseTokenOnItsSubstitutecallsPgLookaheadTest::testNormalizedSettlesTheBaseTokenOnItsSubstitute#NOT before NULLcoversPgLookaheadTest::testNormalizedWalksASubstitutionBackWhenTheFollowerDoesNotCallForItcallsPgLookaheadTest::testNormalizedWalksASubstitutionBackWhenTheFollowerDoesNotCallForIt#NOT before NULLcovers
Other tests reaching this symbol 29
MySqlProviderTestcallsGenerationContextTestcallsDefinitionFactoryTestcallsKeywordLexemeGeneratorTestcallsLexicalGrammarTestcallsLookaheadRuleTestcallsRewriteDefinitionsTestcallsPgTokenizerTest::testDollarTokenAtLeavesADollarThatOpensNeithercallsPgTokenizerTest::testFixedOperatorNamesTheOperatorsThatHaveTokenscallsPgTokenizerTest::testIsPunctuationAcceptsASingleGrammarCharactercallsPgTokenizerTest::testNumericTokenAtLeavesTextThatIsNoNumbercallsPgTokenizerTest::testOperatorAtReportsNothingForAWordcallsPgTokenizerTest::testOperatorAtReportsPunctuationAsItselfcallsPgTokenizerTest::testOperatorAtTakesTheLongestRunOfOperatorCharacterscallsPgTokenizerTest::testOperatorTokenAtLeavesTextThatIsNoOperatorcallsPgTokenizerTest::testQuotedTokenAtLeavesAnythingThatOpensNoQuotecallsPgTokenizerTest::testSkipQuotedReportsARunThatNeverClosescallsPgTokenizerTest::testSkipQuotedTreatsADoubledQuoteAsAnEscapecallsPgTokenizerTest::testSkipTriviaReportsAnUnterminatedBlockCommentcallsPgTokenizerTest::testSkipTriviaReportsWhenNothingWasSkippedcallsPgTokenizerTest::testTokenAtReadsTheFirstTokenAndAdvancesPastItcallsPgTokenizerTest::testTokenizeAppliesTheLookaheadSubstitutioncallsPgTokenizerTest::testTokenizeReadsTextAsTheServerWouldcallsPgTokenizerTest::testTokenizeReportsAnUnterminatedDollarQuotedStringcallsPgTokenizerTest::testTokenizeReportsTextItCannotReadcallsPgTokenizerTest::testWordTokenAtLeavesTextThatIsNoWordcallsPostgreSqlProviderTestcallsSqlGeneratorFactoryTestcallsSqliteProviderTestcalls
Relations§
Instantiated in 1
Static calls 3
- static-call SqlFaker\PostgreSql\Generation\Lexeme\KeywordLexemeGenerator::generate() packages/sql-faker/src/PostgreSql/Generation/Lexeme/KeywordLexemeGenerator.php:37
- static-call SqlFaker\PostgreSql\Generation\LexicalGrammar::__construct() packages/sql-faker/src/PostgreSql/Generation/LexicalGrammar.php:72
- static-call SqlFaker\PostgreSql\Generation\Rewrite\LookaheadRule::rewrite() packages/sql-faker/src/PostgreSql/Generation/Rewrite/LookaheadRule.php:35
Method calls 2
- method-call SqlFaker\PostgreSql\Generation\LexicalGrammar::normalizeLookahead() packages/sql-faker/src/PostgreSql/Generation/LexicalGrammar.php:105
- method-call SqlFaker\PostgreSql\Generation\Tokenization\PgTokenizer::tokenize() packages/sql-faker/src/PostgreSql/Generation/Tokenization/PgTokenizer.php:81
Type declarations 3
- type SqlFaker\PostgreSql\Generation\LexicalGrammar packages/sql-faker/src/PostgreSql/Generation/LexicalGrammar.php:48
- type SqlFaker\PostgreSql\Generation\Tokenization\PgTokenizer packages/sql-faker/src/PostgreSql/Generation/Tokenization/PgTokenizer.php:31
- type SqlFaker\PostgreSql\Generation\Tokenization\PgTokenizer packages/sql-faker/src/PostgreSql/Generation/Tokenization/PgTokenizer.php:39