1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Latte;
9:
10:
11: 12: 13:
14: class MacroTokens extends TokenIterator
15: {
16: const T_WHITESPACE = 1,
17: = 2,
18: T_SYMBOL = 3,
19: T_NUMBER = 4,
20: T_VARIABLE = 5,
21: T_STRING = 6,
22: T_CAST = 7,
23: T_KEYWORD = 8,
24: T_CHAR = 9;
25:
26:
27: private static $tokenizer;
28:
29:
30: public $depth = 0;
31:
32:
33: public function __construct($input = NULL)
34: {
35: parent::__construct(is_array($input) ? $input : $this->parse($input));
36: $this->ignored = array(self::T_COMMENT, self::T_WHITESPACE);
37: }
38:
39:
40: public function parse($s)
41: {
42: self::$tokenizer = self::$tokenizer ?: new Tokenizer(array(
43: self::T_WHITESPACE => '\s+',
44: self::T_COMMENT => '(?s)/\*.*?\*/',
45: self::T_STRING => Parser::RE_STRING,
46: self::T_KEYWORD => '(?:true|false|null|and|or|xor|clone|new|instanceof|return|continue|break|[A-Z_][A-Z0-9_]{2,})(?![\w\pL_])',
47: self::T_CAST => '\((?:expand|string|array|int|integer|float|bool|boolean|object)\)',
48: self::T_VARIABLE => '\$[\w\pL_]+',
49: self::T_NUMBER => '[+-]?[0-9]+(?:\.[0-9]+)?(?:e[0-9]+)?',
50: self::T_SYMBOL => '[\w\pL_]+(?:-[\w\pL_]+)*',
51: self::T_CHAR => '::|=>|->|\+\+|--|<<|>>|<=>|<=|>=|===|!==|==|!=|<>|&&|\|\||\?\?|\*\*|\.\.\.|[^"\']',
52: ), 'u');
53: return self::$tokenizer->tokenize($s);
54: }
55:
56:
57: 58: 59: 60:
61: public function append($val, $position = NULL)
62: {
63: if ($val != NULL) {
64: array_splice(
65: $this->tokens,
66: $position === NULL ? count($this->tokens) : $position, 0,
67: is_array($val) ? array($val) : $this->parse($val)
68: );
69: }
70: return $this;
71: }
72:
73:
74: 75: 76: 77:
78: public function prepend($val)
79: {
80: if ($val != NULL) {
81: array_splice($this->tokens, 0, 0, is_array($val) ? array($val) : $this->parse($val));
82: }
83: return $this;
84: }
85:
86:
87: 88: 89: 90: 91:
92: public function fetchWord()
93: {
94: $words = $this->fetchWords();
95: return $words ? implode(':', $words) : FALSE;
96: }
97:
98:
99: 100: 101: 102: 103:
104: public function fetchWords()
105: {
106: do {
107: $words[] = $this->joinUntil(self::T_WHITESPACE, ',', ':');
108: } while ($this->nextToken(':'));
109:
110: if (count($words) === 1 && ($space = $this->nextValue(self::T_WHITESPACE))
111: && (($dot = $this->nextValue('.')) || $this->isPrev('.')))
112: {
113: $words[0] .= $space . $dot . $this->joinUntil(',');
114: }
115: $this->nextToken(',');
116: $this->nextAll(self::T_WHITESPACE, self::T_COMMENT);
117: return $words === array('') ? array() : $words;
118: }
119:
120:
121: public function reset()
122: {
123: $this->depth = 0;
124: return parent::reset();
125: }
126:
127:
128: protected function next()
129: {
130: parent::next();
131: if ($this->isCurrent('[', '(', '{')) {
132: $this->depth++;
133: } elseif ($this->isCurrent(']', ')', '}')) {
134: $this->depth--;
135: }
136: }
137:
138: }
139: