classGrammarBuilder
final class GrammarBuilder
Collects the declarations of a grammar source and numbers them into a grammar.
Readers meet symbols in whatever order the source spells them, so names are gathered first and numbered only when the grammar is built: terminals in declaration order after the end marker, then the accept symbol and the nonterminals in the order their rules appear.
Constants§
public const ACCEPT = '$accept'The name of the nonterminal the augmented start rule derives.
Methods§
public function terminal(string $name): voidDeclares a terminal, keeping the position of its first declaration.
Parameters
$name | string | Terminal name |
Test cases 30
ClosureIndexTest::testEmptyRulescallsClosureIndexTest::testReachablecallsClosureIndexTest::testStartsWithcallsLookaheadSetsTest::testOfFollowsTheTextbookGrammarcallsLookaheadSetsTest::testOfReadsThroughNullableNonterminalscallsLookaheadSetsTest::testReadscallsLr0BuilderTest::testBuildCompletesEmptyRulesInTheClosurecallsLr0BuilderTest::testBuildDiscoversEveryStateOfTheTextbookGrammarcallsNullableSetTest::testIsNullablecallsNullableSetTest::testTailNullablecallsParseTableBuilderTest::testBuildCountsConflictsItSettlesByDefaultcallsParseTableBuilderTest::testBuildKeepsReductionsExplicitWhereTheWildcardActscallsParseTableBuilderTest::testBuildMakesANonAssociativeOperatorAnErrorcallsParseTableBuilderTest::testBuildSettlesAnAmbiguousGrammarWithPrecedencecallsBisonGrammarReaderTest::testAlternativecallsGrammarBuilderTest::testBuildAugmentsTheGrammarcallsGrammarBuilderTest::testBuildNumbersHiddenRulesWithoutOrdinalscallsGrammarBuilderTest::testBuildRejectsANameThatIsBothTerminalAndNonterminalcallsGrammarBuilderTest::testBuildResolvesThePrecedenceSymbolOfARulecallsGrammarBuilderTest::testFirstVisibleLhscallsGrammarBuilderTest::testNumberedRulescallsGrammarBuilderTest::testRulecallsGrammarBuilderTest::testStartcallsGrammarBuilderTest::testTerminalcallsLrParserTest::testExpectedcallsLrParserTest::testParseBuildsATreeNamedAfterTheRulescallsLrParserTest::testParseGivesTheTreeTheTextThatFollowsTheLastTokencallsLrParserTest::testParseLeavesMidRuleActionsOutOfTheTreecallsLrParserTest::testParseRejectsAnUnexpectedTokencallsLrParserTest::testParseSuppliesTheEndMarkerWhenTheStreamLacksItcalls
Called from 10
- method-call SqlParser\Compiler\BisonGrammarReader::read() packages/sql-parser/src/Compiler/BisonGrammarReader.php:75
- method-call SqlParser\Compiler\BisonGrammarReader::declaration() packages/sql-parser/src/Compiler/BisonGrammarReader.php:105
- method-call SqlParser\Compiler\BisonGrammarReader::alternative() packages/sql-parser/src/Compiler/BisonGrammarReader.php:145
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:96
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:140
- method-call SqlParser\Grammar\GrammarBuilder::precedence() packages/sql-parser/src/Grammar/GrammarBuilder.php:135
- method-call SqlParser\Grammar\GrammarBuilder::tokenClass() packages/sql-parser/src/Grammar/GrammarBuilder.php:179
- method-call SqlParser\Grammar\GrammarBuilder::fallback() packages/sql-parser/src/Grammar/GrammarBuilder.php:192
- method-call SqlParser\Grammar\GrammarBuilder::fallback() packages/sql-parser/src/Grammar/GrammarBuilder.php:194
- method-call SqlParser\Grammar\GrammarBuilder::wildcard() packages/sql-parser/src/Grammar/GrammarBuilder.php:206
public function nonterminal(string $name): voidDeclares a nonterminal, keeping the position of its first declaration.
Parameters
$name | string | Nonterminal name |
Test cases 1
Called from 1
public function isTerminal(string $name): boolReports whether a name has been declared as a terminal.
Parameters
$name | string | Symbol name |
Returns
bool True when the name is a terminal or a token classTest cases 6
Called from 3
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:137
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:139
- method-call SqlParser\Grammar\GrammarBuilder::build() packages/sql-parser/src/Grammar/GrammarBuilder.php:224
public function isNonterminal(string $name): boolReports whether a name has been declared as a nonterminal.
Parameters
$name | string | Symbol name |
Returns
bool True when a rule derives the nameTest cases 3
public function rule(
string $lhs,
list<string> $rhs,
string|null $precedenceSymbol = null,
bool $hidden = false,
): voidRecords one production.
The left-hand side becomes a nonterminal; right-hand names are resolved when the grammar is built, so they may be declared later.
Parameters
$lhs | string | Nonterminal the rule derives |
$rhs | list<string> | Symbol names the rule expands to |
$precedenceSymbol | string|null | Terminal named to lend its precedence |
$hidden | bool | Whether the rule stands in for a mid-rule action |
Test cases 40
ClosureIndexTest::testEmptyRulescallsClosureIndexTest::testReachablecallsClosureIndexTest::testStartsWithcallsLookaheadSetsTest::testOfFollowsTheTextbookGrammarcallsLookaheadSetsTest::testOfReadsThroughNullableNonterminalscallsLookaheadSetsTest::testReadscallsLr0BuilderTest::testBuildCompletesEmptyRulesInTheClosurecallsLr0BuilderTest::testBuildDiscoversEveryStateOfTheTextbookGrammarcallsNullableSetTest::testIsNullablecallsNullableSetTest::testTailNullablecallsParseTableBuilderTest::testBuildCountsConflictsItSettlesByDefaultcallsParseTableBuilderTest::testBuildKeepsReductionsExplicitWhereTheWildcardActscallsParseTableBuilderTest::testBuildMakesANonAssociativeOperatorAnErrorcallsParseTableBuilderTest::testBuildSettlesAnAmbiguousGrammarWithPrecedencecallsParseTableBuilderTest::testBuildSpellsTokenClassesOutToTheirMemberscallsBisonGrammarReaderTest::testDeclarationcallsBisonGrammarReaderTest::testMidRulecallsLemonGrammarReaderTest::testDeclarationcallsGrammarBuilderTest::testBuildAugmentsTheGrammarcallsGrammarBuilderTest::testBuildNumbersHiddenRulesWithoutOrdinalscallsGrammarBuilderTest::testBuildRejectsANameThatIsBothTerminalAndNonterminalcallsGrammarBuilderTest::testBuildRejectsAnUndeclaredSymbolcallsGrammarBuilderTest::testBuildResolvesThePrecedenceSymbolOfARulecallsGrammarBuilderTest::testExpectcallsGrammarBuilderTest::testFallbackcallsGrammarBuilderTest::testFirstVisibleLhscallsGrammarBuilderTest::testIsNonterminalcallsGrammarBuilderTest::testNumberedRulescallsGrammarBuilderTest::testPolicycallsGrammarBuilderTest::testPrecedencecallsGrammarBuilderTest::testRulecallsGrammarBuilderTest::testStartcallsGrammarBuilderTest::testTokenClasscallsGrammarBuilderTest::testWildcardcallsLrParserTest::testExpectedcallsLrParserTest::testParseBuildsATreeNamedAfterTheRulescallsLrParserTest::testParseGivesTheTreeTheTextThatFollowsTheLastTokencallsLrParserTest::testParseLeavesMidRuleActionsOutOfTheTreecallsLrParserTest::testParseRejectsAnUnexpectedTokencallsLrParserTest::testParseSuppliesTheEndMarkerWhenTheStreamLacksItcalls
Called from 3
- method-call SqlParser\Compiler\BisonGrammarReader::alternative() packages/sql-parser/src/Compiler/BisonGrammarReader.php:154
- method-call SqlParser\Compiler\BisonGrammarReader::midRule() packages/sql-parser/src/Compiler/BisonGrammarReader.php:186
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:144
Calls 1
- method-call GrammarBuilder::nonterminal() line 121
public function precedence(list<string> $names, Associativity $associativity): voidRecords one precedence declaration, ranking above every earlier one.
Parameters
$names | list<string> | Terminals the declaration ranks |
$associativity | Associativity | How ties within the rank are settled |
Test cases 5
ParseTableBuilderTest::testBuildMakesANonAssociativeOperatorAnErrorcallsParseTableBuilderTest::testBuildSettlesAnAmbiguousGrammarWithPrecedencecallsGrammarBuilderTest::testBuildResolvesThePrecedenceSymbolOfARulecallsGrammarBuilderTest::testPrecedencecallsLrParserTest::testParseBuildsATreeNamedAfterTheRulescalls
Called from 2
Calls 2
- method-call GrammarBuilder::terminal() line 135
- new Precedence line 136
public function start(string $name): voidNames the start symbol; the first rule's left-hand side is used otherwise.
Parameters
$name | string | Nonterminal to start from |
Test cases 1
public function expect(int $count): voidRecords how many shift/reduce conflicts the source declares as expected.
Parameters
$count | int | Declared conflict count |
Test cases 1
public function policy(PrecedencePolicy $policy): voidChooses how an unranked rule borrows its precedence.
Parameters
$policy | PrecedencePolicy | The generator's convention |
Test cases 4
public function tokenClass(string $name, list<string> $members): voidDeclares a token class, a terminal that stands for any of its members.
Parameters
$name | string | Class name |
$members | list<string> | Terminals the class stands for |
Test cases 3
Called from 2
Calls 1
- method-call GrammarBuilder::terminal() line 179
public function fallback(string $target, list<string> $names): voidDeclares which terminal to retry with when a listed terminal cannot be used.
Parameters
$target | string | Terminal to fall back to |
$names | list<string> | Terminals that fall back |
Test cases 1
Called from 1
Calls 1
- method-call GrammarBuilder::terminal() line 192
public function wildcard(string $name): voidDeclares the terminal that stands for any other.
Parameters
$name | string | Wildcard terminal name |
Test cases 2
Called from 1
Calls 1
- method-call GrammarBuilder::terminal() line 206
public function build(): GrammarNumbers everything collected and answers the augmented grammar.
Returns
Grammar The grammarThrows
GrammarException When no rule was recorded or a name is both a terminal and a nonterminalUnknownSymbolException When a rule names a symbol nothing declaresTest cases 41
ClosureIndexTest::testEmptyRulescallsClosureIndexTest::testReachablecallsClosureIndexTest::testStartsWithcallsLookaheadSetsTest::testOfFollowsTheTextbookGrammarcallsLookaheadSetsTest::testOfReadsThroughNullableNonterminalscallsLookaheadSetsTest::testReadscallsLr0BuilderTest::testBuildCompletesEmptyRulesInTheClosurecallsLr0BuilderTest::testBuildDiscoversEveryStateOfTheTextbookGrammarcallsNullableSetTest::testIsNullablecallsNullableSetTest::testTailNullablecallsParseTableBuilderTest::testBuildCountsConflictsItSettlesByDefaultcallsParseTableBuilderTest::testBuildKeepsReductionsExplicitWhereTheWildcardActscallsParseTableBuilderTest::testBuildMakesANonAssociativeOperatorAnErrorcallsParseTableBuilderTest::testBuildSettlesAnAmbiguousGrammarWithPrecedencecallsParseTableBuilderTest::testBuildSpellsTokenClassesOutToTheirMemberscallsBisonGrammarReaderTest::testAlternativecallsBisonGrammarReaderTest::testDeclarationcallsBisonGrammarReaderTest::testMidRulecallsLemonGrammarReaderTest::testDeclarationcallsLemonGrammarReaderTest::testRulecallsGrammarBuilderTest::testBuildAugmentsTheGrammarcallsGrammarBuilderTest::testBuildNumbersHiddenRulesWithoutOrdinalscallsGrammarBuilderTest::testBuildRejectsANameThatIsBothTerminalAndNonterminalcallsGrammarBuilderTest::testBuildRejectsAnEmptyGrammarcallsGrammarBuilderTest::testBuildRejectsAnUndeclaredSymbolcallsGrammarBuilderTest::testBuildResolvesThePrecedenceSymbolOfARulecallsGrammarBuilderTest::testExpectcallsGrammarBuilderTest::testFallbackcallsGrammarBuilderTest::testFirstVisibleLhscallsGrammarBuilderTest::testPolicycallsGrammarBuilderTest::testPrecedencecallsGrammarBuilderTest::testRulecallsGrammarBuilderTest::testStartcallsGrammarBuilderTest::testTokenClasscallsGrammarBuilderTest::testWildcardcallsLrParserTest::testExpectedcallsLrParserTest::testParseBuildsATreeNamedAfterTheRulescallsLrParserTest::testParseGivesTheTreeTheTextThatFollowsTheLastTokencallsLrParserTest::testParseLeavesMidRuleActionsOutOfTheTreecallsLrParserTest::testParseRejectsAnUnexpectedTokencallsLrParserTest::testParseSuppliesTheEndMarkerWhenTheStreamLacksItcalls
Called from 2
Calls 12
- new GrammarException line 221
- function-call
array_keysline 223 - method-call GrammarBuilder::isTerminal() line 224
- new SymbolTable line 228
- class-const SymbolTable::END() line 229
- class-const GrammarBuilder::ACCEPT() line 230
- method-call GrammarBuilder::firstVisibleLhs() line 232
- new Rule line 233
- method-call GrammarBuilder::id() line 233
- method-call GrammarBuilder::numberedRules() line 234
- function-call
array_mapline 243 - new Grammar line 250
public function numberedRules(SymbolTable $symbols): list<Rule>Numbers the recorded rules after the augmented start rule.
Parameters
$symbols | SymbolTable | The numbering |
Returns
list<Rule> Rules numbered from one, alternatives counted per nonterminalThrows
UnknownSymbolException When a rule names a symbol nothing declaresTest cases 1
Called from 1
public function firstVisibleLhs(): stringAnswers the left-hand side of the first rule that was not synthesised.
A rule synthesised for a mid-rule action is numbered before the rule it appears in, so the first recorded rule is not always the first rule the source wrote.
Returns
string Nonterminal of the first rule as writtenTest cases 1
Called from 1
public function id(SymbolTable $symbols, string $name): intResolves a name against the numbered symbols.
Parameters
$symbols | SymbolTable | The numbering |
$name | string | Symbol name |
Returns
int The symbol numberThrows
UnknownSymbolException When nothing declares the nameTest cases 2
Called from 8
- method-call SqlParser\Grammar\GrammarBuilder::build() packages/sql-parser/src/Grammar/GrammarBuilder.php:233
- method-call SqlParser\Grammar\GrammarBuilder::build() packages/sql-parser/src/Grammar/GrammarBuilder.php:239
- method-call SqlParser\Grammar\GrammarBuilder::build() packages/sql-parser/src/Grammar/GrammarBuilder.php:243
- method-call SqlParser\Grammar\GrammarBuilder::build() packages/sql-parser/src/Grammar/GrammarBuilder.php:247
- method-call SqlParser\Grammar\GrammarBuilder::build() packages/sql-parser/src/Grammar/GrammarBuilder.php:258
- method-call SqlParser\Grammar\GrammarBuilder::numberedRules() packages/sql-parser/src/Grammar/GrammarBuilder.php:276
- method-call SqlParser\Grammar\GrammarBuilder::numberedRules() packages/sql-parser/src/Grammar/GrammarBuilder.php:284
- method-call SqlParser\Grammar\GrammarBuilder::numberedRules() packages/sql-parser/src/Grammar/GrammarBuilder.php:287
Calls 2
- method-call SymbolTable::id() line 326
- new UnknownSymbolException line 328
Private surface 11§
Implementation details, listed for orientation only.
private array<string, true> $terminals = []private array<string, true> $nonterminals = []private list<array{string, list<string>, string|null, bool}> $rules = []private array<string, Precedence> $precedences = []private int $level = 0private ?string $start = nullprivate ?int $expectedConflicts = nullprivate PrecedencePolicy $policy = PrecedencePolicy::LastTerminalprivate array<string, list<string>> $tokenClasses = []private array<string, string> $fallbacks = []private ?string $wildcard = nullTest cases 48§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 22
GrammarBuilderTest::testBuildAugmentsTheGrammarcallsGrammarBuilderTest::testBuildNumbersHiddenRulesWithoutOrdinalscallsGrammarBuilderTest::testBuildRejectsANameThatIsBothTerminalAndNonterminalcallsGrammarBuilderTest::testBuildRejectsAnEmptyGrammarcallsGrammarBuilderTest::testBuildRejectsAnUndeclaredSymbolcallsGrammarBuilderTest::testBuildResolvesThePrecedenceSymbolOfARulecallsGrammarBuilderTest::testExpectcallsGrammarBuilderTest::testFallbackcallsGrammarBuilderTest::testFirstVisibleLhscallsGrammarBuilderTest::testIdcallsGrammarBuilderTest::testIdRejectsAnUnknownNamecallsGrammarBuilderTest::testIsNonterminalcallsGrammarBuilderTest::testIsTerminalCountsTokenClassescallsGrammarBuilderTest::testNonterminalcallsGrammarBuilderTest::testNumberedRulescallsGrammarBuilderTest::testPolicycallsGrammarBuilderTest::testPrecedencecallsGrammarBuilderTest::testRulecallsGrammarBuilderTest::testStartcallsGrammarBuilderTest::testTerminalcallsGrammarBuilderTest::testTokenClasscallsGrammarBuilderTest::testWildcardcalls
Other tests reaching this symbol 26
ClosureIndexTest::testEmptyRulescallsClosureIndexTest::testReachablecallsClosureIndexTest::testStartsWithcallsLookaheadSetsTest::testOfFollowsTheTextbookGrammarcallsLookaheadSetsTest::testOfReadsThroughNullableNonterminalscallsLookaheadSetsTest::testReadscallsLr0BuilderTest::testBuildCompletesEmptyRulesInTheClosurecallsLr0BuilderTest::testBuildDiscoversEveryStateOfTheTextbookGrammarcallsNullableSetTest::testIsNullablecallsNullableSetTest::testTailNullablecallsParseTableBuilderTest::testBuildCountsConflictsItSettlesByDefaultcallsParseTableBuilderTest::testBuildKeepsReductionsExplicitWhereTheWildcardActscallsParseTableBuilderTest::testBuildMakesANonAssociativeOperatorAnErrorcallsParseTableBuilderTest::testBuildSettlesAnAmbiguousGrammarWithPrecedencecallsParseTableBuilderTest::testBuildSpellsTokenClassesOutToTheirMemberscallsBisonGrammarReaderTest::testAlternativecallsBisonGrammarReaderTest::testDeclarationcallsBisonGrammarReaderTest::testMidRulecallsLemonGrammarReaderTest::testDeclarationcallsLemonGrammarReaderTest::testRulecallsLrParserTest::testExpectedcallsLrParserTest::testParseBuildsATreeNamedAfterTheRulescallsLrParserTest::testParseGivesTheTreeTheTextThatFollowsTheLastTokencallsLrParserTest::testParseLeavesMidRuleActionsOutOfTheTreecallsLrParserTest::testParseRejectsAnUnexpectedTokencallsLrParserTest::testParseSuppliesTheEndMarkerWhenTheStreamLacksItcalls
Relations§
Instantiated in 2
Method calls 23
- method-call SqlParser\Compiler\BisonGrammarReader::read() packages/sql-parser/src/Compiler/BisonGrammarReader.php:74
- method-call SqlParser\Compiler\BisonGrammarReader::read() packages/sql-parser/src/Compiler/BisonGrammarReader.php:75
- method-call SqlParser\Compiler\BisonGrammarReader::read() packages/sql-parser/src/Compiler/BisonGrammarReader.php:86
- method-call SqlParser\Compiler\BisonGrammarReader::declaration() packages/sql-parser/src/Compiler/BisonGrammarReader.php:102
- method-call SqlParser\Compiler\BisonGrammarReader::declaration() packages/sql-parser/src/Compiler/BisonGrammarReader.php:105
- method-call SqlParser\Compiler\BisonGrammarReader::declaration() packages/sql-parser/src/Compiler/BisonGrammarReader.php:108
- method-call SqlParser\Compiler\BisonGrammarReader::declaration() packages/sql-parser/src/Compiler/BisonGrammarReader.php:110
- method-call SqlParser\Compiler\BisonGrammarReader::alternative() packages/sql-parser/src/Compiler/BisonGrammarReader.php:145
- method-call SqlParser\Compiler\BisonGrammarReader::alternative() packages/sql-parser/src/Compiler/BisonGrammarReader.php:154
- method-call SqlParser\Compiler\BisonGrammarReader::midRule() packages/sql-parser/src/Compiler/BisonGrammarReader.php:186
- method-call SqlParser\Compiler\LemonGrammarReader::read() packages/sql-parser/src/Compiler/LemonGrammarReader.php:72
- method-call SqlParser\Compiler\LemonGrammarReader::read() packages/sql-parser/src/Compiler/LemonGrammarReader.php:81
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:93
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:96
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:99
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:101
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:103
- method-call SqlParser\Compiler\LemonGrammarReader::declaration() packages/sql-parser/src/Compiler/LemonGrammarReader.php:105
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:137
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:138
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:139
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:140
- method-call SqlParser\Compiler\LemonGrammarReader::rule() packages/sql-parser/src/Compiler/LemonGrammarReader.php:144
Type declarations 5
- type SqlParser\Compiler\BisonGrammarReader packages/sql-parser/src/Compiler/BisonGrammarReader.php:95
- type SqlParser\Compiler\BisonGrammarReader packages/sql-parser/src/Compiler/BisonGrammarReader.php:138
- type SqlParser\Compiler\BisonGrammarReader packages/sql-parser/src/Compiler/BisonGrammarReader.php:183
- type SqlParser\Compiler\LemonGrammarReader packages/sql-parser/src/Compiler/LemonGrammarReader.php:90
- type SqlParser\Compiler\LemonGrammarReader packages/sql-parser/src/Compiler/LemonGrammarReader.php:131