Ejemplo n.º 1
0
 /**
  * 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;
 }
Ejemplo n.º 2
0
 /**
  * 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;
 }