|
|
@ -16,6 +16,7 @@ namespace MensBeam\Docopt; |
|
|
|
* for their purpose. Some are ported as calls to array_map or array_filter, |
|
|
|
* while others are ported as loops for efficiency |
|
|
|
* - func(*list) in Python is equivalent to func(...$arr) in PHP, both in calls and definitions |
|
|
|
* - A set in Python is roughly equivalent to array_unique($arr) in PHP, but this depends on the types of the contents |
|
|
|
*/ |
|
|
|
|
|
|
|
class Docopt { |
|
|
@ -328,7 +329,7 @@ class LeafPattern extends Pattern { |
|
|
|
$increment = [$match->value]; |
|
|
|
} |
|
|
|
# if same_name[0].value is not None and increment is not None: |
|
|
|
if ($name_name[0]->value !== null and $increment !== null) { |
|
|
|
if ($same_name[0]->value !== null and $increment !== null) { |
|
|
|
# if isinstance(same_name[0].value, type(increment)): |
|
|
|
# same_name[0].value += increment |
|
|
|
// This is a weird way of asking whether the value and |
|
|
@ -340,7 +341,7 @@ class LeafPattern extends Pattern { |
|
|
|
} |
|
|
|
} |
|
|
|
# return True, left_, collected |
|
|
|
return [true, $left_, $coollected]; |
|
|
|
return [true, $left_, $collected]; |
|
|
|
} |
|
|
|
# elif not same_name and type(self.value) == list: |
|
|
|
elseif (!$same_name && is_array($this->value)) { |
|
|
@ -359,54 +360,79 @@ class LeafPattern extends Pattern { |
|
|
|
|
|
|
|
|
|
|
|
# class BranchPattern(Pattern): |
|
|
|
|
|
|
|
# """Branch/inner node of a pattern tree.""" |
|
|
|
class BranchPattern extends Pattern { |
|
|
|
public $children = []; |
|
|
|
|
|
|
|
# def __init__(self, *children) -> None: |
|
|
|
# self.children = list(children) |
|
|
|
# def __init__(self, *children) -> None: |
|
|
|
# self.children = list(children) |
|
|
|
public function __construct(Pattern ...$children) { |
|
|
|
$this->children = $children; |
|
|
|
} |
|
|
|
|
|
|
|
# def match(self, left: List["Pattern"], collected: List["Pattern"] = None) -> Any: |
|
|
|
# raise NotImplementedError # pragma: no cover |
|
|
|
|
|
|
|
# def fix(self) -> "BranchPattern": |
|
|
|
# self.fix_identities() |
|
|
|
# self.fix_repeating_arguments() |
|
|
|
# return self |
|
|
|
|
|
|
|
# def fix_identities(self, uniq: Optional[Any] = None) -> None: |
|
|
|
# """Make pattern-tree tips point to same object if they are equal.""" |
|
|
|
# flattened = self.flat() |
|
|
|
# uniq = list(set(flattened)) if uniq is None else uniq |
|
|
|
# for i, child in enumerate(self.children): |
|
|
|
# if not hasattr(child, "children"): |
|
|
|
# assert child in uniq |
|
|
|
# self.children[i] = uniq[uniq.index(child)] |
|
|
|
# else: |
|
|
|
# child.fix_identities(uniq) |
|
|
|
# return None |
|
|
|
|
|
|
|
# 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 |
|
|
|
# def match(self, left: List["Pattern"], collected: List["Pattern"] = None) -> Any: |
|
|
|
# raise NotImplementedError # pragma: no cover |
|
|
|
public function match(array $left, ?array $collected = null) { |
|
|
|
throw new \Exception("Not implemented"); |
|
|
|
} |
|
|
|
|
|
|
|
# def __repr__(self) -> str: |
|
|
|
# return "%s(%s)" % (self.__class__.__name__, ", ".join(repr(a) for a in self.children)) |
|
|
|
# def fix(self) -> "BranchPattern": |
|
|
|
# self.fix_identities() |
|
|
|
# self.fix_repeating_arguments() |
|
|
|
# return self |
|
|
|
public function fix(): self { |
|
|
|
$this->fix_identities(); |
|
|
|
$this->fix_repeating_arguments(); |
|
|
|
return $this; |
|
|
|
} |
|
|
|
|
|
|
|
# def flat(self, *types) -> Any: |
|
|
|
# if type(self) in types: |
|
|
|
# return [self] |
|
|
|
# return sum([child.flat(*types) for child in self.children], []) |
|
|
|
# def fix_identities(self, uniq: Optional[Any] = None) -> None: |
|
|
|
# """Make pattern-tree tips point to same object if they are equal.""" |
|
|
|
public function fix_identities(?array $uniq = null): void { |
|
|
|
# flattened = self.flat() |
|
|
|
# uniq = list(set(flattened)) if uniq is None else uniq |
|
|
|
$uniq = $uniq ?? array_unique($this->flat()); |
|
|
|
# for i, child in enumerate(self.children): |
|
|
|
foreach ($this->children as [$i, $child]) { |
|
|
|
# if not hasattr(child, "children"): |
|
|
|
if (!isset($child->children)) { |
|
|
|
# assert child in uniq |
|
|
|
assert(in_array($child, $uniq), new \Exception()); |
|
|
|
# self.children[i] = uniq[uniq.index(child)] |
|
|
|
$this->children[$i] = $uniq[array_search($child, $uniq)]; |
|
|
|
} |
|
|
|
# else: |
|
|
|
else { |
|
|
|
# child.fix_identities(uniq) |
|
|
|
$child->fix_identities($uniq); |
|
|
|
} |
|
|
|
} |
|
|
|
# return None |
|
|
|
// Void function |
|
|
|
} |
|
|
|
|
|
|
|
# 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 |
|
|
|
|
|
|
|
# def __repr__(self) -> str: |
|
|
|
# return "%s(%s)" % (self.__class__.__name__, ", ".join(repr(a) for a in self.children)) |
|
|
|
|
|
|
|
# def flat(self, *types) -> Any: |
|
|
|
# if type(self) in types: |
|
|
|
# return [self] |
|
|
|
# return sum([child.flat(*types) for child in self.children], []) |
|
|
|
} |
|
|
|
|
|
|
|
# class Argument(LeafPattern): |
|
|
|
# def single_match(self, left: List[LeafPattern]) -> TSingleMatch: |
|
|
|