Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
CoalesceOptionalStrings.php
001 <?php declare(strict_types=1);
002
003 /**
004 * @package s9e\RegexpBuilder
005 * @copyright Copyright (c) 2016-2022 The s9e authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\RegexpBuilder\Passes;
009
010 use const false;
011 use function array_diff_key, array_pop, array_unshift, count, end, is_array, serialize, unserialize;
012
013 /**
014 * Replaces (?:ab?|b)? with a?b?
015 */
016 class CoalesceOptionalStrings extends AbstractPass
017 {
018 /**
019 * {@inheritdoc}
020 */
021 protected function canRun(array $strings): bool
022 {
023 return ($this->isOptional && count($strings) > 1);
024 }
025
026 /**
027 * {@inheritdoc}
028 */
029 protected function runPass(array $strings): array
030 {
031 foreach ($this->getPrefixGroups($strings) as $suffix => $prefixStrings)
032 {
033 $suffix = unserialize($suffix);
034 $suffixStrings = array_diff_key($strings, $prefixStrings);
035 if ($suffix === $this->buildSuffix($suffixStrings))
036 {
037 $this->isOptional = false;
038
039 return $this->buildCoalescedStrings($prefixStrings, $suffix);
040 }
041 }
042
043 return $strings;
044 }
045
046 /**
047 * Build the final list of coalesced strings
048 *
049 * @param array[] $prefixStrings
050 * @param array $suffix
051 * @return array[]
052 */
053 protected function buildCoalescedStrings(array $prefixStrings, array $suffix): array
054 {
055 $strings = $this->runPass($this->buildPrefix($prefixStrings));
056 if ($this->isSingleOptionalAlternation($strings))
057 {
058 // If the prefix has been remerged into a list of strings which contains only one string
059 // of which the first element is an optional alternation, we only need to append the
060 // suffix
061 $strings[0][] = $suffix;
062 }
063 else
064 {
065 // Put the current list of strings that form the prefix into a new list of strings, of
066 // which the only string is composed of our optional prefix followed by the suffix
067 array_unshift($strings, []);
068 $strings = [[$strings, $suffix]];
069 }
070
071 return $strings;
072 }
073
074 /**
075 * Build the list of strings used as prefix
076 *
077 * @param array[] $strings
078 * @return array[]
079 */
080 protected function buildPrefix(array $strings): array
081 {
082 $prefix = [];
083 foreach ($strings as $string)
084 {
085 // Remove the last element (suffix) of each string before adding it
086 array_pop($string);
087 $prefix[] = $string;
088 }
089
090 return $prefix;
091 }
092
093 /**
094 * Build a list of strings that matches any given strings or nothing
095 *
096 * Will unpack groups of single characters
097 *
098 * @param array[] $strings
099 * @return array[]
100 */
101 protected function buildSuffix(array $strings): array
102 {
103 $suffix = [[]];
104 foreach ($strings as $string)
105 {
106 if ($this->isCharacterClassString($string))
107 {
108 foreach ($string[0] as $element)
109 {
110 $suffix[] = $element;
111 }
112 }
113 else
114 {
115 $suffix[] = $string;
116 }
117 }
118
119 return $suffix;
120 }
121
122 /**
123 * Get the list of potential prefix strings grouped by identical suffix
124 *
125 * @param array[] $strings
126 * @return array
127 */
128 protected function getPrefixGroups(array $strings): array
129 {
130 $groups = [];
131 foreach ($strings as $k => $string)
132 {
133 if ($this->hasOptionalSuffix($string))
134 {
135 $groups[serialize(end($string))][$k] = $string;
136 }
137 }
138
139 return $groups;
140 }
141
142 /**
143 * Test whether given list of strings starts with a single optional alternation
144 *
145 * @param array $strings
146 * @return bool
147 */
148 protected function isSingleOptionalAlternation(array $strings): bool
149 {
150 return (count($strings) === 1 && is_array($strings[0][0]) && $strings[0][0][0] === []);
151 }
152 }