Files
san-reymoros/vendor/s9e/regexp-builder/src/Builder.php
2020-03-31 15:31:03 +02:00

167 lines
3.8 KiB
PHP

<?php
/**
* @package s9e\RegexpBuilder
* @copyright Copyright (c) 2016-2018 The s9e Authors
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace s9e\RegexpBuilder;
use s9e\RegexpBuilder\Input\InputInterface;
use s9e\RegexpBuilder\Output\OutputInterface;
use s9e\RegexpBuilder\Passes\CoalesceOptionalStrings;
use s9e\RegexpBuilder\Passes\CoalesceSingleCharacterPrefix;
use s9e\RegexpBuilder\Passes\GroupSingleCharacters;
use s9e\RegexpBuilder\Passes\MergePrefix;
use s9e\RegexpBuilder\Passes\MergeSuffix;
use s9e\RegexpBuilder\Passes\PromoteSingleStrings;
use s9e\RegexpBuilder\Passes\Recurse;
class Builder
{
/**
* @var InputInterface
*/
protected $input;
/**
* @var MetaCharacters
*/
protected $meta;
/**
* @var Runner
*/
protected $runner;
/**
* @var Serializer
*/
protected $serializer;
/**
* @param array $config
*/
public function __construct(array $config = [])
{
$config += [
'delimiter' => '/',
'input' => 'Bytes',
'inputOptions' => [],
'meta' => [],
'output' => 'Bytes',
'outputOptions' => []
];
$this->setInput($config['input'], $config['inputOptions']);
$this->setMeta($config['meta']);
$this->setSerializer($config['output'], $config['outputOptions'], $config['delimiter']);
$this->setRunner();
}
/**
* Build and return a regular expression that matches all of the given strings
*
* @param string[] $strings Literal strings to be matched
* @return string Regular expression (without delimiters)
*/
public function build(array $strings)
{
$strings = array_unique($strings);
sort($strings);
if ($this->isEmpty($strings))
{
return '';
}
$strings = $this->splitStrings($strings);
$strings = $this->meta->replaceMeta($strings);
$strings = $this->runner->run($strings);
return $this->serializer->serializeStrings($strings);
}
/**
* Test whether the list of strings is empty
*
* @param string[] $strings
* @return bool
*/
protected function isEmpty(array $strings)
{
return (empty($strings) || $strings === ['']);
}
/**
* Set the InputInterface instance in $this->input
*
* @param string $inputType
* @param array $inputOptions
* @return void
*/
protected function setInput($inputType, array $inputOptions)
{
$className = __NAMESPACE__ . '\\Input\\' . $inputType;
$this->input = new $className($inputOptions);
}
/**
* Set the MetaCharacters instance in $this->meta
*
* @param array $map
* @return void
*/
protected function setMeta(array $map)
{
$this->meta = new MetaCharacters($this->input);
foreach ($map as $char => $expr)
{
$this->meta->add($char, $expr);
}
}
/**
* Set the Runner instance $in this->runner
*
* @return void
*/
protected function setRunner()
{
$this->runner = new Runner;
$this->runner->addPass(new MergePrefix);
$this->runner->addPass(new GroupSingleCharacters);
$this->runner->addPass(new Recurse($this->runner));
$this->runner->addPass(new PromoteSingleStrings);
$this->runner->addPass(new CoalesceOptionalStrings);
$this->runner->addPass(new MergeSuffix);
$this->runner->addPass(new CoalesceSingleCharacterPrefix);
}
/**
* Set the Serializer instance in $this->serializer
*
* @param string $outputType
* @param array $outputOptions
* @param string $delimiter
* @return void
*/
protected function setSerializer($outputType, array $outputOptions, $delimiter)
{
$className = __NAMESPACE__ . '\\Output\\' . $outputType;
$output = new $className($outputOptions);
$escaper = new Escaper($delimiter);
$this->serializer = new Serializer($output, $this->meta, $escaper);
}
/**
* Split all given strings by character
*
* @param string[] $strings List of strings
* @return array[] List of arrays
*/
protected function splitStrings(array $strings)
{
return array_map([$this->input, 'split'], $strings);
}
}