public static function positionForSequence(array $sequence, $tokens, $startFrom = null)
    {
        $seqIterator = (new ArrayObject($sequence))->getIterator();
        $tokenIterator = (new ArrayObject($tokens))->getIterator();
        if ($startFrom != null) {
            $tokenIterator->seek($startFrom);
        }
        while ($tokenIterator->valid()) {
            $seqIterator->rewind();
            $keys = array();
            list($allowedTokens, $timesAllowed) = $seqIterator->current();
            self::seekToNextType($tokenIterator, $allowedTokens);
            while ($tokenIterator->valid()) {
                if (!$seqIterator->valid()) {
                    $first = array_shift($keys);
                    $last = array_pop($keys);

                    return array($first, $last);
                }

                list($allowedTokens, $timesAllowed) = $seqIterator->current();
                if ($timesAllowed == '*') {
                    while ($tokenIterator->valid() && self::isTokenType($tokenIterator->current(),
                            $allowedTokens)) {
                        $keys[] = $tokenIterator->key();
                        $tokenIterator->next();
                    }
                } else {
                    for ($i = 0; $i < $timesAllowed; $i++) {
                        if (self::isTokenType($tokenIterator->current(), $allowedTokens)) {
                            $keys[] = $tokenIterator->key();
                            $tokenIterator->next();
                        } else {
                            continue 3;
                        }
                    }
                }
                $seqIterator->next();
            }
        }
    }
public static function positionForSequence(array $sequence, $tokens, $startFrom = null)
    {
        $seqIterator = (new ArrayObject($sequence))->getIterator();
        $tokenIterator = (new ArrayObject($tokens))->getIterator();
        if ($startFrom != null) {
            $tokenIterator->seek($startFrom);
        }
        while ($tokenIterator->valid()) {
            $seqIterator->rewind();
            $keys = array();
            list($allowedTokens, $timesAllowed) = $seqIterator->current();
            self::seekToNextType($tokenIterator, $allowedTokens);
            while ($tokenIterator->valid()) {
                if (!$seqIterator->valid()) {
                    $first = array_shift($keys);
                    $last = array_pop($keys);

                    return array($first, $last);
                }

                list($allowedTokens, $timesAllowed) = $seqIterator->current();
                if ($timesAllowed == '*') {
                    while ($tokenIterator->valid() && self::isTokenType($tokenIterator->current(),
                            $allowedTokens)) {
                        $keys[] = $tokenIterator->key();
                        $tokenIterator->next();
                    }
                } else {
                    for ($i = 0; $i < $timesAllowed; $i++) {
                        if (self::isTokenType($tokenIterator->current(), $allowedTokens)) {
                            $keys[] = $tokenIterator->key();
                            $tokenIterator->next();
                        } else {
                            continue 3;
                        }
                    }
                }
                $seqIterator->next();
            }
        }
    }
public static function positionForSequence ( array $ sequence , $ tokens , $ startFrom = null ) { $ seqIterator = ( new ArrayObject ( $ sequence ) ) -> getIterator ( ) ; $ tokenIterator = ( new ArrayObject ( $ tokens ) ) -> getIterator ( ) ; if ( $ startFrom != null ) { $ tokenIterator -> seek ( $ startFrom ) ; } while ( $ tokenIterator -> valid ( ) ) { $ seqIterator -> rewind ( ) ; $ keys = array ( ) ; list ( $ allowedTokens , $ timesAllowed ) = $ seqIterator -> current ( ) ; self :: seekToNextType ( $ tokenIterator , $ allowedTokens ) ; while ( $ tokenIterator -> valid ( ) ) { if ( ! $ seqIterator -> valid ( ) ) { $ first = array_shift ( $ keys ) ; $ last = array_pop ( $ keys ) ; return array ( $ first , $ last ) ; } list ( $ allowedTokens , $ timesAllowed ) = $ seqIterator -> current ( ) ; if ( $ timesAllowed == '*' ) { while ( $ tokenIterator -> valid ( ) && self :: isTokenType ( $ tokenIterator -> current ( ) , $ allowedTokens ) ) { $ keys [ ] = $ tokenIterator -> key ( ) ; $ tokenIterator -> next ( ) ; } } else { for ( $ i = 0 ; $ i < $ timesAllowed ; $ i ++ ) { if ( self :: isTokenType ( $ tokenIterator -> current ( ) , $ allowedTokens ) ) { $ keys [ ] = $ tokenIterator -> key ( ) ; $ tokenIterator -> next ( ) ; } else { continue 3 ; } } } $ seqIterator -> next ( ) ; } } }
Utility method to find a sequence of tokens matching the specified tokenisation pattern.

@param array $sequence the tokenisation sequence pattern to match
@param array $tokens the array of tokens to match as returned by token_get_all
@param int $startFrom an optional starting index from which to begin searching
@return array the start and end position of the tokenisation sequence pattern
Utility method to find a sequence of tokens matching the specified tokenisation pattern .