Last active
March 14, 2025 11:06
-
-
Save belfie13/82f85324a4edbff7759fb42a8681d436 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* On every loop of `while(true)` we check: | |
* 1. If all elements in group have same head -> extract it to common head, | |
* 2. If all elements in group have same tail -> extract it to common tail, | |
* 3. If some elements have common head -> create sub group of this elements, and put there head as common head of group, | |
* 4. Same for tails. | |
* If none of previous happen - we stop loop. | |
* Then check if current group has empty entry and convert it to optional (like `(a|b|) -> (a|b)?`). | |
* Then for every child group of current group we run same loops. | |
*/ | |
function most_frequent(iterable $list_to_search) { | |
$counter = 0; | |
$num = $list_to_search[0]; | |
foreach ($list_to_search as $i) { | |
$curr_frequency = 0; | |
foreach ($list_to_search as $j) { | |
if ($j === $i) { | |
$curr_frequency++; | |
} | |
} | |
if ($curr_frequency > $counter) { | |
$counter = $curr_frequency; | |
$num = $i; | |
} | |
} | |
return [$num, $counter]; | |
} | |
interface ReToken extends Countable { | |
public function get_head(): string; | |
public function has_head(): bool; | |
public function get_tail(): string; | |
public function has_tail(): bool; | |
public function create_without_head(): ReToken; | |
public function create_without_tail(): ReToken; | |
} | |
/** | |
* list of words split by uppercase characters. | |
*/ | |
class ReSingleToken implements ReToken { | |
private iterable $vals; | |
public function __construct(string $val) { | |
echo 'ReSingleToken('.$val.')'.PHP_EOL; | |
$val = preg_replace('~([A-Z])~', '§\1', $val); | |
$vals = explode('§', $val); | |
// explode() adds § to start/end of array if § is @ start/end of string given | |
if ($vals[0] === '§') | |
array_shift($vals); | |
if ($vals[array_key_last($vals)] === '§') | |
array_pop($vals); | |
$this->vals = $vals; | |
print_r($this->vals); | |
} | |
public function __toString(): string { | |
return implode('', $this->vals); | |
} | |
public function count(): int { | |
return count($this->vals); | |
} | |
public function get_head(): string { | |
return count($this) > 0 ? $this->vals[0] : ''; | |
} | |
public function has_head(): bool { | |
return true; | |
} | |
public function get_tail(): string { | |
$count = count($this); | |
return $count > 0 ? $this->vals[$count -1] : ''; | |
} | |
public function has_tail(): bool { | |
return true; | |
} | |
public function create_without_head(): ReSingleToken { | |
// $str = substr($this->__toString(), 1); | |
$vars = $this->vals; | |
array_shift($vars); | |
return new ReSingleToken(implode('', $vars)); | |
} | |
public function create_without_tail(): ReSingleToken { | |
// $str = substr($this->__toString(), 0, -1); | |
$vars = $this->vals; | |
array_pop($vars); | |
return new ReSingleToken(implode('', $vars)); | |
} | |
} | |
class ReGroup implements ReToken { | |
public function __construct( | |
private iterable $tokens, | |
private $commonBeginning, | |
private $commonEnding, | |
private bool $optional = false | |
) | |
{ | |
echo 'ReGroup([' | |
.implode(',', $tokens) | |
.'],' | |
.$commonBeginning.',' | |
.$commonEnding.',' | |
.(string)$optional.')' | |
.PHP_EOL; | |
} | |
public function tryToOptimize() { | |
while (true) { | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token->has_head()) { | |
$tokens[] = $token->get_head(); | |
} | |
} | |
list($head_most_popular, $head_count) = most_frequent($tokens); | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token->has_tail()) { | |
$tokens[] = $token->get_tail(); | |
} | |
} | |
list($tail_most_popular, $tail_count) = most_frequent($tokens); | |
if ($head_count === count($this->tokens)) { | |
$this->commonBeginning .= $head_most_popular; | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
$tokens[] = $token->create_without_head(); | |
} | |
$this->tokens = $tokens; | |
continue; | |
} | |
if ($tail_count === count($this->tokens)) { | |
$this->commonEnding .= $tail_most_popular; | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
$tokens[] = $token->create_without_tail(); | |
} | |
$this->tokens = $tokens; | |
continue; | |
} | |
if ($head_count > $tail_count) { | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token->get_head() === $head_most_popular) { | |
$tokens[] = $token->create_without_head(); | |
} | |
} | |
$newGroup = new ReGroup($tokens, $head_most_popular, '', false); | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token->get_head() !== $head_most_popular) { | |
$tokens[] = $token; | |
} | |
} | |
$this->tokens = $tokens; | |
$this->tokens[] = $newGroup; | |
} | |
else { | |
# no common groups | |
if ($tail_count < 2) { | |
break; | |
} | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token->get_tail() === $tail_most_popular) { | |
$tokens[] = $token; | |
} | |
} | |
$newGroup = new ReGroup($tokens, '', $tail_most_popular, false); | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token->get_tail() !== $tail_most_popular) { | |
$tokens[] = $token; | |
} | |
} | |
$this->tokens = $tokens; | |
$this->tokens[] = $newGroup; | |
} | |
} | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if ($token instanceof ReSingleToken and $token->get_head() === '') { | |
$tokens[] = $token; | |
} | |
} | |
if (count($tokens) > 0) { | |
#check if group has '' -> make optional | |
$this->optional = true; | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
if (!$token instanceof ReSingleToken or $token->get_head() !== '') { | |
$tokens[] = $token; | |
} | |
} | |
} | |
$this->tokens = $tokens; | |
foreach ($this->tokens as $group) { | |
if ($group instanceof ReGroup) { | |
$group->tryToOptimize(); | |
} | |
} | |
} | |
public function __toString(): string { | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
$tokens[] = $token->__toString(); | |
} | |
$ret = $this->commonBeginning.'('.implode('|', $tokens).')'.($this->optional ? '?' : '').$this->commonEnding; | |
echo $ret.PHP_EOL; | |
return $ret; | |
} | |
public function count(): int { | |
return count($this->tokens); | |
} | |
public function get_head(): string { | |
return $this->commonBeginning; | |
} | |
public function has_head(): bool { | |
return $this->commonBeginning != ''; | |
} | |
public function get_tail(): string { | |
return $this->commonEnding; | |
} | |
public function has_tail(): bool { | |
return $this->commonEnding != ''; | |
} | |
public function create_without_head(): ReGroup { | |
return new ReGroup($this->tokens, '', $this->commonEnding, $this->optional); | |
} | |
public function create_without_tail(): ReGroup { | |
return new ReGroup($this->tokens, $this->commonBeginning, '', $this->optional); | |
} | |
} | |
$for_test = [ | |
'(A|B|C|D)', | |
'(A|B|C|DA)', | |
'(A|B|C|AD)', | |
'(Example|ArrayIterator|RecursiveArrayIterator|DirectoryIterator|RecursiveDirectoryIterator)', | |
'(Example|DOMNode|DOMText|DOMElement)' | |
]; | |
foreach ($for_test as $init) { | |
echo 'a'.PHP_EOL; | |
$init = substr($init, 1, -1); | |
$tokens = []; | |
foreach (explode('|', $init) as $token) { | |
$tokens[] = new ReSingleToken($token); | |
} | |
$r = new ReGroup($tokens, '', '', false); | |
$r->tryToOptimize(); | |
print_r($r); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import abc | |
from typing import List | |
import re | |
def most_frequent(list_to_search: List): | |
counter = 0 | |
num = List[0] | |
for i in list_to_search: | |
curr_frequency = list_to_search.count(i) | |
if curr_frequency > counter: | |
counter = curr_frequency | |
num = i | |
return num, counter | |
class ReToken: | |
@abc.abstractmethod | |
def get_head(self) -> str: | |
pass | |
@abc.abstractmethod | |
def has_head(self) -> bool: | |
pass | |
@abc.abstractmethod | |
def get_tail(self) -> str: | |
pass | |
@abc.abstractmethod | |
def has_tail(self) -> bool: | |
pass | |
@abc.abstractmethod | |
def create_without_head(self) -> 'ReToken': | |
pass | |
@abc.abstractmethod | |
def create_without_tail(self) -> 'ReToken': | |
pass | |
class ReSingleToken(ReToken): | |
def create_without_head(self) -> 'ReSingleToken': | |
return ReSingleToken(''.join(self.vals[1:])) | |
def create_without_tail(self) -> 'ReSingleToken': | |
return ReSingleToken(''.join(self.vals[:-1])) | |
def get_head(self) -> str: | |
return self.vals[0] if len(self.vals) > 0 else '' | |
def has_head(self) -> bool: | |
return True | |
def get_tail(self) -> str: | |
return self.vals[-1] if len(self.vals) > 0 else '' | |
def has_tail(self) -> bool: | |
return True | |
def __init__(self, val: str): | |
self.vals = re.sub(r"([A-Z])", r" \1", val).split() | |
def __repr__(self): | |
return ''.join(self.vals) | |
# return self.vals.__str__() | |
class ReGroup(ReToken): | |
def create_without_head(self) -> 'ReGroup': | |
return ReGroup(self.tokens, '', self.commonEnding, self.optional) | |
def create_without_tail(self) -> 'ReGroup': | |
return ReGroup(self.tokens, self.commonBeginning, '', self.optional) | |
def __init__(self, tokens: List[ReToken], commonBeginning, commonEnding, optional=False): | |
self.tokens = tokens | |
self.commonBeginning = commonBeginning | |
self.commonEnding = commonEnding | |
self.optional = optional | |
def get_head(self) -> str: | |
return self.commonBeginning | |
def has_head(self) -> bool: | |
return self.commonBeginning != '' | |
def get_tail(self) -> str: | |
return self.commonEnding | |
def has_tail(self) -> bool: | |
return self.commonEnding != '' | |
def __repr__(self): | |
return self.commonBeginning + '(' + '|'.join( | |
[token.__repr__() for token in self.tokens]) + ')' + ('?' if self.optional else '') + self.commonEnding | |
def tryToOptimize(self): | |
while (True): | |
head_most_popular, head_count = most_frequent( | |
[token.get_head() for token in self.tokens if token.has_head()]) | |
tail_most_popular, tail_count = most_frequent( | |
[token.get_tail() for token in self.tokens if token.has_tail()]) | |
if head_count == len(self.tokens): | |
self.commonBeginning += head_most_popular | |
self.tokens = [token.create_without_head() for token in self.tokens] | |
continue | |
if tail_count == len(self.tokens): | |
self.commonEnding += tail_most_popular | |
self.tokens = [token.create_without_tail() for token in self.tokens] | |
continue | |
if head_count > tail_count: | |
newGroup = ReGroup( | |
[token.create_without_head() for token in self.tokens if token.get_head() == head_most_popular], | |
head_most_popular, '', False) | |
self.tokens = [token for token in self.tokens if token.get_head() != head_most_popular] | |
self.tokens.append(newGroup) | |
else: | |
if tail_count < 2: # No common groups | |
break | |
newGroup = ReGroup( | |
[token.create_without_tail() for token in self.tokens if token.get_tail() == tail_most_popular], '', | |
tail_most_popular, False) | |
self.tokens = [token for token in self.tokens if token.get_tail() != tail_most_popular] | |
self.tokens.append(newGroup) | |
if len([token for token in self.tokens if isinstance(token, ReSingleToken) and token.get_head() == '']) > 0: | |
# check if group has '' -> make optional | |
self.optional = True | |
self.tokens = [token for token in self.tokens if | |
not isinstance(token, ReSingleToken) or token.get_head() != ''] | |
for group in self.tokens: | |
if isinstance(group, ReGroup): | |
group.tryToOptimize() | |
for_test = [ | |
'(A|B|C|D)', | |
'(A|B|C|DA)', | |
'(A|B|C|AD)', | |
'(Example|ArrayIterator|RecursiveArrayIterator|DirectoryIterator|RecursiveDirectoryIterator)', | |
'(Example|DOMNode|DOMText|DOMElement)' | |
] | |
for init in for_test: | |
r = ReGroup([ReSingleToken(token) for token in init[1:-1].split('|')], '', '', False) | |
r.tryToOptimize() | |
print(r) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
# THE RESULT HERE IS KINDA KOOL BUT I'M NOT SURE IF I MADE IT WORSE OR BETTER BY STUFFING AROUND WITHOUT A PLAN ! | |
function most_frequent(array $list_to_search) { | |
// print_r($list_to_search);#DEBUG | |
if (count($list_to_search) === 0) | |
return ['', 0]; | |
$it = new ArrayIterator($list_to_search); | |
$counter = 0; | |
$num = $list_to_search[0]; | |
foreach ($it as $i) { | |
$curr_frequency = 0; | |
foreach (new ArrayIterator($list_to_search) as $j) { | |
if ($j === $i) { | |
$curr_frequency++; | |
} | |
} | |
if ($curr_frequency > $counter) { | |
$counter = $curr_frequency; | |
$num = $i; | |
} | |
} | |
return [$num, $counter]; | |
} | |
interface ReToken extends Countable { | |
public function is_empty(): bool; | |
public function get_head(): string; | |
public function has_head(): bool; | |
public function get_tail(): string; | |
public function has_tail(): bool; | |
public function create_without_head(): ReToken; | |
public function create_without_tail(): ReToken; | |
} | |
/** | |
* A string split by [A-Z]+[] | |
*/ | |
class ReSingleToken implements ReToken { | |
private iterable $vals; | |
public function __construct(string $val) { | |
// echo 'ReSingleToken('.$val.')'.PHP_EOL;#DEBUG | |
$regexV1 = '/([A-Z]*[a-z_0-9]*)(?=[A-Z]+)/'; | |
$regexV2 = '~([A-Z]?[^A-Z]+|[A-Z]+(?=[A-Z][^A-Z]|$))~'; | |
$words = preg_split($regexV2,$val,-1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); | |
// print_r($words);#DEBUG | |
$this->vals = $words; | |
// print_r(['"'.$val.'"', $words]);#DEBUG | |
} | |
public function __toString(): string { | |
return implode('', $this->vals); | |
} | |
public function count(): int { | |
return count($this->vals); | |
} | |
public function is_empty(): bool { | |
return count($this) === 0; | |
} | |
public function get_head(): string { | |
return count($this) > 0 ? $this->vals[0] : ''; | |
} | |
public function has_head(): bool { | |
return true; | |
} | |
public function get_tail(): string { | |
return count($this) > 0 ? $this->vals[array_key_last($this->vals)] : ''; | |
} | |
public function has_tail(): bool { | |
return true; | |
} | |
public function create_without_head(): ReSingleToken { | |
$vals = $this->vals; | |
if ($this->has_head()) | |
{ | |
array_shift($vals); | |
} | |
return new ReSingleToken(implode('', $vals)); | |
} | |
public function create_without_tail(): ReSingleToken { | |
$vals = $this->vals; | |
if ($this->has_tail()) | |
{ | |
array_pop($vals); | |
} | |
return new ReSingleToken(implode('', $vals)); | |
} | |
} | |
class ReGroup implements ReToken, RecursiveIterator { | |
public function __construct( | |
private iterable $tokens, | |
private $commonBeginning, | |
private $commonEnding, | |
private bool $optional = false | |
) | |
{ | |
// echo 'ReGroup(['.implode(',', $tokens).'], commonBeginning='.$commonBeginning.', commonEnding='.$commonEnding.', optional='.(string)$optional.')'.PHP_EOL;#DEBUG | |
foreach ($tokens as $key => $value) | |
{ | |
if ($value->is_empty()) { | |
unset($this->tokens[$key]); | |
$this->optional = true; | |
} | |
} | |
} | |
/** | |
* Sets the tokens that are not empty string and makes the object optional | |
* if any are empty. | |
* | |
* @param iterable $tokens The tokens that represent the alternation group. | |
*/ | |
public function setTokens(iterable $tokens) { | |
$this->tokens = []; | |
$this->optional = false; | |
foreach ($tokens as $token) { | |
if ((string)$token === '') | |
$this->optional = true; | |
else $this->tokens[] = $token; | |
} | |
} | |
public function tryToOptimize() { | |
while (true) { | |
// get all token heads | |
$tokenHeads = []; | |
foreach ($this->tokens as $token) { | |
if ($token->has_head()) { | |
$tokenHeads[] = $token->get_head(); | |
} | |
} | |
list($head_most_popular, $head_count) = most_frequent($tokenHeads); | |
// get all token tails | |
$tokenTails = []; | |
foreach ($this->tokens as $token) { | |
if ($token->has_tail()) { | |
$tokenTails[] = $token->get_tail(); | |
} | |
} | |
list($tail_most_popular, $tail_count) = most_frequent($tokenTails); | |
// all tokens have same head | |
if ($head_count > 1 and $head_count === count($this->tokens)) { | |
$tokenGroup = []; | |
// $optional = false; | |
foreach ($this->tokens as $token) { | |
$token = $token->create_without_head(); | |
$tokenGroup[] = $token; | |
// if ((string)$token === '') | |
// $optional = true; | |
} | |
// $this->tokens = [new ReGroup($tokenGroup, $head_most_popular, '', $optional)]; | |
$this->setTokens($tokenGroup); | |
$this->commonBeginning = $head_most_popular; | |
$this->commonEnding = ''; | |
// echo 'grouped by popular head: '.__LINE__.PHP_EOL;#DEBUG | |
continue; | |
} | |
// all tokens have same tail | |
if ($tail_count > 1 and $tail_count === count($this->tokens)) { | |
$tokenGroup = []; | |
// $optional = false; | |
foreach ($this->tokens as $token) { | |
$token = $token->create_without_tail(); | |
$tokenGroup[] = $token; | |
// if ((string)$token === '') | |
// $optional = true; | |
} | |
// $this->tokens = [new ReGroup($tokenGroup, '', $tail_most_popular, $optional)]; | |
$this->setTokens($tokenGroup); | |
$this->commonBeginning = ''; | |
$this->commonEnding = $tail_most_popular; | |
// echo 'grouped by popular tail: '.__LINE__.PHP_EOL;#DEBUG | |
continue; | |
} | |
if ($head_count >= $tail_count) { | |
if ($head_count < 2) { | |
// echo '//############################################################################//';#DEBUG | |
// print_r(get_defined_vars());#DEBUG | |
// echo 'no common groups: '.__LINE__.PHP_EOL;#DEBUG | |
break; | |
} | |
$tokensNoHead = []; | |
$tokensOther = []; | |
$optional = false; | |
foreach ($this->tokens as $token) { | |
if ($token->get_head() === $head_most_popular) | |
{ | |
$token = $token->create_without_head(); | |
$tokensNoHead[] = $token; | |
if ((string)$token === '') | |
$optional = true; | |
} | |
else | |
$tokensOther[] = $token; | |
} | |
$newGroup = new ReGroup($tokensNoHead, $head_most_popular, '', $optional); | |
$this->tokens = [$newGroup, ...$tokensOther]; | |
} | |
else { | |
if ($tail_count < 2) { | |
// echo 'no common groups: '.__LINE__.PHP_EOL;#DEBUG | |
break; | |
} | |
$tokensNoTail = []; | |
$tokensOther = []; | |
$optional = false; | |
foreach ($this->tokens as $token) { | |
if ($token->get_tail() === $tail_most_popular) | |
{ | |
$token = $token->create_without_tail(); | |
$tokensNoTail[] = $token; | |
if ((string)$token === '') | |
$optional = true; | |
} | |
else | |
$tokensOther[] = $token; | |
} | |
$newGroup = new ReGroup($tokensNoTail, '', $tail_most_popular, $optional); | |
$this->tokens = [$newGroup, ...$tokensOther]; | |
} | |
} | |
// $tokens = []; | |
// foreach ($this->tokens as $token) { | |
// if ($token instanceof ReSingleToken and $token->get_head() === '') { | |
// $tokens[] = $token; | |
// } | |
// } | |
// if (count($tokens) > 0) { | |
// #check if group has '' -> make optional | |
// $this->optional = true; | |
// $tokens = []; | |
// foreach ($this->tokens as $token) { | |
// if (!$token instanceof ReSingleToken or $token->get_head() !== '') { | |
// $tokens[] = $token; | |
// } | |
// } | |
// } | |
foreach ($this->tokens as $group) { | |
if ($group instanceof ReGroup) { | |
$group->tryToOptimize(); | |
} | |
} | |
} | |
public function __toString(): string { | |
$tokens = []; | |
foreach ($this->tokens as $token) { | |
$tokens[] = $token->__toString(); | |
} | |
$ret = $this->commonBeginning.'('.implode('|', $tokens).')'.($this->optional ? '?' : '').$this->commonEnding; | |
// echo $ret.PHP_EOL;#DEBUG | |
return $ret; | |
} | |
public function count(): int { | |
return count($this->tokens); | |
} | |
public function is_empty(): bool { | |
return count($this) === 0; | |
} | |
public function get_head(): string { | |
return (string)$this->commonBeginning; | |
} | |
public function has_head(): bool { | |
return (string)$this->commonBeginning != ''; | |
} | |
public function get_tail(): string { | |
return (string)$this->commonEnding; | |
} | |
public function has_tail(): bool { | |
return (string)$this->commonEnding != ''; | |
} | |
public function create_without_head(): ReGroup { | |
return new ReGroup($this->tokens, '', $this->commonEnding, $this->optional); | |
} | |
public function create_without_tail(): ReGroup { | |
return new ReGroup($this->tokens, $this->commonBeginning, '', $this->optional); | |
} | |
// ~~~>>> Iterator <<<~~~ //\ | |
private int $position = 0; | |
public function current(): mixed { | |
return $this->tokens[$this->position]; | |
} | |
public function key(): mixed { | |
return $this->position; | |
} | |
public function next(): void { | |
$this->position++; | |
} | |
public function rewind(): void { | |
$this->position = 0; | |
} | |
public function valid(): bool { | |
return count($this) > $this->position; | |
} | |
// ~~~>>> RecursiveIterator <<<~~~ // | |
public function getChildren(): ?RecursiveIterator { | |
return $this->tokens; | |
} | |
public function hasChildren(): bool { | |
return (bool)count($this); | |
} | |
} | |
$for_test = [ | |
'(A|B|C|D)', | |
'(A|B|C|DA)', | |
'(A|B|C|AD)', | |
'(Example|ArrayIterator|RecursiveArrayIterator|DirectoryIterator|RecursiveDirectoryIterator)', | |
'(Example|DOMNode|DOMText|DOMElement)' | |
]; | |
$for_test[] = '('.implode( | |
'|', | |
array_filter( | |
get_declared_classes(), | |
function ($value) { return !(bool)strpos($value, '\\'); } | |
) | |
).')'; | |
foreach ($for_test as $init) { | |
// print_r(preg_split('/([A-Z]*[a-z_0-9]*)(?=[A-Z]+)/',substr($init, 1, -1),-1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE)); | |
// continue; | |
echo PHP_EOL.PHP_EOL.'----'.PHP_EOL.PHP_EOL; | |
$inita = substr($init, 1, -1); | |
$tokens = []; | |
$strings = explode('|', $inita); | |
foreach ($strings as $token) { | |
$tokens[] = new ReSingleToken($token); | |
} | |
$r = new ReGroup($tokens, '', '', false); | |
$r->tryToOptimize(); | |
// print_r($r); | |
echo $init.' => '.$r; | |
foreach ($r as $token) { | |
if ($token instanceof ReGroup) | |
$token->tryToOptimize(); | |
} | |
echo PHP_EOL.PHP_EOL.$r.PHP_EOL.PHP_EOL; | |
$tree = new RecursiveTreeIterator($r); | |
foreach ($tree as $key => $value) { | |
echo $value.PHP_EOL; | |
} | |
} | |
/** RANDOM NOTES JUST KEEPING CAUSE I'M TOO TIRED TO GO THROUGH IT NOW | |
* (Sngle|Sngle) | |
* Group = Sngle(Sngle|Sngle)Sngle | |
* | |
* Token can have head/tail | |
* | |
* Sngle split into words: | |
* - starting with upper case character | |
* - all uppercase before a word ^ | |
* head/tail = first/last word | |
* | |
* Group split into Sngle | |
* head/tail = common head/tail | |
* | |
* for a group, | |
* get all heads | |
* if any match | |
* group them with heads removed | |
* rebuild tokens with group and remaining tokens | |
* | |
* Abcdef(Ghijk|Lmnop)?Vwxyz | |
* ^pre ^attrib opt^^post | |
* | |
* prefixToken(tokens)suffixToken | |
* | |
* @todo 🟡 what if the common head and tail counts are equal? | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---- | |
(A|B|C|D) => (A|B|C|D) | |
(A|B|C|D) | |
|-A | |
|-B | |
|-C | |
\-D | |
---- | |
(A|B|C|DA) => (A|B|C|DA) | |
(A|B|C|DA) | |
|-A | |
|-B | |
|-C | |
\-DA | |
---- | |
(A|B|C|AD) => (A|B|C|AD) | |
(A|B|C|AD) | |
|-A | |
|-B | |
|-C | |
\-AD | |
---- | |
(Example|ArrayIterator|RecursiveArrayIterator|DirectoryIterator|RecursiveDirectoryIterator) => ((Recursive(Array|Directory)|Array|Directory)Iterator|Example) | |
((Recursive(Array|Directory)|Array|Directory)Iterator|Example) | |
|-(Recursive(Array|Directory)|Array|Directory)Iterator | |
\-Example | |
---- | |
(Example|DOMNode|DOMText|DOMElement) => (DOM(Node|Text|Element)|Example) | |
(DOM(Node|Text|Element)|Example) | |
|-DOM(Node|Text|Element) | |
\-Example | |
---- | |
(InternalIterator|Exception|ErrorException|Error|CompileError|ParseError|TypeError|ArgumentCountError|ValueError|ArithmeticError|DivisionByZeroError|UnhandledMatchError|Closure|Generator|ClosedGeneratorException|WeakReference|WeakMap|Attribute|ReturnTypeWillChange|AllowDynamicProperties|SensitiveParameter|SensitiveParameterValue|Fiber|FiberError|stdClass|DateTime|DateTimeImmutable|DateTimeZone|DateInterval|DatePeriod|LibXMLError|InflateContext|DeflateContext|DOMException|DOMImplementation|DOMNode|DOMNameSpaceNode|DOMDocumentFragment|DOMDocument|DOMNodeList|DOMNamedNodeMap|DOMCharacterData|DOMAttr|DOMElement|DOMText|DOMComment|DOMCdataSection|DOMDocumentType|DOMNotation|DOMEntity|DOMEntityReference|DOMProcessingInstruction|DOMXPath|finfo|HashContext|JsonException|LogicException|BadFunctionCallException|BadMethodCallException|DomainException|InvalidArgumentException|LengthException|OutOfRangeException|RuntimeException|OutOfBoundsException|OverflowException|RangeException|UnderflowException|UnexpectedValueException|RecursiveIteratorIterator|IteratorIterator|FilterIterator|RecursiveFilterIterator|CallbackFilterIterator|RecursiveCallbackFilterIterator|ParentIterator|LimitIterator|CachingIterator|RecursiveCachingIterator|NoRewindIterator|AppendIterator|InfiniteIterator|RegexIterator|RecursiveRegexIterator|EmptyIterator|RecursiveTreeIterator|ArrayObject|ArrayIterator|RecursiveArrayIterator|SplFileInfo|DirectoryIterator|FilesystemIterator|RecursiveDirectoryIterator|GlobIterator|SplFileObject|SplTempFileObject|SplDoublyLinkedList|SplQueue|SplStack|SplHeap|SplMinHeap|SplMaxHeap|SplPriorityQueue|SplFixedArray|SplObjectStorage|MultipleIterator|SessionHandler|PDOException|PDO|PDOStatement|PDORow|OpenSSLCertificate|OpenSSLCertificateSigningRequest|OpenSSLAsymmetricKey|ReflectionException|Reflection|ReflectionFunctionAbstract|ReflectionFunction|ReflectionGenerator|ReflectionParameter|ReflectionType|ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|ReflectionMethod|ReflectionClass|ReflectionObject|ReflectionProperty|ReflectionClassConstant|ReflectionExtension|ReflectionZendExtension|ReflectionReference|ReflectionAttribute|ReflectionEnum|ReflectionEnumUnitCase|ReflectionEnumBackedCase|ReflectionFiber|__PHP_Incomplete_Class|AssertionError|php_user_filter|Directory|SimpleXMLElement|SimpleXMLIterator|PhpToken|XMLParser|XMLReader|XMLWriter|CurlHandle|CurlMultiHandle|CurlShareHandle|CURLFile|CURLStringFile|PharException|Phar|PharData|PharFileInfo|RarArchive|RarEntry|RarException|ReSingleToken|ReGroup) => ((std|__PHP_Incomplete_)Class|Re(SingleToken|Group)|Rar(Archive|Entry)|(String)?File|Parameter(Value)?|Weak(Reference|Map)|(Inflate|Deflate|Hash)Context|Phar(Data|FileInfo)?|(Multi|Share)?Handle|XML(Parser|Reader|Writer)|SSL(Certificate(SigningRequest)?|AsymmetricKey)|PDO(Statement|Row)?|Date(Time(Immutable|Zone)?|Interval|Period)|(Compile|Parse|Type|ArgumentCount|Value|Arithmetic|DivisionByZero|UnhandledMatch|Fiber|LibXML|Assertion)?Error|Spl((Priority)?Queue|File(Info|Object)|(Min|Max)?Heap|TempFileObject|DoublyLinkedList|Stack|FixedArray|ObjectStorage)|DOM(Entity(Reference)?|Node(List)?|Document(Fragment|Type)?|Implementation|NameSpaceNode|NamedNodeMap|CharacterData|Attr|Element|Text|Comment|CdataSection|Notation|ProcessingInstruction)|(Of(Range|Bounds)|(Function|Method)Call|Error|ClosedGenerator|DOM|Json|Logic|Domain|InvalidArgument|Length|Runtime|Overflow|Range|Underflow|UnexpectedValue|PDO|Phar|Rar)?Exception|Reflection((Zend)?Extension|Class(Constant)?|Function(Abstract)?|(Unit|Backed)Case|(Named|Union|Intersection)?Type|Exception|Generator|Parameter|Method|Object|Property|Reference|Attribute|Fiber)?|((Callback)?Filter|Recursive((Callback)?Filter|Iterator|Caching|Regex|Tree|Array|Directory)|Internal|Iterator|Parent|Limit|Caching|NoRewind|Append|Infinite|Regex|Empty|Array|Directory|Filesystem|Glob|Multiple|SimpleXML)Iterator|Closure|Generator|Attribute|ReturnTypeWillChange|AllowDynamicProperties|Fiber|DOMXPath|finfo|ArrayObject|SessionHandler|php_user_filter|Directory|SimpleXMLElement|PhpToken) | |
((std|__PHP_Incomplete_)Class|Re(SingleToken|Group)|Rar(Archive|Entry)|(String)?File|Parameter(Value)?|Weak(Reference|Map)|(Inflate|Deflate|Hash)Context|Phar(Data|FileInfo)?|(Multi|Share)?Handle|XML(Parser|Reader|Writer)|SSL(Certificate(SigningRequest)?|AsymmetricKey)|PDO(Statement|Row)?|Date(Time(Immutable|Zone)?|Interval|Period)|(Compile|Parse|Type|ArgumentCount|Value|Arithmetic|DivisionByZero|UnhandledMatch|Fiber|LibXML|Assertion)?Error|Spl((Priority)?Queue|File(Info|Object)|(Min|Max)?Heap|TempFileObject|DoublyLinkedList|Stack|FixedArray|ObjectStorage)|DOM(Entity(Reference)?|Node(List)?|Document(Fragment|Type)?|Implementation|NameSpaceNode|NamedNodeMap|CharacterData|Attr|Element|Text|Comment|CdataSection|Notation|ProcessingInstruction)|(Of(Range|Bounds)|(Function|Method)Call|Error|ClosedGenerator|DOM|Json|Logic|Domain|InvalidArgument|Length|Runtime|Overflow|Range|Underflow|UnexpectedValue|PDO|Phar|Rar)?Exception|Reflection((Zend)?Extension|Class(Constant)?|Function(Abstract)?|(Unit|Backed)Case|(Named|Union|Intersection)?Type|Exception|Generator|Parameter|Method|Object|Property|Reference|Attribute|Fiber)?|((Callback)?Filter|Recursive((Callback)?Filter|Iterator|Caching|Regex|Tree|Array|Directory)|Internal|Iterator|Parent|Limit|Caching|NoRewind|Append|Infinite|Regex|Empty|Array|Directory|Filesystem|Glob|Multiple|SimpleXML)Iterator|Closure|Generator|Attribute|ReturnTypeWillChange|AllowDynamicProperties|Fiber|DOMXPath|finfo|ArrayObject|SessionHandler|php_user_filter|Directory|SimpleXMLElement|PhpToken) | |
|-(std|__PHP_Incomplete_)Class | |
|-Re(SingleToken|Group) | |
|-Rar(Archive|Entry) | |
|-(String)?File | |
|-Parameter(Value)? | |
|-Weak(Reference|Map) | |
|-(Inflate|Deflate|Hash)Context | |
|-Phar(Data|FileInfo)? | |
|-(Multi|Share)?Handle | |
|-XML(Parser|Reader|Writer) | |
|-SSL(Certificate(SigningRequest)?|AsymmetricKey) | |
|-PDO(Statement|Row)? | |
|-Date(Time(Immutable|Zone)?|Interval|Period) | |
|-(Compile|Parse|Type|ArgumentCount|Value|Arithmetic|DivisionByZero|UnhandledMatch|Fiber|LibXML|Assertion)?Error | |
|-Spl((Priority)?Queue|File(Info|Object)|(Min|Max)?Heap|TempFileObject|DoublyLinkedList|Stack|FixedArray|ObjectStorage) | |
|-DOM(Entity(Reference)?|Node(List)?|Document(Fragment|Type)?|Implementation|NameSpaceNode|NamedNodeMap|CharacterData|Attr|Element|Text|Comment|CdataSection|Notation|ProcessingInstruction) | |
|-(Of(Range|Bounds)|(Function|Method)Call|Error|ClosedGenerator|DOM|Json|Logic|Domain|InvalidArgument|Length|Runtime|Overflow|Range|Underflow|UnexpectedValue|PDO|Phar|Rar)?Exception | |
|-Reflection((Zend)?Extension|Class(Constant)?|Function(Abstract)?|(Unit|Backed)Case|(Named|Union|Intersection)?Type|Exception|Generator|Parameter|Method|Object|Property|Reference|Attribute|Fiber)? | |
|-((Callback)?Filter|Recursive((Callback)?Filter|Iterator|Caching|Regex|Tree|Array|Directory)|Internal|Iterator|Parent|Limit|Caching|NoRewind|Append|Infinite|Regex|Empty|Array|Directory|Filesystem|Glob|Multiple|SimpleXML)Iterator | |
|-Closure | |
|-Generator | |
|-Attribute | |
|-ReturnTypeWillChange | |
|-AllowDynamicProperties | |
|-Fiber | |
|-DOMXPath | |
|-finfo | |
|-ArrayObject | |
|-SessionHandler | |
|-php_user_filter | |
|-Directory | |
|-SimpleXMLElement | |
\-PhpToken |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
check it here at 3v4l
Next step... refactor? simplify... remove stuff..... then try multiple head/tails?
like
((Recursive(Array|Directory)|Array|Directory)Iterator|Example)
to
((Recursive)?(Array|Directory)Iterator|Example)