Beispiel #1
0
 public function testSkip()
 {
     $text = "1 foo: bar ( 3 + double ) ";
     $tokens = new Tokenizer($text);
     $tokens->skip()->skip(T_STRING)->skip(':');
     try {
         $tokens->skip(T_STRING)->skip('(')->skip(':');
     } catch (\Exception $e) {
         $this->assertInstanceOf('Fenom\\Error\\UnexpectedTokenException', $e);
         $this->assertStringStartsWith("Unexpected token '3' in expression, expect ':'", $e->getMessage());
     }
     $this->assertTrue($tokens->valid());
     $this->assertSame("3", $tokens->current());
     $this->assertSame(T_LNUMBER, $tokens->key());
     $this->assertSame($tokens, $tokens->next());
     $tokens->next();
     $this->assertSame("double", $tokens->getAndNext());
     $this->assertSame(")", $tokens->current());
     $this->assertTrue($tokens->isLast());
     $this->assertSame($tokens, $tokens->next());
     $tokens->p = 1000;
     $this->assertSame($tokens, $tokens->next());
     $tokens->p = -1000;
     $this->assertSame($tokens, $tokens->back());
     $this->assertNull($tokens->undef);
 }
 public function __construct(Tokenizer $tokens, $expect = null, $where = null)
 {
     if ($expect && count($expect) == 1 && is_string($expect[0])) {
         $expect = ", expect '" . $expect[0] . "'";
     } else {
         $expect = "";
     }
     if (!$tokens->curr) {
         $this->message = "Unexpected end of " . ($where ?: "expression") . "{$expect}";
     } else {
         $this->message = "Unexpected token '" . $tokens->current() . "' in " . ($where ?: "expression") . "{$expect}";
     }
 }
Beispiel #3
0
 /**
  * Import macros from templates
  *
  * @param Tokenizer $tokens
  * @param Template $tpl
  * @throws UnexpectedTokenException
  * @throws InvalidUsageException
  * @return string
  */
 public static function tagImport(Tokenizer $tokens, Template $tpl)
 {
     $import = array();
     if ($tokens->is('[')) {
         $tokens->next();
         while ($tokens->valid()) {
             if ($tokens->is(Tokenizer::MACRO_STRING)) {
                 $import[$tokens->current()] = true;
                 $tokens->next();
             } elseif ($tokens->is(']')) {
                 $tokens->next();
                 break;
             } elseif ($tokens->is(',')) {
                 $tokens->next();
             } else {
                 break;
             }
         }
         if ($tokens->current() != "from") {
             throw new UnexpectedTokenException($tokens);
         }
         $tokens->next();
     }
     $tpl->parsePlainArg($tokens, $name);
     if (!$name) {
         throw new InvalidUsageException("Invalid usage tag {import}");
     }
     if ($tokens->is(T_AS)) {
         $alias = $tokens->next()->get(Tokenizer::MACRO_STRING);
         if ($alias === "macro") {
             $alias = "";
         }
         $tokens->next();
     } else {
         $alias = "";
     }
     $donor = $tpl->getStorage()->getRawTemplate()->load($name, true);
     if ($donor->macros) {
         foreach ($donor->macros as $name => $macro) {
             if ($p = strpos($name, ".")) {
                 $name = substr($name, $p);
             }
             if ($import && !isset($import[$name])) {
                 continue;
             }
             if ($alias) {
                 $name = $alias . '.' . $name;
             }
             $tpl->macros[$name] = $macro;
         }
         $tpl->addDepend($donor);
     }
     return '';
 }
