1 : <?php
2 :
3 :
4 :
5 :
6 :
7 :
8 :
9 :
10 :
11 :
12 :
13 :
14 :
15 :
16 :
17 :
18 :
19 :
20 :
21 :
22 :
23 :
24 :
25 :
26 :
27 :
28 :
29 :
30 :
31 :
32 :
33 : class JavascriptLexer
34 : {
35 :
36 : private $single_characters = array(
37 : '(' => TOKEN_OPEN_NORMAL_BRACKET,
38 : ')' => TOKEN_CLOSE_NORMAL_BRACKET,
39 : '{' => TOKEN_OPEN_CURLY_BRACKET,
40 : '}' => TOKEN_CLOSE_CURLY_BRACKET,
41 : '[' => TOKEN_OPEN_SQUARE_BRACKET,
42 : ']' => TOKEN_CLOSE_SQUARE_BRACKET,
43 : '=' => TOKEN_EQUALS,
44 : '.' => TOKEN_PERIOD,
45 : ',' => TOKEN_COMMA,
46 : ';' => TOKEN_SEMICOLON
47 : );
48 :
49 : private $reserved_words = array(
50 : 'break', 'else', 'new', 'var', 'case', 'finally', 'return', 'void', 'catch',
51 : 'for', 'switch', 'while', 'do', 'continue', 'function', 'this', 'with', 'default', 'if', 'throw',
52 : 'delete', 'in', 'try', 'instanceof', 'typeof',
53 :
54 : 'abstract', 'enum', 'int', 'short', 'boolean', 'export', 'interface', 'static', 'byte', 'extends',
55 : 'long', 'super', 'char', 'final', 'native', 'synchronized', 'class', 'float', 'package', 'throws',
56 : 'const', 'goto', 'private', 'transient', 'debugger', 'implements', 'protected', 'volatile'
57 : );
58 :
59 : private $reserved_values = array('null', 'true', 'false');
60 :
61 :
62 :
63 :
64 :
65 : public function resetState()
66 3 : {}
67 :
68 :
69 :
70 :
71 :
72 : public function process($source)
73 : {
74 3 : $offset = 0;
75 3 : $length = strlen($source);
76 3 : $tokens = array();
77 3 : $junk = array();
78 :
79 3 : Token::setCurrLineNum(1);
80 3 : while ($offset < $length) {
81 :
82 3 : if (preg_match('/\G(\n|\r|\n\r)/', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
83 3 : Token::setIncrLineNum();
84 3 : $offset = $matches[0][1] + strlen($matches[0][0]);
85 :
86 3 : continue;
87 : }
88 :
89 :
90 :
91 3 : foreach ($this->single_characters as $char => $token_type) {
92 3 : if ($source[$offset] == $char) {
93 3 : $tokens[] = new Token($token_type, $char);
94 3 : $offset++;
95 3 : continue 2;
96 : }
97 3 : }
98 :
99 :
100 :
101 :
102 :
103 3 : if (preg_match('/\G\/\*\*(.+?)\*\//s', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
104 2 : $tokens[] = new Token(TOKEN_DOCBLOCK, $matches[0][0]);
105 2 : $offset = $matches[0][1] + strlen($matches[0][0]);
106 2 : Token::setIncrLineNum(preg_match_all('/\n|\r|\n\r/', $matches[0][0], $junk));
107 2 : continue;
108 : }
109 :
110 :
111 3 : if (preg_match('/\G\/\*(.+?)\*\//s', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
112 1 : $tokens[] = new Token(TOKEN_COMMENT, $matches[0][0]);
113 1 : $offset = $matches[0][1] + strlen($matches[0][0]);
114 1 : Token::setIncrLineNum(preg_match_all('/\n|\r|\n\r/', $matches[0][0], $junk));
115 1 : continue;
116 : }
117 :
118 :
119 3 : if (preg_match('/\G\/\/.*\n/', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
120 1 : $tokens[] = new Token(TOKEN_COMMENT, rtrim($matches[0][0]));
121 1 : $offset = $matches[0][1] + strlen($matches[0][0]);
122 1 : Token::setIncrLineNum();
123 1 : continue;
124 : }
125 :
126 :
127 3 : if (preg_match('/\G"([^\"]|\.)*"/i', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
128 1 : $tokens[] = new Token(TOKEN_STRING, $matches[0][0]);
129 1 : $offset = $matches[0][1] + strlen($matches[0][0]);
130 1 : Token::setIncrLineNum(preg_match_all('/\n|\r|\n\r/', $matches[0][0], $junk));
131 1 : continue;
132 : }
133 :
134 :
135 3 : if (preg_match('/\G\'([^\\\']|\.)*\'/i', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
136 0 : $tokens[] = new Token(TOKEN_STRING, $matches[0][0]);
137 0 : $offset = $matches[0][1] + strlen($matches[0][0]);
138 0 : Token::setIncrLineNum(preg_match_all('/\n|\r|\n\r/', $matches[0][0], $junk));
139 0 : continue;
140 : }
141 :
142 :
143 3 : foreach ($this->reserved_words as $word) {
144 3 : if (preg_match('/\G' . $word . '/i', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
145 :
146 :
147 :
148 : switch ($word) {
149 3 : case 'function':
150 3 : $tokens[] = new Token(TOKEN_FUNCTION);
151 3 : break;
152 :
153 3 : default:
154 3 : $tokens[] = new Token(TOKEN_RESERVED_WORD, $word);
155 3 : break;
156 3 : }
157 :
158 3 : $offset = $matches[0][1] + strlen($matches[0][0]);
159 3 : continue;
160 : }
161 3 : }
162 :
163 :
164 3 : foreach ($this->reserved_values as $value) {
165 3 : if (preg_match('/\G' . $value . '/i', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
166 0 : $tokens[] = new Token(TOKEN_RESERVED_VALUE, $value);
167 0 : $offset = $matches[0][1] + strlen($matches[0][0]);
168 0 : continue;
169 : }
170 3 : }
171 :
172 :
173 : $number_expressions = array(
174 3 : '/\G0x[0-9A-F]+/i',
175 : '/\G[0-9]+/'
176 3 : );
177 3 : foreach ($number_expressions as $expression) {
178 3 : if (preg_match($expression, $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
179 3 : $tokens[] = new Token(TOKEN_NUMBER, $matches[0][0]);
180 3 : $offset = $matches[0][1] + strlen($matches[0][0]);
181 3 : continue;
182 : }
183 3 : }
184 :
185 :
186 3 : if (preg_match('/\G[a-z$_][a-z0-9$_]*/i', $source, $matches, PREG_OFFSET_CAPTURE, $offset)) {
187 3 : $tokens[] = new Token(TOKEN_IDENTIFIER, $matches[0][0]);
188 3 : $offset = $matches[0][1] + strlen($matches[0][0]);
189 3 : continue;
190 : }
191 :
192 3 : $offset++;
193 3 : }
194 :
195 3 : return $tokens;
196 : }
197 :
198 :
199 : }
200 :
201 :
202 : ?>
|