/** * Implementation of “simple”. * * @return mixed * @throws \Hoa\Compiler\Exception * @throws \Hoa\Compiler\Exception\Rule */ protected function simple(&$pNodeId) { if ('capturing_' === $this->getCurrentToken()) { $this->consumeToken(); $rule = $this->choice($pNodeId); if (null === $rule) { return null; } if ('_capturing' != $this->getCurrentToken()) { return null; } $this->consumeToken(); return $rule; } if ('skipped' === $this->getCurrentToken()) { $tokenName = trim($this->getCurrentToken('value'), ':'); if (']' === substr($tokenName, -1)) { $uId = (int) substr($tokenName, strpos($tokenName, '[') + 1, -1); $tokenName = substr($tokenName, 0, strpos($tokenName, '[')); } else { $uId = -1; } $exists = false; foreach ($this->_tokens as $namespace => $tokens) { foreach ($tokens as $token => $value) { if ($token === $tokenName || substr($token, 0, strpos($token, ':')) === $tokenName) { $exists = true; break 2; } } } if (false == $exists) { throw new Compiler\Exception('Token ::%s:: does not exist in%s.', 3, [$tokenName, $this->_rule]); } $name = count($this->_createdRules) + 1; $this->_createdRules[$name] = new Token($name, $tokenName, null, $uId); $this->consumeToken(); return $name; } if ('kept' === $this->getCurrentToken()) { $tokenName = trim($this->getCurrentToken('value'), '<>'); if (']' === substr($tokenName, -1)) { $uId = (int) substr($tokenName, strpos($tokenName, '[') + 1, -1); $tokenName = substr($tokenName, 0, strpos($tokenName, '[')); } else { $uId = -1; } $exists = false; foreach ($this->_tokens as $namespace => $tokens) { foreach ($tokens as $token => $value) { if ($token === $tokenName || substr($token, 0, strpos($token, ':')) === $tokenName) { $exists = true; break 2; } } } if (false == $exists) { throw new Compiler\Exception('Token <%s> does not exist in%s.', 4, [$tokenName, $this->_rule]); } $name = count($this->_createdRules) + 1; $token = new Token($name, $tokenName, null, $uId); $token->setKept(true); $this->_createdRules[$name] = $token; $this->consumeToken(); return $name; } if ('named' === $this->getCurrentToken()) { $tokenName = rtrim($this->getCurrentToken('value'), '()'); if (false === array_key_exists($tokenName, $this->_rules) && false === array_key_exists('#' . $tokenName, $this->_rules)) { throw new Compiler\Exception\Rule('Rule %s() does not exist.', 5, $tokenName); } if (0 == $this->_currentState && 'EOF' === $this->getNextToken()) { $name = count($this->_createdRules) + 1; $this->_createdRules[$name] = new Concatenation($name, [$tokenName], null); } else { $name = $tokenName; } $this->consumeToken(); return $name; } return null; }
/** * Complete a token (namespace and representation). * It returns the next namespace. * * @param \Hoa\Compiler\Llk\Rule\Token $token Token. * @return string */ protected function completeToken(Compiler\Llk\Rule\Token $token) { if (null !== $token->getRepresentation()) { return $this->_currentNamespace; } $name = $token->getTokenName(); $token->setNamespace($this->_currentNamespace); $toNamespace = $this->_currentNamespace; if (isset($this->_tokens[$this->_currentNamespace][$name])) { $token->setRepresentation($this->_tokens[$this->_currentNamespace][$name]); } else { foreach ($this->_tokens[$this->_currentNamespace] as $_name => $regex) { if (false === strpos($_name, ':')) { continue; } list($_name, $toNamespace) = explode(':', $_name, 2); if ($_name === $name) { break; } } $token->setRepresentation($regex); } return $toNamespace; }