Completed
Push — master ( 95e794...553f1a )
by Josh
04:13
created
src/Serializer.php 1 patch
Indentation   +198 added lines, -198 removed lines patch added patch discarded remove patch
@@ -11,202 +11,202 @@
 block discarded – undo
11 11
 
12 12
 class Serializer
13 13
 {
14
-	/**
15
-	* @var Escaper
16
-	*/
17
-	protected $escaper;
18
-
19
-	/**
20
-	* @var OutputInterface
21
-	*/
22
-	protected $output;
23
-
24
-	/**
25
-	* @param OutputInterface $output
26
-	* @param Escaper         $escaper
27
-	*/
28
-	public function __construct(OutputInterface $output, Escaper $escaper)
29
-	{
30
-		$this->escaper = $escaper;
31
-		$this->output  = $output;
32
-	}
33
-
34
-	/**
35
-	* Serialize given strings into a regular expression
36
-	*
37
-	* @param  array[] $strings
38
-	* @return string
39
-	*/
40
-	public function serializeStrings(array $strings)
41
-	{
42
-		$info = $this->analyzeStrings($strings);
43
-		$alternations = $this->buildAlternations($info);
44
-		$expr = implode('|', $alternations);
45
-
46
-		if (count($alternations) > 1 || $this->isOneOptionalString($info))
47
-		{
48
-			$expr = '(?:' . $expr . ')';
49
-		}
50
-
51
-		return $expr . $info['quantifier'];
52
-	}
53
-
54
-	/**
55
-	* Analyze given strings to determine how to serialize them
56
-	*
57
-	* The returned array may contains any of the following elements:
58
-	*
59
-	*  - (string) quantifier Either '' or '?'
60
-	*  - (array)  chars      List of values from single-char strings
61
-	*  - (array)  strings    List of multi-char strings
62
-	*
63
-	* @param  array[] $strings
64
-	* @return array
65
-	*/
66
-	protected function analyzeStrings(array $strings)
67
-	{
68
-		$info = ['quantifier' => ''];
69
-		if ($strings[0] === [])
70
-		{
71
-			$info['quantifier'] = '?';
72
-			unset($strings[0]);
73
-		}
74
-
75
-		$chars = $this->getChars($strings);
76
-		if (count($chars) > 1)
77
-		{
78
-			$info['chars'] = array_values($chars);
79
-			$strings = array_diff_key($strings, $chars);
80
-		}
81
-
82
-		$info['strings'] = array_values($strings);
83
-
84
-		return $info;
85
-	}
86
-
87
-	/**
88
-	* Build the list of alternations based on given info
89
-	*
90
-	* @param  array    $info
91
-	* @return string[]
92
-	*/
93
-	protected function buildAlternations(array $info)
94
-	{
95
-		$alternations = [];
96
-		if (!empty($info['chars']))
97
-		{
98
-			$alternations[] = $this->serializeCharacterClass($info['chars']);
99
-		}
100
-		foreach ($info['strings'] as $string)
101
-		{
102
-			$alternations[] = $this->serializeString($string);
103
-		}
104
-
105
-		return $alternations;
106
-	}
107
-
108
-	/**
109
-	* Return the portion of strings that are composed of a single character
110
-	*
111
-	* @param  array[]
112
-	* @return array   String key => codepoint
113
-	*/
114
-	protected function getChars(array $strings)
115
-	{
116
-		$chars = [];
117
-		foreach ($strings as $k => $string)
118
-		{
119
-			if (count($string) === 1)
120
-			{
121
-				$chars[$k] = $string[0];
122
-			}
123
-		}
124
-
125
-		return $chars;
126
-	}
127
-
128
-	/**
129
-	* Get the list of ranges that cover all given values
130
-	*
131
-	* @param  integer[] $values Ordered list of values
132
-	* @return array[]           List of ranges in the form [start, end]
133
-	*/
134
-	protected function getRanges(array $values)
135
-	{
136
-		$i      = 0;
137
-		$cnt    = count($values);
138
-		$start  = $values[0];
139
-		$end    = $start;
140
-		$ranges = [];
141
-		while (++$i < $cnt)
142
-		{
143
-			if ($values[$i] === $end + 1)
144
-			{
145
-				++$end;
146
-			}
147
-			else
148
-			{
149
-				$ranges[] = [$start, $end];
150
-				$start = $end = $values[$i];
151
-			}
152
-		}
153
-		$ranges[] = [$start, $end];
154
-
155
-		return $ranges;
156
-	}
157
-
158
-	/**
159
-	* Test whether a string is optional and has more than one character
160
-	*
161
-	* @param  array $info
162
-	* @return bool
163
-	*/
164
-	protected function isOneOptionalString(array $info)
165
-	{
166
-		// Test whether the first string has a quantifier and more than one element
167
-		return (!empty($info['quantifier']) && isset($info['strings'][0][1]));
168
-	}
169
-
170
-	/**
171
-	* Serialize a given list of values into a character class
172
-	*
173
-	* @param  integer[] $values
174
-	* @return string
175
-	*/
176
-	protected function serializeCharacterClass(array $values)
177
-	{
178
-		$expr = '[';
179
-		foreach ($this->getRanges($values) as list($start, $end))
180
-		{
181
-			$expr .= $this->escaper->escapeCharacterClass($this->output->output($start));
182
-			if ($end > $start)
183
-			{
184
-				if ($end > $start + 1)
185
-				{
186
-					$expr .= '-';
187
-				}
188
-				$expr .= $this->escaper->escapeCharacterClass($this->output->output($end));
189
-			}
190
-		}
191
-		$expr .= ']';
192
-
193
-		return $expr;
194
-	}
195
-
196
-	/**
197
-	* Serialize a given string into a regular expression
198
-	*
199
-	* @param  array  $string
200
-	* @return string
201
-	*/
202
-	protected function serializeString(array $string)
203
-	{
204
-		$expr = '';
205
-		foreach ($string as $element)
206
-		{
207
-			$expr .= (is_array($element)) ? $this->serializeStrings($element) : $this->escaper->escapeLiteral($this->output->output($element));
208
-		}
209
-
210
-		return $expr;
211
-	}
14
+    /**
15
+     * @var Escaper
16
+     */
17
+    protected $escaper;
18
+
19
+    /**
20
+     * @var OutputInterface
21
+     */
22
+    protected $output;
23
+
24
+    /**
25
+     * @param OutputInterface $output
26
+     * @param Escaper         $escaper
27
+     */
28
+    public function __construct(OutputInterface $output, Escaper $escaper)
29
+    {
30
+        $this->escaper = $escaper;
31
+        $this->output  = $output;
32
+    }
33
+
34
+    /**
35
+     * Serialize given strings into a regular expression
36
+     *
37
+     * @param  array[] $strings
38
+     * @return string
39
+     */
40
+    public function serializeStrings(array $strings)
41
+    {
42
+        $info = $this->analyzeStrings($strings);
43
+        $alternations = $this->buildAlternations($info);
44
+        $expr = implode('|', $alternations);
45
+
46
+        if (count($alternations) > 1 || $this->isOneOptionalString($info))
47
+        {
48
+            $expr = '(?:' . $expr . ')';
49
+        }
50
+
51
+        return $expr . $info['quantifier'];
52
+    }
53
+
54
+    /**
55
+     * Analyze given strings to determine how to serialize them
56
+     *
57
+     * The returned array may contains any of the following elements:
58
+     *
59
+     *  - (string) quantifier Either '' or '?'
60
+     *  - (array)  chars      List of values from single-char strings
61
+     *  - (array)  strings    List of multi-char strings
62
+     *
63
+     * @param  array[] $strings
64
+     * @return array
65
+     */
66
+    protected function analyzeStrings(array $strings)
67
+    {
68
+        $info = ['quantifier' => ''];
69
+        if ($strings[0] === [])
70
+        {
71
+            $info['quantifier'] = '?';
72
+            unset($strings[0]);
73
+        }
74
+
75
+        $chars = $this->getChars($strings);
76
+        if (count($chars) > 1)
77
+        {
78
+            $info['chars'] = array_values($chars);
79
+            $strings = array_diff_key($strings, $chars);
80
+        }
81
+
82
+        $info['strings'] = array_values($strings);
83
+
84
+        return $info;
85
+    }
86
+
87
+    /**
88
+     * Build the list of alternations based on given info
89
+     *
90
+     * @param  array    $info
91
+     * @return string[]
92
+     */
93
+    protected function buildAlternations(array $info)
94
+    {
95
+        $alternations = [];
96
+        if (!empty($info['chars']))
97
+        {
98
+            $alternations[] = $this->serializeCharacterClass($info['chars']);
99
+        }
100
+        foreach ($info['strings'] as $string)
101
+        {
102
+            $alternations[] = $this->serializeString($string);
103
+        }
104
+
105
+        return $alternations;
106
+    }
107
+
108
+    /**
109
+     * Return the portion of strings that are composed of a single character
110
+     *
111
+     * @param  array[]
112
+     * @return array   String key => codepoint
113
+     */
114
+    protected function getChars(array $strings)
115
+    {
116
+        $chars = [];
117
+        foreach ($strings as $k => $string)
118
+        {
119
+            if (count($string) === 1)
120
+            {
121
+                $chars[$k] = $string[0];
122
+            }
123
+        }
124
+
125
+        return $chars;
126
+    }
127
+
128
+    /**
129
+     * Get the list of ranges that cover all given values
130
+     *
131
+     * @param  integer[] $values Ordered list of values
132
+     * @return array[]           List of ranges in the form [start, end]
133
+     */
134
+    protected function getRanges(array $values)
135
+    {
136
+        $i      = 0;
137
+        $cnt    = count($values);
138
+        $start  = $values[0];
139
+        $end    = $start;
140
+        $ranges = [];
141
+        while (++$i < $cnt)
142
+        {
143
+            if ($values[$i] === $end + 1)
144
+            {
145
+                ++$end;
146
+            }
147
+            else
148
+            {
149
+                $ranges[] = [$start, $end];
150
+                $start = $end = $values[$i];
151
+            }
152
+        }
153
+        $ranges[] = [$start, $end];
154
+
155
+        return $ranges;
156
+    }
157
+
158
+    /**
159
+     * Test whether a string is optional and has more than one character
160
+     *
161
+     * @param  array $info
162
+     * @return bool
163
+     */
164
+    protected function isOneOptionalString(array $info)
165
+    {
166
+        // Test whether the first string has a quantifier and more than one element
167
+        return (!empty($info['quantifier']) && isset($info['strings'][0][1]));
168
+    }
169
+
170
+    /**
171
+     * Serialize a given list of values into a character class
172
+     *
173
+     * @param  integer[] $values
174
+     * @return string
175
+     */
176
+    protected function serializeCharacterClass(array $values)
177
+    {
178
+        $expr = '[';
179
+        foreach ($this->getRanges($values) as list($start, $end))
180
+        {
181
+            $expr .= $this->escaper->escapeCharacterClass($this->output->output($start));
182
+            if ($end > $start)
183
+            {
184
+                if ($end > $start + 1)
185
+                {
186
+                    $expr .= '-';
187
+                }
188
+                $expr .= $this->escaper->escapeCharacterClass($this->output->output($end));
189
+            }
190
+        }
191
+        $expr .= ']';
192
+
193
+        return $expr;
194
+    }
195
+
196
+    /**
197
+     * Serialize a given string into a regular expression
198
+     *
199
+     * @param  array  $string
200
+     * @return string
201
+     */
202
+    protected function serializeString(array $string)
203
+    {
204
+        $expr = '';
205
+        foreach ($string as $element)
206
+        {
207
+            $expr .= (is_array($element)) ? $this->serializeStrings($element) : $this->escaper->escapeLiteral($this->output->output($element));
208
+        }
209
+
210
+        return $expr;
211
+    }
212 212
 }
