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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

CoalesceOptionalStrings.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 3.34 KiB


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  }