1<?php
2/**
3 * PHPTAL templating engine
4 *
5 * PHP Version 5
6 *
7 * @category HTML
8 * @package  PHPTAL
9 * @author   Kornel Lesiński <kornel@aardvarkmedia.co.uk>
10 * @license  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
11 * @version  SVN: $Id:$
12 * @link     http://phptal.org/
13 */
14
15class PHPTAL_Tokenizer
16{
17    private $regex, $names, $offset, $str;
18
19    private $current_token, $current_value;
20
21    function __construct($str, array $tokens)
22    {
23        $this->offset = 0;
24        $this->str = $str;
25        $this->end = strlen($str);
26
27        $this->regex = '/('.str_replace('/', '\/', implode(')|(', $tokens)).')|(.)/Ssi';
28        $this->names = array_keys($tokens);
29        $this->names[] = 'OTHER';
30    }
31
32    function eof()
33    {
34        return $this->offset >= $this->end;
35    }
36
37    function skipSpace()
38    {
39        while ($this->current_token === 'SPACE') $this->nextToken();
40    }
41
42    function nextToken()
43    {
44        if ($this->offset >= $this->end) {
45            $this->current_value = null;
46            return $this->current_token = 'EOF';
47        }
48
49        //if (!preg_match_all($this->regex, $this->str, $m, PREG_SET_ORDER, $this->offset)) throw new Exception("FAIL {$this->regex} at {$this->offset}");
50        if (!preg_match($this->regex, $this->str, $m, null, $this->offset)) throw new Exception("FAIL {$this->regex} didn't match '{$this->str}' at {$this->offset}");
51
52        $this->offset += strlen($m[0]); // in bytes
53
54        $this->current_value = $m[0];
55        $this->current_token = $this->names[count($m)-2]; // -1 for usual length/offset confusion, and minus one extra for $m[0]
56
57        return $this->current_token;
58    }
59
60    function token()
61    {
62        return $this->current_token;
63    }
64
65    function tokenValue()
66    {
67        return $this->current_value;
68    }
69}
70