|
|
@ -22,13 +22,15 @@ namespace MensBeam\Docopt; |
|
|
|
class Docopt { |
|
|
|
# __version__ = "0.7.2" |
|
|
|
public const VERSION = "0.7.2"; |
|
|
|
} |
|
|
|
|
|
|
|
class Util { |
|
|
|
# def levenshtein_norm(source: str, target: str) -> float: |
|
|
|
# """Calculates the normalized Levenshtein distance between two string |
|
|
|
# arguments. The result will be a float in the range [0.0, 1.0], with 1.0 |
|
|
|
# signifying the biggest possible distance between strings with these lengths |
|
|
|
# """ |
|
|
|
protected static function levenshtein_norm(string $source, string $target): float { |
|
|
|
public 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? |
|
|
|
$s = @preg_split('//Su', $source, -1, \PREG_SPLIT_NO_EMPTY); |
|
|
@ -63,7 +65,7 @@ class Docopt { |
|
|
|
# redundant computations by storing the distances between various prefixes in |
|
|
|
# a matrix that is filled in iteratively. |
|
|
|
# """ |
|
|
|
protected static function levenshtein(array $source, array $target): int { |
|
|
|
public static function levenshtein(array $source, array $target): int { |
|
|
|
// NOTE: Our implementation operates on character arrays rather than strings |
|
|
|
|
|
|
|
# # Create matrix of correct size (this is s_len + 1 * t_len + 1 so that the |
|
|
@ -126,7 +128,7 @@ class Docopt { |
|
|
|
# Quirks: [-a] => (-a), (-a...) => (-a -a) |
|
|
|
# |
|
|
|
# """ |
|
|
|
protected static function transform(BranchPattern $pattern): Either { |
|
|
|
public static function transform(BranchPattern $pattern): Either { |
|
|
|
# result = [] |
|
|
|
# groups = [[pattern]] |
|
|
|
$result = []; |
|
|
@ -277,7 +279,6 @@ class LeafPattern extends Pattern { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# def match(self, left: List["LeafPattern"], collected: List["Pattern"] = None) -> Tuple[bool, List["LeafPattern"], List["Pattern"]]: |
|
|
|
public function match(array $left, ?array $collected = null): array { |
|
|
|
# collected = [] if collected is None else collected |
|
|
@ -413,17 +414,23 @@ class BranchPattern extends Pattern { |
|
|
|
|
|
|
|
# def fix_repeating_arguments(self) -> "BranchPattern": |
|
|
|
# """Fix elements that should accumulate/increment values.""" |
|
|
|
# either = [list(child.children) for child in transform(self).children] |
|
|
|
# for case in either: |
|
|
|
# for e in [child for child in case if case.count(child) > 1]: |
|
|
|
# if type(e) is Argument or type(e) is Option and e.argcount: |
|
|
|
# if e.value is None: |
|
|
|
# e.value = [] |
|
|
|
# elif type(e.value) is not list: |
|
|
|
# e.value = e.value.split() |
|
|
|
# if type(e) is Command or type(e) is Option and e.argcount == 0: |
|
|
|
# e.value = 0 |
|
|
|
# return self |
|
|
|
public function fix_repeating_arguments(): self { |
|
|
|
# either = [list(child.children) for child in transform(self).children] |
|
|
|
$either = []; |
|
|
|
foreach (Util::transform($this)->children as $child) { |
|
|
|
$either[] = (array) $child->children; |
|
|
|
} |
|
|
|
# for case in either: |
|
|
|
# for e in [child for child in case if case.count(child) > 1]: |
|
|
|
# if type(e) is Argument or type(e) is Option and e.argcount: |
|
|
|
# if e.value is None: |
|
|
|
# e.value = [] |
|
|
|
# elif type(e.value) is not list: |
|
|
|
# e.value = e.value.split() |
|
|
|
# if type(e) is Command or type(e) is Option and e.argcount == 0: |
|
|
|
# e.value = 0 |
|
|
|
# return self |
|
|
|
} |
|
|
|
|
|
|
|
# def __repr__(self) -> str: |
|
|
|
# return "%s(%s)" % (self.__class__.__name__, ", ".join(repr(a) for a in self.children)) |
|
|
|