213 213
\ No newline at end of file
Please login to merge, or discard this patch.
src/Builder.php 1 patch
Indentation   +141 added lines, -141 removed lines patch added patch discarded remove patch
@@ -18,145 +18,145 @@
 block discarded – undo
18 18
 
19 19
 class Builder
20 20
 {
21
-	/**
22
-	* @var InputInterface
23
-	*/
24
-	protected $input;
25
-
26
-	/**
27
-	* @var Runner
28
-	*/
29
-	protected $runner;
30
-
31
-	/**
32
-	* @var Serializer
33
-	*/
34
-	protected $serializer;
35
-
36
-	/**
37
-	* @param array $config
38
-	*/
39
-	public function __construct(array $config = [])
40
-	{
41
-		$config += [
42
-			'delimiter' => '/',
43
-			'input'     => 'Bytes',
44
-			'output'    => 'Bytes'
45
-		];
46
-
47
-		$this->setInput($config['input']);
48
-		$this->setSerializer($config['output'], $config['delimiter']);
49
-		$this->setRunner();
50
-	}
51
-
52
-	/**
53
-	* Build and return a regular expression that matches all of the given strings
54
-	*
55
-	* @param  string[] $strings Literal strings to be matched
56
-	* @return string            Regular expression (without delimiters)
57
-	*/
58
-	public function build(array $strings)
59
-	{
60
-		$strings = array_unique($strings);
61
-		if ($this->isEmpty($strings))
62
-		{
63
-			return '';
64
-		}
65
-
66
-		$strings = $this->splitStrings($strings);
67
-		usort($strings, __CLASS__ . '::compareStrings');
68
-		$strings = $this->runner->run($strings);
69
-
70
-		return $this->serializer->serializeStrings($strings);
71
-	}
72
-
73
-	/**
74
-	* Compare two split strings
75
-	*
76
-	* Will sort strings in ascending order
77
-	*
78
-	* @param  integer[] $a
79
-	* @param  integer[] $b
80
-	* @return integer
81
-	*/
82
-	protected function compareStrings(array $a, array $b)
83
-	{
84
-		$i   = -1;
85
-		$cnt = min(count($a), count($b));
86
-		while (++$i < $cnt)
87
-		{
88
-			if ($a[$i] !== $b[$i])
89
-			{
90
-				return $a[$i] - $b[$i];
91
-			}
92
-		}
93
-
94
-		return count($a) - count($b);
95
-	}
96
-
97
-	/**
98
-	* Test whether the list of strings is empty
99
-	*
100
-	* @param  string[] $strings
101
-	* @return bool
102
-	*/
103
-	protected function isEmpty(array $strings)
104
-	{
105
-		return (empty($strings) || $strings === ['']);
106
-	}
107
-
108
-	/**
109
-	* Set the InputInterface instance in $this->input
110
-	*
111
-	* @param  string $inputType
112
-	* @return void
113
-	*/
114
-	protected function setInput($inputType)
115
-	{
116
-		$className   = __NAMESPACE__ . '\\Input\\' . $inputType;
117
-		$this->input = new $className;
118
-	}
119
-
120
-	/**
121
-	* Set the Runner instance $in this->runner
122
-	*
123
-	* @return void
124
-	*/
125
-	protected function setRunner()
126
-	{
127
-		$this->runner = new Runner;
128
-		$this->runner->addPass(new MergePrefix);
129
-		$this->runner->addPass(new GroupSingleCharacters);
130
-		$this->runner->addPass(new Recurse($this->runner));
131
-		$this->runner->addPass(new PromoteSingleStrings);
132
-		$this->runner->addPass(new MergeSuffix);
133
-		$this->runner->addPass(new CoalesceSingleCharacterPrefix);
134
-	}
135
-
136
-	/**
137
-	* Set the Serializer instance in $this->serializer
138
-	*
139
-	* @param  string $outputType
140
-	* @param  string $delimiter
141
-	* @return void
142
-	*/
143
-	protected function setSerializer($outputType, $delimiter)
144
-	{
145
-		$className = __NAMESPACE__ . '\\Output\\' . $outputType;
146
-		$output    = new $className;
147
-		$escaper   = new Escaper($delimiter);
148
-
149
-		$this->serializer = new Serializer($output, $escaper);
150
-	}
151
-
152
-	/**
153
-	* Split all given strings by character
154
-	*
155
-	* @param  string[] $strings List of strings
156
-	* @return array[]           List of arrays
157
-	*/
158
-	protected function splitStrings(array $strings)
159
-	{
160
-		return array_map([$this->input, 'split'], $strings);
161
-	}
21
+    /**
22
+     * @var InputInterface
23
+     */
24
+    protected $input;
25
+
26
+    /**
27
+     * @var Runner
28
+     */
29
+    protected $runner;
30
+
31
+    /**
32
+     * @var Serializer
33
+     */
34
+    protected $serializer;
35
+
36
+    /**
37
+     * @param array $config
38
+     */
39
+    public function __construct(array $config = [])
40
+    {
41
+        $config += [
42
+            'delimiter' => '/',
43
+            'input'     => 'Bytes',
44
+            'output'    => 'Bytes'
45
+        ];
46
+
47
+        $this->setInput($config['input']);
48
+        $this->setSerializer($config['output'], $config['delimiter']);
49
+        $this->setRunner();
50
+    }
51
+
52
+    /**
53
+     * Build and return a regular expression that matches all of the given strings
54
+     *
55
+     * @param  string[] $strings Literal strings to be matched
56
+     * @return string            Regular expression (without delimiters)
57
+     */
58
+    public function build(array $strings)
59
+    {
60
+        $strings = array_unique($strings);
61
+        if ($this->isEmpty($strings))
62
+        {
63
+            return '';
64
+        }
65
+
66
+        $strings = $this->splitStrings($strings);
67
+        usort($strings, __CLASS__ . '::compareStrings');
68
+        $strings = $this->runner->run($strings);
69
+
70
+        return $this->serializer->serializeStrings($strings);
71
+    }
72
+
73
+    /**
74
+     * Compare two split strings
75
+     *
76
+     * Will sort strings in ascending order
77
+     *
78
+     * @param  integer[] $a
79
+     * @param  integer[] $b
80
+     * @return integer
81
+     */
82
+    protected function compareStrings(array $a, array $b)
83
+    {
84
+        $i   = -1;
85
+        $cnt = min(count($a), count($b));
86
+        while (++$i < $cnt)
87
+        {
88
+            if ($a[$i] !== $b[$i])
89
+            {
90
+                return $a[$i] - $b[$i];
91
+            }
92
+        }
93
+
94
+        return count($a) - count($b);
95
+    }
96
+
97
+    /**
98
+     * Test whether the list of strings is empty
99
+     *
100
+     * @param  string[] $strings
101
+     * @return bool
102
+     */
103
+    protected function isEmpty(array $strings)
104
+    {
105
+        return (empty($strings) || $strings === ['']);
106
+    }
107
+
108
+    /**
109
+     * Set the InputInterface instance in $this->input
110
+     *
111
+     * @param  string $inputType
112
+     * @return void
113
+     */
114
+    protected function setInput($inputType)
115
+    {
116
+        $className   = __NAMESPACE__ . '\\Input\\' . $inputType;
117
+        $this->input = new $className;
118
+    }
119
+
120
+    /**
121
+     * Set the Runner instance $in this->runner
122
+     *
123
+     * @return void
124
+     */
125
+    protected function setRunner()
126
+    {
127
+        $this->runner = new Runner;
128
+        $this->runner->addPass(new MergePrefix);
129
+        $this->runner->addPass(new GroupSingleCharacters);
130
+        $this->runner->addPass(new Recurse($this->runner));
131
+        $this->runner->addPass(new PromoteSingleStrings);
132
+        $this->runner->addPass(new MergeSuffix);
133
+        $this->runner->addPass(new CoalesceSingleCharacterPrefix);
134
+    }
135
+
136
+    /**
137
+     * Set the Serializer instance in $this->serializer
138
+     *
139
+     * @param  string $outputType
140
+     * @param  string $delimiter
141
+     * @return void
142
+     */
143
+    protected function setSerializer($outputType, $delimiter)
144
+    {
145
+        $className = __NAMESPACE__ . '\\Output\\' . $outputType;
146
+        $output    = new $className;
147
+        $escaper   = new Escaper($delimiter);
148
+
149
+        $this->serializer = new Serializer($output, $escaper);
150
+    }
151
+
152
+    /**
153
+     * Split all given strings by character
154
+     *
155
+     * @param  string[] $strings List of strings
156
+     * @return array[]           List of arrays
157
+     */
158
+    protected function splitStrings(array $strings)
159
+    {
160
+        return array_map([$this->input, 'split'], $strings);
161
+    }
162 162
 }
163 163
\ No newline at end of file
Please login to merge, or discard this patch.