Forked from ShayCichocki/bnf-story-parser-fixed.php
Created
November 16, 2019 12:00
-
-
Save bubach/4a8638f0904b9d064518bbdade78d339 to your computer and use it in GitHub Desktop.
BNF form parser, exampled with story generating bnf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class BNFParserGenerator { | |
| private $defs = []; | |
| /** | |
| * This converts the BNF string into a set of generator definitions | |
| * that we can use later | |
| * @param string $string | |
| */ | |
| public function parseString(string $string) { | |
| $string = str_replace("\\n", 'NEW_LINE', $string); | |
| $split = array_filter(explode("\n", $string)); | |
| $exploded = array_map(function($gen) { | |
| $gen = str_replace("NEW_LINE", "\n", $gen); | |
| return explode("::=", trim($gen)); | |
| }, $split); | |
| foreach ($exploded as $item) { | |
| $matches = []; | |
| preg_match('/<([A-z\-]+)>/', $item[0], $matches); | |
| $generators = explode("|", $item[1]); | |
| $generators = array_map(function($gen) { | |
| return trim($gen); | |
| }, $generators); | |
| $this->defs[$matches[1]] = $generators; | |
| } | |
| } | |
| /** | |
| * This creates whole new strings based on the grammar | |
| * @param string $startGeneratorName | |
| * @return string | |
| */ | |
| public function generateString(string $startGeneratorName): string { | |
| if(!isset($this->defs[$startGeneratorName])) { | |
| return 'Generator Doesnt Exist'; | |
| } | |
| //get a random key from the set of tokens that the generator can make | |
| $key = array_rand($this->defs[$startGeneratorName]); | |
| $phrase = $this->defs[$startGeneratorName][$key]; | |
| //regex to potentially find replaceable elements in the selected token | |
| $re = '/(?<!\\\\)<(.*?)(?<!\\\\)>/'; | |
| //Does a callback on all regex matches and replaces them with the generator | |
| //aka recurse recurse | |
| $result = preg_replace_callback($re, function($match) { | |
| return $this->generateString($match[1]); | |
| }, $phrase); | |
| //dont need this and could fix grammar to not have '' but pfft | |
| $result = str_replace("'", "", $result); | |
| return $result; | |
| } | |
| } | |
| $bnfString = " | |
| <plot> ::= <plot-point>. <plot> | <plot-point>. <transition><plot-point>.<plot> | <plot-point>. | |
| <plot-point> ::= <char-action><necessities><character><about> | <char-action> | |
| <char-action> ::= <character><action><about> | |
| <necessities> ::= '-' | '->' | <about> | '+' | '*' | |
| <action> ::= '1' | '2' | '3' | '4' |'5' | '' | |
| <about> ::= [<character>] | [<character>+<character>] | '' | |
| <character> ::= 'A'|'B'|'C'|'D'|'E'|'Z' | |
| <transition> ::= '\\n=\\n' | '\\n...\\n' | '' | |
| "; | |
| $parser = new BNFParserGenerator(); | |
| $parser->parseString($bnfString); | |
| $result = ''; | |
| echo $parser->generateString('plot')."\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment