function str_override($matches) { $this->pos($this->pos() + strlen($matches[0])); $this->record($matches[0], 'DELIMITER'); $f = $matches[1]; $type = 'STRING'; if ($f === 'm' || $f === 'qr' || $f === 's' || $f === 'tr' || $f === 'y') { $type = 'REGEX'; } elseif ($f === 'qw') { $type = 'SPLIT_STRING'; } $this->consume_string($matches[3], $type); if ($f === 's' || $f === 'tr' || $f === 'y') { // s/tr/y take two strings, e.g. s/something/somethingelse/, so we // have to consume the next delimiter (if it exists) and consume the // string, again. // if delims were balanced, there's a new delimiter right here, e.g. // s[something][somethingelse] $this->skip_whitespace(); $balanced = LuminousUtils::balance_delimiter($matches[3]) !== $matches[3]; if ($balanced) { $delim2 = $this->scan('/[^a-zA-Z0-9]/'); if ($delim2 !== null) { $this->record($delim2, 'DELIMITER'); $this->consume_string($delim2, 'STRING'); } } else { $this->consume_string($matches[3], 'STRING'); } } if ($type === 'REGEX' && $this->scan('/[cgimosxpe]+/')) { $this->record($this->match(), 'KEYWORD'); } }
public function main() { while (!$this->eos()) { if ($this->bol() && !empty($this->heredocs)) { $this->do_heredoc(); } if ($this->interpolation) { $c = $this->peek(); if ($c === '{') { $this->curley_braces++; } elseif ($c === '}') { $this->curley_braces--; if ($this->curley_braces <= 0) { break; } } } if ($this->rails && $this->check('/-?%>/')) { break; } $c = $this->peek(); if ($c === '=' && $this->scan('/^=begin .*? (^=end|\\z)/msx')) { $this->record($this->match(), 'DOCCOMMENT'); } elseif ($c === '#' && $this->scan($this->comment_regex)) { $this->record($this->match(), 'COMMENT'); } elseif ($this->scan($this->numeric) !== null) { $this->record($this->match(), 'NUMERIC'); } elseif ($c === '$' && $this->scan('/\\$ (?: (?:[!@`\'\\+1~=\\/\\\\,;\\._0\\*\\$\\?:"&<>]) | (?: -[0adFiIlpvw]) | (?:DEBUG|FILENAME|LOAD_PATH|stderr|stdin|stdout|VERBOSE) )/x') || $this->scan('/(\\$|@@?)\\w+/')) { $this->record($this->match(), 'VARIABLE'); } elseif ($this->scan('/:\\w+/')) { $this->record($this->match(), 'VALUE'); } elseif ($c === '<' && $this->scan('/(<<(-?))([\'"`]?)([A-Z_]\\w*)(\\3)/i')) { $m = $this->match_groups(); $this->record($m[0], 'DELIMITER'); $hdoc = array($m[4], $m[2] === '-', $m[3] !== "'"); $this->heredocs[] = $hdoc; } elseif (($c === '"' || $c === "'" || $c === '`' || $c === '%') && $this->scan('/[\'"`]|%( [qQrswWx](?![[:alnum:]]|$) | (?![[:alnum:]\\s]|$))/xm') || $c === '/' && $this->is_regex()) { $interpolation = false; $type = 'STRING'; $delimiter; $pos; $fancy_delim = false; $split = false; if ($c === '/') { $interpolation = true; $type = 'REGEX'; $delimiter = $c; $pos = $this->pos(); $this->get(); } else { $pos = $this->match_pos(); $delimiter = $this->match(); if ($delimiter === '"') { $interpolation = true; } elseif ($delimiter === "'") { } elseif ($delimiter === '`') { $type = 'FUNCTION'; } else { $delimiter = $this->get(); $m1 = $this->match_group(1); if ($m1 === 'Q' || $m1 === 'r' || $m1 === 'W' || $m1 === 'x') { $interpolation = true; } if ($m1 === 'w' || $m1 === 'W') { $split = true; } if ($m1 === 'x') { $type = 'FUNCTION'; } elseif ($m1 === 'r') { $type = 'REGEX'; } $fancy_delim = true; $this->record($this->match() . $delimiter, 'DELIMITER'); $pos = $this->pos(); } } $data = array($type, $delimiter, LuminousUtils::balance_delimiter($delimiter), $pos, $interpolation, $fancy_delim, $split); $this->do_string($data); } elseif ((ctype_alpha($c) || $c === '_') && ($m = $this->scan('/[_a-zA-Z]\\w*[!?]?/')) !== null) { $this->record($m, ctype_upper($m[0]) ? 'CONSTANT' : 'IDENT'); if ($m === '__END__') { if (!$this->interpolation) { $this->record($this->rest(), null); $this->terminate(); } break; } } elseif ($this->scan($this->operator_regex)) { $this->record($this->match(), 'OPERATOR'); } elseif ($this->scan("/[ \t]+/")) { $this->record($this->match(), null); } else { $this->record($this->get(), null); } } // In case not everything was popped if (isset($this->state_[0])) { $this->record(substr($this->string(), $this->state_[0][3], $this->pos() - $this->state_[0][3]), $this->state_[0][0]); $this->terminate(); } }