Skip to content

Instantly share code, notes, and snippets.

@ShayCichocki
Created October 24, 2017 00:59
Show Gist options
  • Save ShayCichocki/14af354dbc8b70f26d0be22d74ac8150 to your computer and use it in GitHub Desktop.
Save ShayCichocki/14af354dbc8b70f26d0be22d74ac8150 to your computer and use it in GitHub Desktop.
Bnf parser and story generator
<?php
class BNFParser {
private $unparsedString;
private $defs = [];
public function __construct(string $bnfString = null)
{
$this->unparsedString = $bnfString;
if($this->unparsedString) {
$this->parseString($bnfString);
}
}
public function parseString($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;
}
}
public function getRandomWeightedElement(array $weightedValues) {
$rand = mt_rand(1, (int) array_sum($weightedValues));
foreach ($weightedValues as $key => $value) {
$rand -= $value;
if ($rand <= 0) {
return $key;
}
}
return null;
}
public function generateString(string $startGeneratorName): string {
if(!isset($this->defs[$startGeneratorName])) {
return 'Generator Doesnt Exist';
}
$key = array_rand($this->defs[$startGeneratorName]);
$phrase = $this->defs[$startGeneratorName][$key];
$re = '/(?<!\\\\)<(.*?)(?<!\\\\)>/';
$result = preg_replace_callback($re, function($match) {
return $this->generateString($match[1]);
}, $phrase);
$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 BNFParser();
$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