public function consumeString($delimiter, $type)
    {
        $close = Utils::balanceDelimiter($delimiter);

        $balanced = $close !== $delimiter;
        $patterns = array('/(?<!\\\\)((?:\\\\\\\\)*)(' . preg_quote($close, '/') . ')/');

        if ($balanced) {
            $patterns[] = '/(?<!\\\\)((?:\\\\\\\\)*)(' . preg_quote($delimiter, '/') . ')/';
        }

        $stack = 1; // we're already inside the string
        $start = $this->pos();
        $closeDelimiterMatch = null;
        while ($stack) {
            $next = $this->getNext($patterns);
            if ($next[0] === -1) {
                $this->terminate();
                $finish = $this->pos();
                break;
            } elseif ($balanced && $next[1][2] === $delimiter) {
                $stack++;
                $finish = $next[0] + strlen($next[1][0]);
            } elseif ($next[1][2] === $close) {
                $stack--;
                if (!$stack) {
                    $closeDelimiterMatch = $next[1][2];
                }
                $finish = $next[0] + strlen($next[1][1]);
            } else {
                assert(0);
            }
            $this->pos($next[0] + strlen($next[1][0]));
        }
        $substr = substr($this->string(), $start, $finish - $start);
        // special case for qw, the string is not a 'STRING', it is actually
        // a whitespace separated list of strings. So we need to split it and
        // record them separately
        if ($type === 'SPLIT_STRING') {
            foreach (preg_split('/(\s+)/', $substr, -1, PREG_SPLIT_DELIM_CAPTURE) as $token) {
                if (preg_match('/^\s/', $token)) {
                    $this->record($token, null);
                } else {
                    $this->record($token, 'STRING');
                }
            }
        } else {
            $this->record($substr, $type);
        }
        if ($closeDelimiterMatch !== null) {
            $this->record($closeDelimiterMatch, 'DELIMITER');
        }
    }