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 :
34 :
35 : class PhpParser
36 : {
37 :
38 :
39 :
40 :
41 : function parseFile($base_dir, $filename)
42 : {
43 :
44 :
45 :
46 97 : $debug = false;
47 :
48 :
49 97 : $source = @file_get_contents($base_dir . $filename);
50 97 : if ($source == null) return null;
51 :
52 97 : $tokens = @token_get_all($source);
53 :
54 :
55 97 : $current_file = new ParserFile ();
56 97 : $current_file->name = $filename;
57 97 : $current_file->source = $source;
58 :
59 97 : unset ($source);
60 :
61 :
62 97 : $current_function = null;
63 97 : $inside_function = null;
64 97 : $current_class = null;
65 97 : $inside_class = null;
66 97 : $current_constant = null;
67 97 : $next = null;
68 97 : $namespace = 0;
69 97 : $brace_count = 0;
70 97 : $abstract = false;
71 97 : $static = false;
72 97 : $final = false;
73 97 : $next_comment = null;
74 97 : $file_has_comment = false;
75 :
76 :
77 97 : if ($debug) {
78 57 : echo '<style>';
79 0 : echo 'span {color: green;}';
80 0 : echo 'h3 {border: 4px black solid; padding: 3px; margin-top: 2em;}';
81 0 : echo 'i {color: gray;}';
82 0 : echo '</style>';
83 :
84 0 : echo '<h3>', htmlspecialchars($filename), '</h3>';
85 0 : echo '<pre>';
86 0 : }
87 :
88 97 : $argument = null;
89 97 : $visibility = null;
90 97 : $param_type = null;
91 97 : foreach ($tokens as $token) {
92 97 : if (is_array($token) and $token[0] == T_WHITESPACE) continue;
93 :
94 :
95 97 : if ($debug) {
96 0 : echo "\n";
97 0 : if (is_string($token)) {
98 0 : echo "BARE TEXT\n<i>" . htmlspecialchars($token) . "</i>\n";
99 0 : } else {
100 0 : echo htmlspecialchars(token_name($token[0])) . "\n<i>" . htmlspecialchars(str_replace("\n", '\n', $token[1])) . "</i>\n";
101 : }
102 0 : }
103 :
104 97 : if (is_string($token)) {
105 :
106 96 : if ($token == '{') {
107 :
108 94 : if ($current_function != null) {
109 62 : if ($inside_class != null) {
110 20 : if ($visibility != null) {
111 4 : $current_function->visibility = $visibility;
112 4 : $visibility = null;
113 4 : }
114 20 : $inside_class->functions[] = $current_function;
115 :
116 20 : } else {
117 44 : $current_file->functions[] = $current_function;
118 : }
119 :
120 62 : $current_function->post_load();
121 62 : $inside_function = $current_function;
122 62 : $current_function = null;
123 62 : $argument = null;
124 :
125 :
126 94 : } else if ($current_class != null) {
127 53 : if ($visibility != null) {
128 0 : $current_class->visibility = $visibility;
129 0 : $visibility = null;
130 0 : }
131 53 : $current_file->classes[] = $current_class;
132 53 : $inside_class = $current_class;
133 53 : $current_class = null;
134 53 : $next = null;
135 3 :
136 53 : } else {
137 9 : $brace_count++;
138 : }
139 :
140 :
141 :
142 96 : } else if ($token == ';') {
143 25 : if ($namespace == 1) {
144 5 : $namespace = 2;
145 25 : } else if ($current_function != null) {
146 4 : if ($visibility != null) {
147 0 : $current_function->visibility = $visibility;
148 0 : $visibility = null;
149 0 : }
150 4 : $current_function->post_load();
151 4 : $inside_class->functions[] = $current_function;
152 4 : $current_function = null;
153 4 : }
154 :
155 :
156 :
157 96 : } else if ($token == '}') {
158 94 : if ($brace_count == 0) {
159 94 : if ($inside_function != null) {
160 62 : $inside_function = null;
161 94 : } else if ($inside_class != null) {
162 53 : $inside_class = null;
163 53 : }
164 :
165 94 : } else {
166 9 : $brace_count--;
167 : }
168 94 : }
169 :
170 96 : } else {
171 :
172 97 : list($id, $text, $linenum) = $token;
173 :
174 : switch ($id) {
175 97 : case T_CURLY_OPEN:
176 0 : $brace_count++;
177 0 : break;
178 :
179 :
180 97 : case T_DOC_COMMENT:
181 44 : if ($next_comment and ! $file_has_comment) {
182 2 : $current_file->applyComment($next_comment);
183 2 : $next_comment = null;
184 2 : $file_has_comment = true;
185 2 : }
186 44 : $next_comment = $text;
187 44 : break;
188 :
189 :
190 97 : case T_FUNCTION:
191 64 : if ($inside_function != null) {
192 8 : break;
193 : }
194 64 : $current_function = new ParserFunction();
195 64 : $current_function->linenum = $linenum;
196 64 : if ($abstract) {
197 1 : $current_function->abstract = true;
198 1 : $abstract = false;
199 1 : }
200 64 : if ($static) {
201 1 : $current_function->static = true;
202 1 : $static = false;
203 1 : }
204 64 : if ($final) {
205 1 : $current_function->final = true;
206 1 : $final = false;
207 1 : }
208 64 : if ($next_comment) {
209 34 : $current_function->applyComment($next_comment);
210 34 : $next_comment = null;
211 34 : }
212 64 : $param_type = null;
213 64 : break;
214 :
215 :
216 97 : case T_CLASS:
217 45 : $current_class = new ParserClass();
218 45 : $current_class->linenum = $linenum;
219 45 : if ($abstract) {
220 1 : $current_class->abstract = true;
221 1 : $abstract = false;
222 45 : } else if ($final) {
223 0 : $current_class->final = true;
224 0 : $final = false;
225 0 : }
226 45 : if ($next_comment) {
227 9 : $current_class->applyComment($next_comment);
228 9 : $next_comment = null;
229 9 : }
230 45 : break;
231 :
232 :
233 97 : case T_INTERFACE:
234 10 : $current_class = new ParserInterface();
235 10 : $current_class->linenum = $linenum;
236 10 : if ($next_comment) {
237 4 : $current_class->applyComment($next_comment);
238 4 : $next_comment = null;
239 4 : }
240 10 : break;
241 :
242 :
243 :
244 :
245 97 : case T_VARIABLE:
246 37 : if ($current_function != null) {
247 22 : $argument = new ParserArgument();
248 22 : $argument->linenum = $linenum;
249 22 : $argument->name = $text;
250 22 : if ($param_type != null) {
251 10 : $argument->type = $param_type;
252 10 : $param_type = null;
253 10 : }
254 22 : $current_function->args[] = $argument;
255 :
256 37 : } else if (($inside_class != null) && ($inside_function == null)) {
257 8 : $variable = new ParserVariable();
258 8 : $variable->linenum = $linenum;
259 8 : $variable->name = $text;
260 8 : $variable->visibility = $visibility ?: 'private';
261 8 : $visibility = null;
262 8 : if ($static) {
263 0 : $variable->static = true;
264 0 : $static = false;
265 0 : }
266 8 : if ($next_comment) {
267 3 : $variable->applyComment($next_comment);
268 3 : $next_comment = null;
269 3 : }
270 8 : $inside_class->variables[] = $variable;
271 8 : }
272 37 : break;
273 :
274 :
275 :
276 :
277 :
278 97 : case T_STRING:
279 96 : if ($next != null) {
280 11 : if ($next == T_EXTENDS) {
281 4 : $current_class->extends = $text;
282 11 : } else if ($next == T_IMPLEMENTS) {
283 5 : $current_class->implements[] = $text;
284 5 : break;
285 5 : } else if ($next == T_NAMESPACE and $namespace == 0) {
286 5 : $current_file->namespace = array($text);
287 5 : $namespace = 1;
288 5 : } else if ($next == T_NS_SEPARATOR and $namespace == 1) {
289 4 : $current_file->namespace[] = $text;
290 4 : }
291 9 : $next = null;
292 :
293 96 : } else if (strcasecmp($text, 'null') == 0) {
294 0 : if ($current_constant) {
295 0 : $current_constant->value = 'NULL';
296 0 : $current_file->constants[] = $current_constant;
297 0 : $current_constant = null;
298 :
299 0 : } else if ($argument) {
300 0 : $argument->default = 'NULL';
301 0 : }
302 :
303 96 : } else if (strcasecmp($text, 'true') == 0) {
304 2 : if ($current_constant) {
305 1 : $current_constant->value = 'TRUE';
306 1 : $current_file->constants[] = $current_constant;
307 1 : $current_constant = null;
308 :
309 2 : } else if ($argument) {
310 0 : $argument->default = 'TRUE';
311 0 : }
312 :
313 96 : } else if (strcasecmp($text, 'false') == 0) {
314 0 : if ($current_constant) {
315 0 : $current_constant->value = 'FALSE';
316 0 : $current_file->constants[] = $current_constant;
317 0 : $current_constant = null;
318 :
319 0 : } else if ($argument) {
320 0 : $argument->default = 'FALSE';
321 0 : }
322 :
323 96 : } else if ($current_function != null) {
324 64 : if ($current_function->name == '') {
325 64 : $current_function->name = $text;
326 64 : } else {
327 4 : $param_type = $text;
328 : }
329 :
330 96 : } else if ($current_class != null) {
331 53 : $current_class->name = $text;
332 :
333 56 : } else if (strcasecmp($text, 'define') == 0) {
334 4 : $current_constant = new ParserConstant();
335 4 : $current_constant->linenum = $linenum;
336 4 : if ($next_comment) {
337 2 : $current_constant->applyComment($next_comment);
338 2 : $next_comment = null;
339 2 : }
340 :
341 4 : }
342 96 : break;
343 :
344 :
345 97 : case T_ARRAY:
346 6 : if ($current_function != null) {
347 6 : $param_type = $text;
348 6 : }
349 6 : break;
350 :
351 :
352 97 : case T_CONSTANT_ENCAPSED_STRING:
353 :
354 5 : $name_search = array("\'", '\"', "'", '"');
355 5 : $name_replace = array("'", '"', '', '');
356 5 : $text = str_replace($name_search, $name_replace, $text);
357 :
358 5 : if ($current_constant) {
359 4 : if ($current_constant->name == null) {
360 4 : $current_constant->name = $text;
361 4 : } else {
362 3 : $current_constant->value = $text;
363 3 : $current_file->constants[] = $current_constant;
364 3 : $current_constant = null;
365 : }
366 :
367 5 : } else if ($argument) {
368 1 : $argument->default = $text;
369 1 : }
370 5 : break;
371 :
372 :
373 97 : case T_LNUMBER:
374 97 : case T_DNUMBER:
375 1 : if ($current_constant) {
376 0 : if ($current_constant->name != null) {
377 0 : $current_constant->value = $text;
378 0 : $current_file->constants[] = $current_constant;
379 0 : $current_constant = null;
380 0 : }
381 :
382 1 : } else if ($argument) {
383 0 : $argument->default = $text;
384 0 : }
385 1 : break;
386 :
387 :
388 :
389 97 : case T_PRIVATE:
390 5 : $visibility = 'private';
391 5 : break;
392 :
393 97 : case T_PROTECTED:
394 2 : $visibility = 'protected';
395 2 : break;
396 :
397 97 : case T_PUBLIC:
398 3 : $visibility = 'public';
399 3 : break;
400 :
401 :
402 :
403 97 : case T_EXTENDS:
404 97 : case T_IMPLEMENTS:
405 97 : case T_NAMESPACE:
406 97 : case T_NS_SEPARATOR:
407 11 : $next = $id;
408 11 : break;
409 :
410 97 : case T_ABSTRACT:
411 2 : $abstract = true;
412 2 : break;
413 :
414 97 : case T_STATIC:
415 1 : if (! $inside_function) $static = true;
416 1 : break;
417 :
418 97 : case T_FINAL:
419 1 : $final = true;
420 1 : break;
421 :
422 : }
423 : }
424 97 : }
425 :
426 :
427 :
428 97 : if ($next_comment and ! $file_has_comment) {
429 1 : $current_file->applyComment($next_comment);
430 1 : $next_comment = null;
431 1 : $file_has_comment = true;
432 1 : }
433 :
434 97 : if ($debug) echo '</pre>';
435 :
436 :
437 97 : return $current_file;
438 : }
439 :
440 :
441 : }
442 :
443 :
444 : ?>
|