/** * @param \Carrooi\Tokenizer\Parsing\Lexer $lexer * @return int */ function match(Lexer $lexer) { $tokens = []; foreach ($this->tokens as $token) { if ($token instanceof AbstractModifier || $token instanceof Matcher) { $token = $this->builder->_matchToken($lexer, $token); if (is_array($token) && Helpers::isListOfValidTokens($token)) { return $token; } elseif ($token !== false) { $tokens[] = $token; } } else { $tokens[] = $token; } } if (!$lexer->isNextToken($tokens)) { return false; } $result = []; while (true) { $peek = $lexer->peek(); if (!$peek) { break; } if (Helpers::isTokenA($peek['type'], $tokens)) { $result[] = $peek; } else { $lexer->resetPeek(); break; } } return count($result) ? $result : false; }
/** * @param \Carrooi\Tokenizer\Parsing\Lexer $lexer * @return bool|array|null */ function match(Lexer $lexer) { $token = $this->token instanceof AbstractModifier || $this->token instanceof Matcher ? $this->builder->_matchToken($lexer, $this->token) : $this->token; if ($token === false) { return null; } elseif ($token === true) { return true; } elseif (is_int($token)) { return $lexer->isNextToken($token) ? true : null; } else { return $token; } }
/** * @param \Carrooi\Tokenizer\Parsing\Lexer $lexer * @param array $tokens * @return array|null */ private function matchTokens(Lexer $lexer, array $tokens) { $result = []; foreach ($tokens as $select) { $token = $this->matcher->_matchToken($lexer, $select); if ($select instanceof Matcher && $token) { if (!$token[0]) { return null; } $result[] = $token[0]; } elseif ($token !== false) { $result[] = $token; } } return count($result) ? $result : null; }
/** * @param \Carrooi\Tokenizer\Parsing\Lexer $lexer * @return array|bool */ function match(Lexer $lexer) { $startToken = $this->startToken instanceof AbstractModifier ? $this->builder->_matchToken($lexer, $this->startToken) : $this->startToken; $endToken = $this->endToken instanceof AbstractModifier ? $this->builder->_matchToken($lexer, $this->endToken) : $this->endToken; if (!$lexer->isNextToken($startToken)) { return false; } $openings = 0; $result = []; while (true) { $peek = $lexer->peek(); if (!$peek) { break; } if (Helpers::isTokenA($peek['type'], $startToken)) { $openings++; if ($openings > 1 && $this->recursive) { $subTokens = array_slice($lexer->tokens, $lexer->position + $lexer->peekPosition - 1); $subLexer = new Lexer($subTokens); $parenthesis = $this->match($subLexer); if (!$parenthesis) { return false; } $moveTo = $subLexer->peekPosition - 1; for ($i = 0; $i < $moveTo; $i++) { $lexer->peek(); } $openings--; $result[] = $parenthesis; } else { $result[] = $peek; } } else { $result[] = $peek; if (Helpers::isTokenA($peek['type'], $endToken) && --$openings < 1) { break; } } } return count($result) ? $result : false; }
/** * @return \Carrooi\Tokenizer\Matching\Matcher */ public function classDeclaration() { $typeMatcher = new Matcher(); $typeMatcher->select($typeMatcher->expr()->anyOf(Lexer::T_FINAL, Lexer::T_ABSTRACT), Lexer::T_WHITESPACE); $extendsMatcher = new Matcher(); $extendsMatcher->select(Lexer::T_WHITESPACE, Lexer::T_EXTENDS, Lexer::T_WHITESPACE, $this->className()); $implementsDelimiterMatcher = new Matcher(); $implementsDelimiterMatcher->select($implementsDelimiterMatcher->expr()->notRequired(Lexer::T_WHITESPACE), Lexer::T_COMMA, $implementsDelimiterMatcher->expr()->notRequired(Lexer::T_WHITESPACE)); $implementsMatcher = new Matcher(); $implementsMatcher->select(Lexer::T_WHITESPACE, Lexer::T_IMPLEMENTS, Lexer::T_WHITESPACE, $implementsMatcher->expr()->listOf($implementsDelimiterMatcher, $this->className())); $matcher = new Matcher(); $matcher->select($matcher->expr()->notRequired($typeMatcher), Lexer::T_CLASS, Lexer::T_WHITESPACE, Lexer::T_STRING, $matcher->expr()->notRequired($extendsMatcher), $matcher->expr()->notRequired($implementsMatcher)); $matcher->map(new ResultMapping(function (array $tokens) { $class = new ClassDeclaration(Helpers::flattenTokens($tokens), $tokens[3]['value']); if ($tokens[0]) { if ($tokens[0][0]['type'] === Lexer::T_FINAL) { $class->final = true; } if ($tokens[0][0]['type'] === Lexer::T_ABSTRACT) { $class->abstract = true; } } if ($tokens[4] && $tokens[4][3]) { $class->extends = $tokens[4][3]; } if ($tokens[5]) { $implements = array_slice($tokens[5], 3); $implements = array_filter($implements, function ($token) { return $token instanceof ClassNameExpression; }); $class->implements = array_values($implements); } return $class; })); return $matcher; }