diff --git a/lib/Docopt.php b/lib/Docopt.php index 349904d..6982f2e 100644 --- a/lib/Docopt.php +++ b/lib/Docopt.php @@ -19,7 +19,7 @@ namespace MensBeam\Docopt; * - A set in Python is roughly equivalent to array_unique($arr) in PHP, but this depends on the types of the contents */ -class Docopt { +abstract class Docopt { # __version__ = "0.7.2" public const VERSION = "0.7.2"; @@ -73,7 +73,7 @@ class Docopt { * @param bool $options_first Set to True to require options precede positional arguments, i.e. to forbid options and positional arguments intermix * @param bool $more_magic Try to be extra-helpful; offer advanced pattern-matching and spellcheck */ - public function docopt( + public static function docopt( string $docstring, // DEVIATION: Our docstring is not optional since we can't get one from the parent context $argv = null, bool $default_help = true, @@ -122,7 +122,7 @@ class Docopt { # raise DocoptLanguageError('"usage:" section (case-insensitive) not found. Perhaps missing indentation?') # if len(usage_sections) > 1: # raise DocoptLanguageError('More than one "usage:" (case-insensitive).') - $usage_sections = Util::parse_section("usage:", $docstring); + $usage_sections = Parser::parse_section("usage:", $docstring); if (sizeof($usage_sections) === 0) { throw new DocoptLanguageError('"usage:" section (case-insensitive) not found. Perhaps missing indentation?'); } @@ -140,6 +140,10 @@ class Docopt { # options = parse_defaults(docstring) # pattern = parse_pattern(formal_usage(DocoptExit.usage), options) # pattern_options = set(pattern.flat(Option)) + DocoptExit::$usage = $usage_sections[0]; + $options = Parser::parse_defaults($docstring); + $pattern = Parser::parse_pattern(Parser::formal_usage(DocoptExit::$usage), $options); + $pattern_options = array_unique($pattern->flat(Options::class)); # for options_shortcut in pattern.flat(OptionsShortcut): # doc_options = parse_defaults(docstring) # options_shortcut.children = [opt for opt in doc_options if opt not in pattern_options] @@ -160,17 +164,17 @@ class Docopt { # magic = magic_docopt = docopt /** Helper function to invoke the docopt() method with $more_magic always true */ - public function magic(string $docstring, $argv = null, bool $default_help = true, $version = null, bool $options_first = false, bool $more_magic = false): ParsedOptions { + public static function magic(string $docstring, $argv = null, bool $default_help = true, $version = null, bool $options_first = false, bool $more_magic = false): ParsedOptions { return static::docopt($docstring, $argv, $default_help, $version, $options_first, true); } /** Helper function to invoke the docopt() method with $more_magic always true */ - public function magic_docopt(string $docstring, $argv = null, bool $default_help = true, $version = null, bool $options_first = false, bool $more_magic = false): ParsedOptions { + public static function magic_docopt(string $docstring, $argv = null, bool $default_help = true, $version = null, bool $options_first = false, bool $more_magic = false): ParsedOptions { return static::docopt($docstring, $argv, $default_help, $version, $options_first, true); } } -class Util { +abstract class Parser { # 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 @@ -563,7 +567,7 @@ class BranchPattern extends Pattern { public function fix_repeating_arguments(): self { # either = [list(child.children) for child in transform(self).children] $either = []; - foreach (Util::transform($this)->children as $child) { + foreach (Parser::transform($this)->children as $child) { $either[] = (array) $child->children; } # for case in either: