From 77707690cca620155a329c5b861d8a2591575b5f Mon Sep 17 00:00:00 2001 From: "J. King" Date: Wed, 9 Feb 2022 17:53:39 -0500 Subject: [PATCH] More porting --- lib/Docopt.php | 112 +++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/lib/Docopt.php b/lib/Docopt.php index ab79311..89d2154 100644 --- a/lib/Docopt.php +++ b/lib/Docopt.php @@ -18,15 +18,20 @@ class Docopt { protected static function levenshtein_norm(string $source, string $target): float { // NOTE: We split the strings into arrays of UTF-8 characters to match Python's behaviour (for UTF-8 input) // TODO: How is argv encoded in Windows and macOS? Does the Windows Command Prompt differ from Powershell? - $source = preg_split('/(? int: @@ -100,6 +105,45 @@ class Docopt { # return matrix[len(source)][len(target)] return $matrix[sizeof($source)][sizeof($target)]; } + + # def transform(pattern: "BranchPattern") -> "Either": + # """Expand pattern into an (almost) equivalent one, but with single Either. + # + # Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d) + # Quirks: [-a] => (-a), (-a...) => (-a -a) + # + # """ + protected static function transform(BranchPattern $pattern): Either { + # result = [] + # groups = [[pattern]] + $result = []; + $groups = [[$pattern]]; + # while groups: + while ($groups) { + # children = groups.pop(0) + $children = array_shift($groups); + # parents = [Required, NotRequired, OptionsShortcut, Either, OneOrMore] + $parents = [Required::class, NotRequired::class, OptionsShortcut::class, Either::class, OneOrMore::class]; + # if any(t in map(type, children) for t in parents): + $anyParentTypeInChildren = array_reduce($children, function($out, $c) use ($parents) { + return $out ?: in_array(get_class($c), $parents); + }, false); + if ($anyParentTypeInChildren) { + # child = [c for c in children if type(c) in parents][0] + # children.remove(child) + # if type(child) is Either: + # for c in child.children: + # groups.append([c] + children) + # elif type(child) is OneOrMore: + # groups.append(child.children * 2 + children) + # else: + # groups.append(child.children + children) + } + # else: + # result.append(children) + } + # return Either(*[Required(*e) for e in result]) + } } # class DocoptLanguageError(Exception): @@ -135,46 +179,32 @@ class DocoptExit extends \Exception { } # class Pattern: -# def __init__(self, name: Optional[str], value: Optional[Union[List[str], str, int]] = None) -> None: -# self._name, self.value = name, value - -# @property -# def name(self) -> Optional[str]: -# return self._name - -# def __eq__(self, other: Any) -> bool: -# return repr(self) == repr(other) - -# def __hash__(self) -> int: -# return hash(repr(self)) - +class Pattern { + public $name = null; // DEVIATION: This is a read-only property in Python. As this class is not part of the public API, this was deemed unnecessary complication + public $value = null; + + # def __init__(self, name: Optional[str], value: Optional[Union[List[str], str, int]] = None) -> None: + public function __construct(?string $name, $value = null) { + # self._name, self.value = name, value + $this->name = $name; + $this->value = $value; + } -# def transform(pattern: "BranchPattern") -> "Either": -# """Expand pattern into an (almost) equivalent one, but with single Either. + # @property + # def name(self) -> Optional[str]: + # return self._name + // DEVIATION: Not implemented; see property definition above -# Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d) -# Quirks: [-a] => (-a), (-a...) => (-a -a) - -# """ -# result = [] -# groups = [[pattern]] -# while groups: -# children = groups.pop(0) -# parents = [Required, NotRequired, OptionsShortcut, Either, OneOrMore] -# if any(t in map(type, children) for t in parents): -# child = [c for c in children if type(c) in parents][0] -# children.remove(child) -# if type(child) is Either: -# for c in child.children: -# groups.append([c] + children) -# elif type(child) is OneOrMore: -# groups.append(child.children * 2 + children) -# else: -# groups.append(child.children + children) -# else: -# result.append(children) -# return Either(*[Required(*e) for e in result]) + # def __eq__(self, other: Any) -> bool: + # return repr(self) == repr(other) + // DEVIATION: Operators cannot be overloaded in PHP, thus this is not implemented + // TODO: Do we need to implement an explicit means oof comparison? + # def __hash__(self) -> int: + # return hash(repr(self)) + // DEVIATION: Not implemented as it is only used internally for object comparison + // See https://docs.python.org/3/reference/datamodel.html?highlight=__hash__#object.__hash__ +} # TSingleMatch = Tuple[Union[int, None], Union["LeafPattern", None]]