Beispiel #4
0
 /**
  * Parse string with or without variable
  *
  * @param Tokenizer $tokens
  * @throws UnexpectedTokenException
  * @return string
  */
 public function parseQuote(Tokenizer $tokens)
 {
     if ($tokens->is('"')) {
         $stop = $tokens->current();
         $_str = '"';
         $tokens->next();
         while ($t = $tokens->key()) {
             if ($t === T_ENCAPSED_AND_WHITESPACE) {
                 $_str .= $tokens->current();
                 $tokens->next();
             } elseif ($t === T_VARIABLE) {
                 if (strlen($_str) > 1) {
                     $_str .= '".';
                 } else {
                     $_str = "";
                 }
                 $_str .= '$var["' . substr($tokens->current(), 1) . '"]';
                 $tokens->next();
                 if ($tokens->is($stop)) {
                     $tokens->skip();
                     return $_str;
                 } else {
                     $_str .= '."';
                 }
             } elseif ($t === T_CURLY_OPEN) {
                 if (strlen($_str) > 1) {
                     $_str .= '".';
                 } else {
                     $_str = "";
                 }
                 $tokens->getNext(T_VARIABLE);
                 $_str .= '(' . $this->parseExpr($tokens) . ')';
                 if ($tokens->is($stop)) {
                     $tokens->next();
                     return $_str;
                 } else {
                     $_str .= '."';
                 }
             } elseif ($t === "}") {
                 $tokens->next();
             } elseif ($t === $stop) {
                 $tokens->next();
                 return $_str . '"';
             } else {
                 break;
             }
         }
         throw new UnexpectedTokenException($tokens);
     } elseif ($tokens->is(T_CONSTANT_ENCAPSED_STRING)) {
         return $tokens->getAndNext();
     } elseif ($tokens->is(T_ENCAPSED_AND_WHITESPACE)) {
         throw new UnexpectedTokenException($tokens);
     } else {
         return "";
     }
 }
 /**
  * Define macro
  *
  * @param Tokenizer $tokens
  * @param Tag $scope
  * @throws InvalidUsageException
  */
 public static function macroOpen(Tokenizer $tokens, Tag $scope)
 {
     $scope["name"] = $tokens->get(Tokenizer::MACRO_STRING);
     $scope["recursive"] = false;
     $args = array();
     $defaults = array();
     if (!$tokens->valid()) {
         return;
     }
     $tokens->next();
     if ($tokens->is('(') || !$tokens->isNext(')')) {
         $tokens->next();
         while ($tokens->is(Tokenizer::MACRO_STRING, T_VARIABLE)) {
             $param = $tokens->current();
             if ($tokens->is(T_VARIABLE)) {
                 $param = ltrim($param, '$');
             }
             $tokens->next();
             $args[] = $param;
             if ($tokens->is('=')) {
                 $tokens->next();
                 if ($tokens->is(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_DNUMBER) || $tokens->isSpecialVal()) {
                     $defaults[$param] = $tokens->getAndNext();
                 } else {
                     throw new InvalidUsageException("Macro parameters may have only scalar defaults");
                 }
             }
             $tokens->skipIf(',');
         }
         $tokens->skipIf(')');
     }
     $scope["macro"] = array("name" => $scope["name"], "args" => $args, "defaults" => $defaults, "body" => "", "recursive" => false);
     return;
 }
Beispiel #6
0
 /**
  * Parse modifiers
  * |modifier:1:2.3:'string':false:$var:(4+5*$var3)|modifier2:"str {$var+3} ing":$arr.item
  *
  * @param Tokenizer $tokens
  * @param                    $value
  * @throws \LogicException
  * @throws \Exception
  * @return string
  */
 public function parseModifier(Tokenizer $tokens, $value)
 {
     while ($tokens->is("|")) {
         $mods = $this->_fenom->getModifier($tokens->getNext(Tokenizer::MACRO_STRING), $this);
         if (!$mods) {
             throw new \Exception("Modifier " . $tokens->current() . " not found");
         }
         $tokens->next();
         $args = array();
         while ($tokens->is(":")) {
             if (!($args[] = $this->parseTerm($tokens->next()))) {
                 throw new UnexpectedTokenException($tokens);
             }
         }
         if (!is_string($mods)) {
             // dynamic modifier
             $mods = 'call_user_func($tpl->getStorage()->getModifier("' . $mods . '"), ';
         } else {
             $mods .= "(";
         }
         if ($args) {
             $value = $mods . $value . ', ' . implode(", ", $args) . ')';
         } else {
             $value = $mods . $value . ')';
         }
     }
     return $value;
 }