3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare(strict_types = 1); /** * https://github.com/ekinhbayar/IntervalParser/ */ namespace IntervalParser; use \DateInterval; class Exception extends \Exception {} class FormatException extends Exception {} class IntervalIterator implements \Iterator { private $var = []; public function __construct($array) { if (is_array($array)) { $this->var = $array; } } public function rewind() { #echo "rewinding\n"; reset($this->var); } public function current() { $var = current($this->var); # echo "current: $var\n"; return $var; } public function key() { $var = key($this->var); #echo "key: $var\n"; return $var; } public function next() { $var = next($this->var); #echo "next: $var\n"; return $var; } public function valid() { $key = key($this->var); $var = ($key !== NULL && $key !== FALSE); #echo "valid: $var\n"; return $var; } } /** Parser Settings * * IntervalParser takes a ParserSettings object which is handy for when you want to deal with multiple intervals. * * When parsing multiple intervals if you don't supply your own settings, * the parser will try to find comma separated intervals within given input by default. * However there is no default value for $wordSeparator. * * Example: * * $parserSettings = new ParserSettings(',', 'then'); * # works for "2 days then 5 months then 2 hours" * $intervalParser = new IntervalParser($parserSettings); * */ class ParserSettings { const SYMBOL = 0; const STRING = 1; private $separationType; private $symbol; private $word; /** * ParserSettings constructor. * * @param int $separationType * @param string $symbol * @param string|null $word */ public function __construct( int $separationType = self::SYMBOL, string $symbol = ',', string $word = null ) { $this->separationType = $separationType; $this->word = $word; $this->symbol = $symbol; } public function getSymbolSeparator() : string { return $this->symbol; } public function getWordSeparator() : string { return $this->word; } public function getSeparationType(): string { return ($this->separationType == self::STRING) ? 'string' : 'symbol'; } } class IntervalFlags { const INTERVAL_ONLY = 0b00000000; const REQUIRE_TRAILING = 0b00000001; const REQUIRE_LEADING = 0b00000010; const MULTIPLE_INTERVALS = 0b00000100; } class TimeInterval { private $intervalOffset; private $intervalLength; /*private $intervalType;*/ private $leadingData; private $trailingData; private $interval; public function __construct( int $intervalOffset, int $intervalLength, /*int $intervalType,*/ string $leadingData = null, string $trailingData = null, DateInterval $interval ) { $this->interval = $interval; $this->intervalOffset = $intervalOffset; $this->intervalLength = $intervalLength; /*$this->intervalType = $intervalType;*/ $this->leadingData = $leadingData; $this->trailingData = $trailingData; } public function getInterval() : DateInterval { return $this->interval; } public function getIntervalOffset() : int { return $this->intervalOffset; } public function getIntervalLength() : int { return $this->intervalLength; } /*public function getIntervalType() : int { return $this->intervalType; }*/ public function getLeadingData() : string { return $this->leadingData; } public function getTrailingData() : string { return $this->trailingData; } } class IntervalParser { /** * Set of regular expressions utilized to match/replace/validate parts of a given input. * * Don't forget to close parentheses when using $define */ public static $define = "/(?(DEFINE)"; # Definitions of sub patterns for a valid interval public static $integer = <<<'REGEX' (?<integer> (?:\G|(?!\n)) (\s*\b)? \d{1,5} \s* ) REGEX; # Starts with integer followed by time specified public static $timepart = <<<'REGEX' (?<timepart> (?&integer) ( s(ec(ond)?s?)? | m(on(ths?)?|in(ute)?s?)? | h(rs?|ours?)? | d(ays?)? | w(eeks?)? ) ) REGEX; # Leading separator public static $leadingSeparator = "(?<leadingSeparator>\s?(?:in)\s?)"; # Leading separator with capturing groups public static $leadingGroupSeparator = "/(.*)\s+(?:in)\s+(.*)/ui"; # Regex to match a valid interval, holds the value in $matches['interval'] public static $intervalOnly = "^(?<interval>(?&timepart)++)$/uix"; # Regex to match a valid interval and any trailing string, holds the interval in $matches['interval'], the rest in $matches['trailing'] public static $intervalWithTrailingData = "^(?<interval>(?&timepart)++)(?<trailing>.+)*?$/uix"; /** * Used to turn a given non-strtotime-compatible time string into a compatible one * Only modifies the non-strtotime-compatible time strings provided leaving the rest intact * * @var string $normalizerExpression */ public static $normalizerExpression = <<<'REGEX' ~ # grab the integer part of time string \s? (?<int> \d{1,5}) \s? # match only the shortest abbreviations that aren't supported by strtotime (?<time> (?: s (?=(?:ec(?:ond)?s?)?(?:\b|\d)) | m (?=(?:in(?:ute)?s?)?(?:\b|\d)) | h (?=(?:(?:ou)?rs?)?(?:\b|\d)) | d (?=(?:ays?)?(?:\b|\d)) | w (?=(?:eeks?)?(?:\b|\d)) | mon (?=(?:(?:th)?s?)?(?:\b|\d)) ) ) [^\d]*?(?=\b|\d) # do only extract start of string | (?<text> .+) ~uix REGEX; # Regex to handle an input that may have multiple intervals along with leading and/or trailing data public static $multipleIntervals = <<<'REGEX' ^(?<leading>.*?)? (?<sep>(?&leadingSeparator))? (?<interval>(?&timepart)++) (?<trailing>.*) /uix REGEX; /** * IntervalParser constructor. * * Default settings are : * * string $symbolSeparator = ',', * string $wordSeparator = null * * @param \IntervalParser\ParserSettings $settings */ public function __construct(ParserSettings $settings) { $this->settings = $settings; } /** * Looks for a valid interval along with leading and/or trailing data IF the respective flags are set. * TimeInterval is essentially DateInterval with extra information such as interval offset & length, leading/trailing data. * * @param string $input * @param int $flags * @return TimeInterval|array * @throws FormatException */ public function findInterval(string $input, int $flags = IntervalFlags::INTERVAL_ONLY) { if( $flags & ~IntervalFlags::INTERVAL_ONLY & ~IntervalFlags::REQUIRE_TRAILING & ~IntervalFlags::REQUIRE_LEADING & ~IntervalFlags::MULTIPLE_INTERVALS ){ throw new InvalidFlagException("You have tried to use an invalid flag combination."); } if($flags & IntervalFlags::INTERVAL_ONLY){ $input = $this->normalizeTimeInterval($input); $definition = self::$define . self::$integer . self::$timepart .')'; $expression = $definition . self::$intervalOnly; if(preg_match($expression, $input)){ $intervalOffset = 0; $intervalLength = strlen($input); # create and return the interval object $interval = DateInterval::createFromDateString($input); return new TimeInterval($intervalOffset, $intervalLength, null, null, $interval); } throw new FormatException("Given input is not a valid interval."); } if($flags == (IntervalFlags::REQUIRE_LEADING | IntervalFlags::REQUIRE_TRAILING)){ # Default leading separator is "in" $leadingSeparation = preg_match(self::$leadingGroupSeparator, $input, $matches, PREG_OFFSET_CAPTURE); if(!$leadingSeparation){ throw new FormatException("Allowing leading data requires using a separator. Ie. foo in <interval>"); } $leadingData = $matches[1][0] ?? null; $intervalAndTrailingData = $matches[2][0] ?? null; # throw early for missing parts if(!$leadingData){ throw new FormatException("Given input does not contain a valid leading data."); } if(!$intervalAndTrailingData){ throw new FormatException("Given input does not contain a valid interval and/or trailing data."); } $intervalOffset = $matches[2][1] ?? null; # If interval contains non-strtotime-compatible abbreviations, replace 'em $intervalAndTrailingData = $this->normalizeTimeInterval($intervalAndTrailingData); $definition = self::$define . self::$integer . self::$timepart .')'; $expression = $definition . self::$intervalWithTrailingData; if(preg_match($expression, $intervalAndTrailingData, $parts)){ $interval = $parts['interval']; $trailingData = $parts['trailing']; $intervalLength = strlen($interval); # create and return the interval object $interval = DateInterval::createFromDateString($interval); return new TimeInterval($intervalOffset, $intervalLength, $leadingData, $trailingData, $interval); } throw new FormatException("Given input does not contain a valid interval and/or trailing data."); } if($flags & IntervalFlags::REQUIRE_LEADING){ # Default leading separator is "in" $leadingSeparation = preg_match(self::$leadingGroupSeparator, $input, $matches, PREG_OFFSET_CAPTURE); if(!$leadingSeparation){ throw new FormatException("Allowing leading data requires using a separator. Ie. foo in <interval>"); } $leadingData = $matches[1][0] ?? null; $intervalAndPossibleTrailingData = $matches[2][0] ?? null; if(!$leadingData){ throw new FormatException("Could not find any valid leading data."); } if(!$intervalAndPossibleTrailingData){ throw new FormatException("Could not find any valid interval and/or leading data."); } $intervalOffset = $matches[2][1] ?? null; # If interval contains non-strtotime-compatible abbreviations, replace 'em $safeInterval = $this->normalizeTimeInterval($intervalAndPossibleTrailingData); # since above normalization is expected to not return any trailing data, only check for a valid interval $definition = self::$define . self::$integer . self::$timepart .')'; $expression = $definition . self::$intervalOnly; if(preg_match($expression, $safeInterval, $parts)){ $interval = $parts['interval']; $intervalLength = strlen($interval); # create the interval object $interval = DateInterval::createFromDateString($interval); return new TimeInterval($intervalOffset, $intervalLength, $leadingData, null, $interval); } throw new FormatException("Given input does not contain a valid interval. Keep in mind trailing data is not allowed with current flag."); } if($flags & IntervalFlags::REQUIRE_TRAILING){ $definition = self::$define . self::$integer . self::$timepart .')'; $expression = $definition . self::$intervalWithTrailingData; # If interval contains non-strtotime-compatible abbreviations, replace 'em $safeInterval = $this->normalizeTimeInterval($input); # Separate interval from trailing data if(preg_match($expression, $safeInterval, $parts)){ $trailingData = $parts['trailing'] ?? null; $interval = $parts['interval'] ?? null; if(!$interval){ throw new FormatException("Could not find any valid interval."); } if(!$trailingData){ throw new FormatException("Could not find any valid trailing data."); } $intervalLength = strlen($interval); $intervalOffset = 0; # since we don't allow leading data here # create the interval object $interval = DateInterval::createFromDateString($interval); return new TimeInterval($intervalOffset, $intervalLength, null, $trailingData, $interval); } throw new FormatException("Given input does not contain a valid interval. Keep in mind leading data is not allowed with current flag."); } if($flags & IntervalFlags::MULTIPLE_INTERVALS){ $payload = []; $separator = ($this->settings->getSeparationType() == 'symbol') ? $this->settings->getSymbolSeparator() : $this->settings->getWordSeparator(); $expression = "/(?J)\b(?:(?<match>.*?)\s?{$separator})\s?|\b(?<match>.*)/ui"; if(preg_match_all($expression, $input, $intervals, PREG_SET_ORDER)){ $intervalSet = array_filter(array_map(function($set){ foreach($iter = new IntervalIterator($set) as $key => $interval){ if($iter->key() === 'match') { return $interval; } } }, $intervals)); foreach($intervalSet as $key => $interval){ $definition = self::$define . self::$leadingSeparator . self::$integer . self::$timepart .')'; $expression = $definition . self::$multipleIntervals; preg_match($expression, $interval, $matches); $matches = array_filter($matches); $leadingData = $matches['leading'] ?? null; $leadingSep = $matches['sep'] ?? false; $interval = $matches['interval'] ?? null; $trailing = $matches['trailing'] ?? null; if(!$leadingData){ $leadingData = ($leadingSep) ?: ""; } $intervalOffset = (!$leadingSep) ? 0 : strlen($leadingData) + strlen($leadingSep); # If interval contains non-strtotime-compatible abbreviations, replace them $safeInterval = $this->normalizeTimeInterval($interval . $trailing); # Separate intervals from trailing data if(preg_match($expression, $safeInterval, $parts)){ $trailingData = $parts['trailing'] ?? null; $interval = $parts['interval'] ?? null; if(!$interval) continue; $intervalLength = strlen($interval); # create the interval object $interval = DateInterval::createFromDateString($interval); $payload[] = new TimeInterval($intervalOffset, $intervalLength, $leadingData, $trailingData, $interval); } } if($payload) return $payload; } } } /** * Turns any non-strtotime-compatible time string into a compatible one. * If the passed input has trailing data, it won't be lost since within the callback the input is reassembled. * However no leading data is accepted. * * @param string $input * @return string */ public function normalizeTimeInterval(string $input): string { $output = preg_replace_callback(self::$normalizerExpression, function ($matches) { $int = $matches['int']; switch ($matches['time']) { case 's': $t = ($int == 1) ? ' second ' : ' seconds '; break; case 'm': $t = ($int == 1) ? ' minute ' : ' minutes '; break; case 'h': $t = ($int == 1) ? ' hour ' : ' hours '; break; case 'd': $t = ($int == 1) ? ' day ' : ' days '; break; case 'w': $t = ($int == 1) ? ' week ' : ' weeks '; break; case 'mon': $t = ($int == 1) ? ' month ' : ' months '; break; case 'y': $t = ($int == 1) ? ' year ' : ' years '; break; } $t = $t ?? ''; # rebuild the interval string $time = $int . $t; if(isset($matches['text'])){ $time .= trim($matches['text']); } return $time; }, $input); return trim($output); } /** * Normalizes any non-strtotime-compatible time string, then validates the interval and returns a DateInterval object. * No leading or trailing data is accepted. * * @param string $input * @return DateInterval * @throws \InvalidArgumentException */ public function parseInterval(string $input): \DateInterval { $input = trim($this->normalizeTimeInterval($input)); $definition = self::$define . self::$integer . self::$timepart .')'; $expression = $definition . self::$intervalOnly; if(preg_match($expression, $input, $matches)){ return DateInterval::createFromDateString($input); } throw new FormatException("Given string is not a valid time interval."); } } # Set ParserSettings for IntervalParser $settings1 = new ParserSettings(); $settings2 = new ParserSettings(0); $settings3 = new ParserSettings(1, ',', 'then'); $settings4 = new ParserSettings(0, '-'); $intervalParser1 = new IntervalParser($settings1); $intervalParser2 = new IntervalParser($settings2); $intervalParser3 = new IntervalParser($settings3); $intervalParser4 = new IntervalParser($settings4); // Usage # Only interval & trailing data $trailingString = '7mon6w5d4h3m2s bazinga!'; #$timeIntervalWithTrailingData = $intervalParser->findInterval($trailingString, IntervalFlags::REQUIRE_TRAILING); #var_dump($timeIntervalWithTrailingData); # Only leading data & interval $leadingString = 'foo in 9w8d7h6m5s'; #$timeIntervalWithLeadingData = $intervalParser->findInterval($leadingString, IntervalFlags::REQUIRE_LEADING); #var_dump($timeIntervalWithLeadingData); # Both interval & leading & trailing data $both = 'foo in 9d8h5m bar'; #$timeIntervalWithBoth = $intervalParser->findInterval($both, IntervalFlags::REQUIRE_TRAILING | IntervalFlags::REQUIRE_LEADING); #var_dump($timeIntervalWithBoth); # Only interval $onlyInterval = '9 mon 2 w 3 m 4 d'; #$dateInterval = $intervalParser->parseInterval($onlyInterval); #var_dump($dateInterval); #$normalizedInterval = $intervalParser->normalizeTimeInterval($onlyInterval); #var_dump($normalizedInterval); # Multiple Intervals # 1. Comma Separated $multiple = 'foo in 9d8h5m bar , baz in 5 minutes, foo in 2 days 4 minutes boo, in 1 hr, 10 days'; $multipleWithSymbol = 'foo in 9d8h5m bar - baz in 5 minutes- foo in 2 days 4 minutes boo- in 1 hr- 10 days'; $multipleWithWord = 'foo in 9d8h5m bar then baz in 5 minutes then foo in 2 days 4 minutes boo then in 1 hr then 10 days'; $multipleIntervals = $intervalParser1->findInterval($multiple, IntervalFlags::MULTIPLE_INTERVALS); var_dump($multipleIntervals); # 2. Separated by a defined-on-settings word #$wordSeparated = 'foo in 9d8h5m bar then baz in 5 minutes then foo in 2 days 4 minutes boo then in 2 hours'; #$wordSeparatedIntervals = $intervalParser3->findInterval($wordSeparated, IntervalFlags::MULTIPLE_INTERVALS); #var_dump($wordSeparatedIntervals);
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  (null)
number of ops:  51
compiled vars:  !0 = $settings1, !1 = $settings2, !2 = $settings3, !3 = $settings4, !4 = $intervalParser1, !5 = $intervalParser2, !6 = $intervalParser3, !7 = $intervalParser4, !8 = $trailingString, !9 = $leadingString, !10 = $both, !11 = $onlyInterval, !12 = $multiple, !13 = $multipleWithSymbol, !14 = $multipleWithWord, !15 = $multipleIntervals
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   13     0  E >   DECLARE_CLASS                                            'intervalparser%5Cintervaliterator'
  570     1        NEW                                              $16     'IntervalParser%5CParserSettings'
          2        DO_FCALL                                      0          
          3        ASSIGN                                                   !0, $16
  571     4        NEW                                              $19     'IntervalParser%5CParserSettings'
          5        SEND_VAL_EX                                              0
          6        DO_FCALL                                      0          
          7        ASSIGN                                                   !1, $19
  572     8        NEW                                              $22     'IntervalParser%5CParserSettings'
          9        SEND_VAL_EX                                              1
         10        SEND_VAL_EX                                              '%2C'
         11        SEND_VAL_EX                                              'then'
         12        DO_FCALL                                      0          
         13        ASSIGN                                                   !2, $22
  573    14        NEW                                              $25     'IntervalParser%5CParserSettings'
         15        SEND_VAL_EX                                              0
         16        SEND_VAL_EX                                              '-'
         17        DO_FCALL                                      0          
         18        ASSIGN                                                   !3, $25
  575    19        NEW                                              $28     'IntervalParser%5CIntervalParser'
         20        SEND_VAR_EX                                              !0
         21        DO_FCALL                                      0          
         22        ASSIGN                                                   !4, $28
  576    23        NEW                                              $31     'IntervalParser%5CIntervalParser'
         24        SEND_VAR_EX                                              !1
         25        DO_FCALL                                      0          
         26        ASSIGN                                                   !5, $31
  577    27        NEW                                              $34     'IntervalParser%5CIntervalParser'
         28        SEND_VAR_EX                                              !2
         29        DO_FCALL                                      0          
         30        ASSIGN                                                   !6, $34
  578    31        NEW                                              $37     'IntervalParser%5CIntervalParser'
         32        SEND_VAR_EX                                              !3
         33        DO_FCALL                                      0          
         34        ASSIGN                                                   !7, $37
  584    35        ASSIGN                                                   !8, '7mon6w5d4h3m2s+bazinga%21'
  589    36        ASSIGN                                                   !9, 'foo+in+9w8d7h6m5s'
  594    37        ASSIGN                                                   !10, 'foo+in+9d8h5m+bar'
  599    38        ASSIGN                                                   !11, '9+mon+2+w+3+m+4+d'
  609    39        ASSIGN                                                   !12, 'foo+in+9d8h5m+bar+%2C+baz+in+5+minutes%2C+foo+in+2+days+4+minutes+boo%2C+in+1+hr%2C+10+days'
  610    40        ASSIGN                                                   !13, 'foo+in+9d8h5m+bar+-+baz+in+5+minutes-+foo+in+2+days+4+minutes+boo-+in+1+hr-+10+days'
  611    41        ASSIGN                                                   !14, 'foo+in+9d8h5m+bar+then+baz+in+5+minutes+then+foo+in+2+days+4+minutes+boo+then+in+1+hr+then+10+days'
  612    42        INIT_METHOD_CALL                                         !4, 'findInterval'
         43        SEND_VAR_EX                                              !12
         44        SEND_VAL_EX                                              4
         45        DO_FCALL                                      0  $47     
         46        ASSIGN                                                   !15, $47
  613    47        INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Cvar_dump'
         48        SEND_VAR_EX                                              !15
         49        DO_FCALL                                      0          
  618    50      > RETURN                                                   1

Function %00intervalparser%5C%7Bclosure%7D%2Fin%2FT5qBt%3A443%241:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 6, Position 2 = 15
Branch analysis from position: 6
2 jumps found. (Code = 78) Position 1 = 7, Position 2 = 15
Branch analysis from position: 7
2 jumps found. (Code = 43) Position 1 = 12, Position 2 = 14
Branch analysis from position: 12
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 14
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 15
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
filename:       /in/T5qBt
function name:  IntervalParser\{closure}
number of ops:  17
compiled vars:  !0 = $set, !1 = $iter, !2 = $interval, !3 = $key
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  443     0  E >   RECV                                             !0      
  444     1        NEW                                              $4      'IntervalParser%5CIntervalIterator'
          2        SEND_VAR_EX                                              !0
          3        DO_FCALL                                      0          
          4        ASSIGN                                           ~6      !1, $4
          5      > FE_RESET_R                                       $7      ~6, ->15
          6    > > FE_FETCH_R                                       ~8      $7, !2, ->15
          7    >   ASSIGN                                                   !3, ~8
  445     8        INIT_METHOD_CALL                                         !1, 'key'
          9        DO_FCALL                                      0  $10     
         10        IS_IDENTICAL                                             $10, 'match'
         11      > JMPZ                                                     ~11, ->14
  446    12    >   FE_FREE                                                  $7
         13      > RETURN                                                   !2
  444    14    > > JMP                                                      ->6
         15    >   FE_FREE                                                  $7
  449    16      > RETURN                                                   null

End of function %00intervalparser%5C%7Bclosure%7D%2Fin%2FT5qBt%3A443%241

Function %00intervalparser%5C%7Bclosure%7D%2Fin%2FT5qBt%3A502%242:
Finding entry points
Branch analysis from position: 0
9 jumps found. (Code = 188) Position 1 = 20, Position 2 = 27, Position 3 = 34, Position 4 = 41, Position 5 = 48, Position 6 = 55, Position 7 = 62, Position 8 = 69, Position 9 = 5
Branch analysis from position: 20
2 jumps found. (Code = 43) Position 1 = 22, Position 2 = 24
Branch analysis from position: 22
1 jumps found. (Code = 42) Position 1 = 25
Branch analysis from position: 25
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
2 jumps found. (Code = 43) Position 1 = 77, Position 2 = 83
Branch analysis from position: 77
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 83
Branch analysis from position: 24
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 27
2 jumps found. (Code = 43) Position 1 = 29, Position 2 = 31
Branch analysis from position: 29
1 jumps found. (Code = 42) Position 1 = 32
Branch analysis from position: 32
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 31
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 34
2 jumps found. (Code = 43) Position 1 = 36, Position 2 = 38
Branch analysis from position: 36
1 jumps found. (Code = 42) Position 1 = 39
Branch analysis from position: 39
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 38
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 41
2 jumps found. (Code = 43) Position 1 = 43, Position 2 = 45
Branch analysis from position: 43
1 jumps found. (Code = 42) Position 1 = 46
Branch analysis from position: 46
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 45
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 48
2 jumps found. (Code = 43) Position 1 = 50, Position 2 = 52
Branch analysis from position: 50
1 jumps found. (Code = 42) Position 1 = 53
Branch analysis from position: 53
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 52
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 55
2 jumps found. (Code = 43) Position 1 = 57, Position 2 = 59
Branch analysis from position: 57
1 jumps found. (Code = 42) Position 1 = 60
Branch analysis from position: 60
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 59
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 62
2 jumps found. (Code = 43) Position 1 = 64, Position 2 = 66
Branch analysis from position: 64
1 jumps found. (Code = 42) Position 1 = 67
Branch analysis from position: 67
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 66
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 69
Branch analysis from position: 5
2 jumps found. (Code = 44) Position 1 = 7, Position 2 = 20
Branch analysis from position: 7
2 jumps found. (Code = 44) Position 1 = 9, Position 2 = 27
Branch analysis from position: 9
2 jumps found. (Code = 44) Position 1 = 11, Position 2 = 34
Branch analysis from position: 11
2 jumps found. (Code = 44) Position 1 = 13, Position 2 = 41
Branch analysis from position: 13
2 jumps found. (Code = 44) Position 1 = 15, Position 2 = 48
Branch analysis from position: 15
2 jumps found. (Code = 44) Position 1 = 17, Position 2 = 55
Branch analysis from position: 17
2 jumps found. (Code = 44) Position 1 = 19, Position 2 = 62
Branch analysis from position: 19
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
Branch analysis from position: 62
Branch analysis from position: 55
Branch analysis from position: 48
Branch analysis from position: 41
Branch analysis from position: 34
Branch analysis from position: 27
Branch analysis from position: 20
filename:       /in/T5qBt
function name:  IntervalParser\{closure}
number of ops:  85
compiled vars:  !0 = $matches, !1 = $int, !2 = $t, !3 = $time
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  502     0  E >   RECV                                             !0      
  503     1        FETCH_DIM_R                                      ~4      !0, 'int'
          2        ASSIGN                                                   !1, ~4
  504     3        FETCH_DIM_R                                      ~6      !0, 'time'
          4      > SWITCH_STRING                                            ~6, [ 's':->20, 'm':->27, 'h':->34, 'd':->41, 'w':->48, 'mon':->55, 'y':->62, ], ->69
  505     5    >   CASE                                                     ~6, 's'
          6      > JMPNZ                                                    ~7, ->20
  508     7    >   CASE                                                     ~6, 'm'
          8      > JMPNZ                                                    ~7, ->27
  511     9    >   CASE                                                     ~6, 'h'
         10      > JMPNZ                                                    ~7, ->34
  514    11    >   CASE                                                     ~6, 'd'
         12      > JMPNZ                                                    ~7, ->41
  517    13    >   CASE                                                     ~6, 'w'
         14      > JMPNZ                                                    ~7, ->48
  520    15    >   CASE                                                     ~6, 'mon'
         16      > JMPNZ                                                    ~7, ->55
  523    17    >   CASE                                                     ~6, 'y'
         18      > JMPNZ                                                    ~7, ->62
         19    > > JMP                                                      ->69
  506    20    >   IS_EQUAL                                                 !1, 1
         21      > JMPZ                                                     ~8, ->24
         22    >   QM_ASSIGN                                        ~9      '+second+'
         23      > JMP                                                      ->25
         24    >   QM_ASSIGN                                        ~9      '+seconds+'
         25    >   ASSIGN                                                   !2, ~9
  507    26      > JMP                                                      ->69
  509    27    >   IS_EQUAL                                                 !1, 1
         28      > JMPZ                                                     ~11, ->31
         29    >   QM_ASSIGN                                        ~12     '+minute+'
         30      > JMP                                                      ->32
         31    >   QM_ASSIGN                                        ~12     '+minutes+'
         32    >   ASSIGN                                                   !2, ~12
  510    33      > JMP                                                      ->69
  512    34    >   IS_EQUAL                                                 !1, 1
         35      > JMPZ                                                     ~14, ->38
         36    >   QM_ASSIGN                                        ~15     '+hour+'
         37      > JMP                                                      ->39
         38    >   QM_ASSIGN                                        ~15     '+hours+'
         39    >   ASSIGN                                                   !2, ~15
  513    40      > JMP                                                      ->69
  515    41    >   IS_EQUAL                                                 !1, 1
         42      > JMPZ                                                     ~17, ->45
         43    >   QM_ASSIGN                                        ~18     '+day+'
         44      > JMP                                                      ->46
         45    >   QM_ASSIGN                                        ~18     '+days+'
         46    >   ASSIGN                                                   !2, ~18
  516    47      > JMP                                                      ->69
  518    48    >   IS_EQUAL                                                 !1, 1
         49      > JMPZ                                                     ~20, ->52
         50    >   QM_ASSIGN                                        ~21     '+week+'
         51      > JMP                                                      ->53
         52    >   QM_ASSIGN                                        ~21     '+weeks+'
         53    >   ASSIGN                                                   !2, ~21
  519    54      > JMP                                                      ->69
  521    55    >   IS_EQUAL                                                 !1, 1
         56      > JMPZ                                                     ~23, ->59
         57    >   QM_ASSIGN                                        ~24     '+month+'
         58      > JMP                                                      ->60
         59    >   QM_ASSIGN                                        ~24     '+months+'
         60    >   ASSIGN                                                   !2, ~24
  522    61      > JMP                                                      ->69
  524    62    >   IS_EQUAL                                                 !1, 1
         63      > JMPZ                                                     ~26, ->66
         64    >   QM_ASSIGN                                        ~27     '+year+'
         65      > JMP                                                      ->67
         66    >   QM_ASSIGN                                        ~27     '+years+'
         67    >   ASSIGN                                                   !2, ~27
  525    68      > JMP                                                      ->69
         69    >   FREE                                                     ~6
  528    70        COALESCE                                         ~29     !2
         71        QM_ASSIGN                                        ~29     ''
         72        ASSIGN                                                   !2, ~29
  530    73        CONCAT                                           ~31     !1, !2
         74        ASSIGN                                                   !3, ~31
  532    75        ISSET_ISEMPTY_DIM_OBJ                         0          !0, 'text'
         76      > JMPZ                                                     ~33, ->83
  533    77    >   INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Ctrim'
         78        CHECK_FUNC_ARG                                           
         79        FETCH_DIM_FUNC_ARG                               $34     !0, 'text'
         80        SEND_FUNC_ARG                                            $34
         81        DO_FCALL                                      0  $35     
         82        ASSIGN_OP                                     8          !3, $35
  536    83    > > RETURN                                                   !3
  538    84*     > RETURN                                                   null

End of function %00intervalparser%5C%7Bclosure%7D%2Fin%2FT5qBt%3A502%242

Class IntervalParser\Exception: [no user functions]
Class IntervalParser\FormatException: [no user functions]
Class IntervalParser\IntervalIterator:
Function __construct:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 5, Position 2 = 7
Branch analysis from position: 5
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 7
filename:       /in/T5qBt
function name:  __construct
number of ops:  8
compiled vars:  !0 = $array
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   17     0  E >   RECV                                             !0      
   19     1        INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Cis_array'
          2        SEND_VAR_EX                                              !0
          3        DO_FCALL                                      0  $1      
          4      > JMPZ                                                     $1, ->7
   20     5    >   ASSIGN_OBJ                                               'var'
          6        OP_DATA                                                  !0
   22     7    > > RETURN                                                   null

End of function __construct

Function rewind:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  rewind
number of ops:  6
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   27     0  E >   INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Creset'
          1        CHECK_FUNC_ARG                                           
          2        FETCH_OBJ_FUNC_ARG                               $0      'var'
          3        SEND_FUNC_ARG                                            $0
          4        DO_FCALL                                      0          
   28     5      > RETURN                                                   null

End of function rewind

Function current:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  current
number of ops:  8
compiled vars:  !0 = $var
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   32     0  E >   INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Ccurrent'
          1        CHECK_FUNC_ARG                                           
          2        FETCH_OBJ_FUNC_ARG                               $1      'var'
          3        SEND_FUNC_ARG                                            $1
          4        DO_FCALL                                      0  $2      
          5        ASSIGN                                                   !0, $2
   34     6      > RETURN                                                   !0
   35     7*     > RETURN                                                   null

End of function current

Function key:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  key
number of ops:  8
compiled vars:  !0 = $var
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   39     0  E >   INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Ckey'
          1        CHECK_FUNC_ARG                                           
          2        FETCH_OBJ_FUNC_ARG                               $1      'var'
          3        SEND_FUNC_ARG                                            $1
          4        DO_FCALL                                      0  $2      
          5        ASSIGN                                                   !0, $2
   41     6      > RETURN                                                   !0
   42     7*     > RETURN                                                   null

End of function key

Function next:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  next
number of ops:  8
compiled vars:  !0 = $var
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   46     0  E >   INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Cnext'
          1        CHECK_FUNC_ARG                                           
          2        FETCH_OBJ_FUNC_ARG                               $1      'var'
          3        SEND_FUNC_ARG                                            $1
          4        DO_FCALL                                      0  $2      
          5        ASSIGN                                                   !0, $2
   48     6      > RETURN                                                   !0
   49     7*     > RETURN                                                   null

End of function next

Function valid:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 46) Position 1 = 8, Position 2 = 10
Branch analysis from position: 8
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 10
filename:       /in/T5qBt
function name:  valid
number of ops:  13
compiled vars:  !0 = $key, !1 = $var
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   53     0  E >   INIT_NS_FCALL_BY_NAME                                    'IntervalParser%5Ckey'
          1        CHECK_FUNC_ARG                                           
          2        FETCH_OBJ_FUNC_ARG                               $2      'var'
          3        SEND_FUNC_ARG                                            $2
          4        DO_FCALL                                      0  $3      
          5        ASSIGN                                                   !0, $3
   54     6        TYPE_CHECK                                  1020  ~5      !0
          7      > JMPZ_EX                                          ~5      ~5, ->10
          8    >   TYPE_CHECK                                  1018  ~6      !0
          9        BOOL                                             ~5      ~6
         10    >   ASSIGN                                                   !1, ~5
   56    11      > RETURN                                                   !1
   57    12*     > RETURN                                                   null

End of function valid

End of class IntervalParser\IntervalIterator.

Class IntervalParser\ParserSettings:
Function __construct:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  __construct
number of ops:  10
compiled vars:  !0 = $separationType, !1 = $symbol, !2 = $word
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   92     0  E >   RECV_INIT                                        !0      <const ast>
          1        RECV_INIT                                        !1      '%2C'
          2        RECV_INIT                                        !2      null
   98     3        ASSIGN_OBJ                                               'separationType'
          4        OP_DATA                                                  !0
   99     5        ASSIGN_OBJ                                               'word'
          6        OP_DATA                                                  !2
  100     7        ASSIGN_OBJ                                               'symbol'
          8        OP_DATA                                                  !1
  101     9      > RETURN                                                   null

End of function __construct

Function getsymbolseparator:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  getSymbolSeparator
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  105     0  E >   FETCH_OBJ_R                                      ~0      'symbol'
          1        VERIFY_RETURN_TYPE                                       ~0
          2      > RETURN                                                   ~0
  106     3*       VERIFY_RETURN_TYPE                                       
          4*     > RETURN                                                   null

End of function getsymbolseparator

Function getwordseparator:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  getWordSeparator
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  110     0  E >   FETCH_OBJ_R                                      ~0      'word'
          1        VERIFY_RETURN_TYPE                                       ~0
          2      > RETURN                                                   ~0
  111     3*       VERIFY_RETURN_TYPE                                       
          4*     > RETURN                                                   null

End of function getwordseparator

Function getseparationtype:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 4, Position 2 = 6
Branch analysis from position: 4
1 jumps found. (Code = 42) Position 1 = 7
Branch analysis from position: 7
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 6
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  getSeparationType
number of ops:  11
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  115     0  E >   FETCH_OBJ_R                                      ~0      'separationType'
          1        FETCH_CLASS_CONSTANT                             ~1      'STRING'
          2        IS_EQUAL                                                 ~0, ~1
          3      > JMPZ                                                     ~2, ->6
          4    >   QM_ASSIGN                                        ~3      'string'
          5      > JMP                                                      ->7
          6    >   QM_ASSIGN                                        ~3      'symbol'
          7    >   VERIFY_RETURN_TYPE                                       ~3
          8      > RETURN                                                   ~3
  116     9*       VERIFY_RETURN_TYPE                                       
         10*     > RETURN                                                   null

End of function getseparationtype

End of class IntervalParser\ParserSettings.

Class IntervalParser\IntervalFlags: [no user functions]
Class IntervalParser\TimeInterval:
Function __construct:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/T5qBt
function name:  __construct
number of ops:  16
compiled vars:  !0 = $intervalOffset, !1 = $intervalLength, !2 = $leadingData, !3 = $trailingData, !4 = $interval
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  137     0  E >   RECV                                             !0      
          1        RECV                                             !1      
          2        RECV_INIT                                        !2      null
          3        RECV_INIT                                        !3      null
          4        RECV                                             !4      
  146     5        ASSIGN_OBJ                                               'interval'
          6        OP_DATA                                                  !4
  147     7        ASSIGN_OBJ                                               'intervalOffset'
          8        OP_DATA                                                  !0
  148     9        ASSIGN_OBJ                                               'intervalL

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
165.2 ms | 1433 KiB | 27 Q