|
<?php |
|
|
|
namespace Kanboard\Core\Filter; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Lexer |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
private $offset = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private $tokenMap = array( |
|
'/^(\s+)/' => 'T_WHITESPACE', |
|
'/^([<=>]{0,2}[0-9]{4}-[0-9]{2}-[0-9]{2})/' => 'T_STRING', |
|
'/^([<=>]{1,2}\w+)/u' => 'T_STRING', |
|
'/^([<=>]{1,2}".+")/' => 'T_STRING', |
|
'/^("(.*?)")/' => 'T_STRING', |
|
'/^(\S+)/u' => 'T_STRING', |
|
'/^(#\d+)/' => 'T_STRING', |
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private $defaultToken = ''; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function addToken($regex, $token) |
|
{ |
|
$this->tokenMap = array($regex => $token) + $this->tokenMap; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setDefaultToken($token) |
|
{ |
|
$this->defaultToken = $token; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function tokenize($input) |
|
{ |
|
$tokens = array(); |
|
$this->offset = 0; |
|
$input_length = mb_strlen($input, 'UTF-8'); |
|
|
|
while ($this->offset < $input_length) { |
|
$result = $this->match(mb_substr($input, $this->offset, $input_length, 'UTF-8')); |
|
|
|
if ($result === false) { |
|
return array(); |
|
} |
|
|
|
$tokens[] = $result; |
|
} |
|
|
|
return $this->map($tokens); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function match($string) |
|
{ |
|
foreach ($this->tokenMap as $pattern => $name) { |
|
if (preg_match($pattern, $string, $matches)) { |
|
$this->offset += mb_strlen($matches[1], 'UTF-8'); |
|
|
|
return array( |
|
'match' => str_replace('"', '', $matches[1]), |
|
'token' => $name, |
|
); |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function map(array $tokens) |
|
{ |
|
$map = array(); |
|
$leftOver = ''; |
|
|
|
while (false !== ($token = current($tokens))) { |
|
if ($token['token'] === 'T_STRING' || $token['token'] === 'T_WHITESPACE') { |
|
$leftOver .= $token['match']; |
|
} else { |
|
$next = next($tokens); |
|
|
|
if ($next !== false && $next['token'] === 'T_STRING') { |
|
$map[$token['token']][] = $next['match']; |
|
} |
|
} |
|
|
|
next($tokens); |
|
} |
|
|
|
$leftOver = trim($leftOver); |
|
|
|
if ($this->defaultToken !== '' && $leftOver !== '') { |
|
$map[$this->defaultToken] = array($leftOver); |
|
} |
|
|
|
return $map; |
|
} |
|
} |
|
|