classLemonGrammarCompiler
final class LemonGrammarCompiler
@visibility public.Turns a Lemon grammar file into the grammar the generators walk.
The file is read with lemon-parser after its %ifdef regions are settled; this class keeps what generation needs. A position shared by several terminals, A|B, is spelled out into one alternative per terminal, a %token_class becomes a rule with one alternative per member, and the first rule is the start symbol. A name written in capitals, digits and underscores is a terminal, as is the %wildcard token whatever its spelling; every other name is a nonterminal.
$grammar = (new \SqlFaker\Compiler\Lemon\LemonGrammarCompiler())->compile("%token_class id ID|INDEXED.\nexpr(A) ::= expr(B) PLUS|MINUS term(C). { A = B + C; }\nexpr ::= term.\nterm ::= NUM.\nterm ::= id.\n");
[$grammar->startSymbol, array_keys($grammar->ruleMap), count($grammar->ruleMap['expr']->alternatives)] // => ['expr', ['expr', 'term', 'id'], 3]Methods§
public function __construct(private Parser $parser = new \LemonParser\Parser())public function compile(string $source, list<string> $defines = []): GrammarCompiles a grammar file.
Parameters
$source | string | The text of the `.y` file |
$defines | list<string> | Names defined for `%ifdef`, as Lemon's `-D` option defines them |
Returns
Grammar The grammarThrows
SyntaxException When the file is not a grammar Lemon acceptsGrammarParseException When the file defines no ruleTest cases 3
Calls 11
- method-call Parser::parse() line 60
- static-call GrammarParseException::noRulesParsed() line 63
- method-call LemonGrammarCompiler::terminals() line 65
- function-call
array_mergeline 69 - method-call LemonGrammarCompiler::expand() line 69
- new Production line 75
- function-call
array_mapline 75 - new Terminal line 75
- new NonTerminal line 75
- new ProductionRule line 77
- new Grammar line 85
public function expand(Rule $rule): list<list<string>>Spells out a rule's shared positions into one sequence of names per combination.
Parameters
$rule | Rule | The rule |
Returns
list<list<string>> The sequences, the first terminal of each position firstTest cases 1
public function terminals(GrammarFile $file): array<string, true>Decides which names are terminals: those spelled as tokens, and the wildcard whatever its spelling.
Parameters
$file | GrammarFile | The tree |
Returns
array<string, true> The terminal namesTest cases 1
Called from 1
Calls 3
- method-call GrammarFile::declarations() line 121
- method-call GrammarFile::rules() line 126
- static-call LemonGrammarCompiler::isTokenName() line 128
public static function isTokenName(string $name): boolReports whether a name is spelled as a token: capitals, digits and underscores, starting with a capital.
Parameters
$name | string | The name |
Returns
bool True for a token spellingTest cases 1
Called from 1
Calls 1
- function-call
preg_matchline 146
Private surface 1§
Implementation details, listed for orientation only.
private Parser $parser = new \LemonParser\Parser()Test cases 6§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 6
LemonGrammarCompilerTest::testCompilecallsLemonGrammarCompilerTest::testCompileRejectsAFileWithoutRulescallsLemonGrammarCompilerTest::testCompileSettlesConditionalRegionscallsLemonGrammarCompilerTest::testExpandcallsLemonGrammarCompilerTest::testIsTokenNamecallsLemonGrammarCompilerTest::testTerminalscalls