81 $tokenizer =
new self;
82 $tokenizer->_tokenize($sql);
83 $tokenizer->makeLines();
84 $tokenizer->makeParenthesis();
97 $tokenizer =
new self;
161 return !isset($this->tokens[$this->index]);
171 public function getPrevToken()
174 $token = $this->tokens[$this->index - 1] ??
null;
185 public function getCurrentToken()
199 public function nextToken()
212 public function nextNotWhiteSpaceToken()
214 $i = $this->index + 1;
215 while (isset($this->tokens[$i]))
218 $token = $this->tokens[$i];
228 return $this->tokens[$i] ??
null;
236 public function skipWhiteSpace()
238 while (isset($this->tokens[$this->index]))
262 public function testUpperText($text)
264 if (isset($this->tokens[$this->index]))
268 if ($token->upper === $text)
286 public function testText($text)
288 if (isset($this->tokens[$this->index]))
292 if ($token->upper === $text)
308 private function _tokenize($sql)
313 $rawTokens = preg_split(
"/(
314 [ \\t\\n\\r]+ # WHITESPACE
318 |`[^`]+` # BACK QUOTE
319 |\\[[^\\]]+\\] # SQUARE QUOTE
320 |\\/\\*.*?\\*\\/ # COMMENTARY
321 |--.*?\\n # COMMENTARY
322 |\\#[^']*?\\n # COMMENTARY
323 |[" . preg_quote($chars,
'/') .
'] # CHARACTER
324 )/xs', $sql, -1, PREG_SPLIT_DELIM_CAPTURE);
325 $isInSingleQuote =
false;
326 $isInDoubleQuote =
false;
327 foreach ($rawTokens as $rawToken)
329 if ($rawToken ===
'')
335 $prevToken = $this->tokens[$tokenCount - 1] ??
null;
337 if ($isInSingleQuote)
339 $prevToken->appendText($rawToken);
342 && preg_match(
"/(\\\\)*'\$/", $prevToken->text, $match)
344 mb_strlen($match[0]) === 0
345 || (mb_strlen($match[0]) % 2) === 1
349 $isInSingleQuote =
false;
352 elseif ($isInDoubleQuote)
354 $prevToken->appendText($rawToken);
357 && preg_match(
'/(\\\\)*"$/', $prevToken->text, $match)
358 && (mb_strlen($match[0]) % 2) === 1
361 $isInDoubleQuote =
false;
364 elseif ($rawToken[0] ===
'`')
368 elseif ($rawToken[0] ===
'[')
373 ($rawToken[0] ===
'/' && $rawToken[1] ===
'*')
374 || ($rawToken[0] ===
'-' && $rawToken[1] ===
'-')
375 || ($rawToken[0] ===
'#')
380 elseif (mb_strlen($rawToken) == 1 && mb_strpos($chars, $rawToken) !==
false)
382 $this->tokens[$tokenCount++] =
new Token(
Token::T_CHAR, $rawToken);
384 elseif ($rawToken ===
'"')
387 $isInDoubleQuote =
true;
389 elseif ($rawToken ===
"'")
392 $isInSingleQuote =
true;
394 elseif (preg_match(
"/^[ \\t\\n\\r]+\$/", $rawToken))
402 $prevToken->appendText($rawToken);
417 private function makeLines()
421 foreach ($this->tokens as $token)
423 $token->line = $line;
424 if (preg_match_all(
"/\\n/", $token->text, $m))
426 $line += count($m[0]);
436 private function makeParenthesis()
440 foreach ($this->tokens as $token)
442 if ($token->text ===
')')
446 $token->level = $level;
447 if ($token->text ===
'(')