psql db schema test
[mirrors/Kyberia-bloodline.git] / scripts / phpindent.pl
CommitLineData
a6540423
H
1#!/usr/bin/perl -w
2
3# php indenter
4# Reformats your php source code
5#
6# $Id: phpindent,v 1.1 2002/05/20 12:54:03 weasel Exp $
7#
8#
9# Depends: Parse::RecDescent
10#
11#
12# (c) 2002 Florian Reitmeir <squat@riot.org>
13# Peter Palfrader <peter@palfrader.org>
14#
15# This program is free software; you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation; either version 2 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28#
29#
30#
31# Usage: phpindent < orig.php > new.php
32#
33#
34# - It might corrupt your code
35# - It might not even work at all
36# - It does not understand all of php
37# - It's damn slow (several hours for one of our 800 line examples on a gHz
38# CPU)
39# - But it was fun to write and merely to test out Parse::RecDescent
40#
41# It was just a proof of concept - don't use it in production
42#
43# Did I mention it was slow?
44#
45#
46# Q: So why did you write it?
47# A: It was an ad hoc quick hack which went out of control but was
48# real fun.
49#
50# Q: So are there any real php indenters?
51# A: We didn't find any which is why we tried this nonsense at all.
52# If you find any just let us know and we will link to them.
53#
54# Q: Will you improve this indenter/fix bugs I report?
55# A: Probably not. But if you happen to have lots of time we would
56# welcome a patch or two.
57#
58# Q: You know your grammar sucks?
59# A: yepp.
60#
61
62#######################################################################
63package MyToken;
64
65sub new
66{
67 my ($class, %args) = @_;
68 bless \%args, $class;
69}
70
71#######################################################################
72package MyBinaryOperator;
73@ISA = qw( MyToken );
74
75sub reprint
76{
77 my ($self) = @_;
78 return
79 sprintf "%s %s %s",
80 $self->{left}->reprint(),
81 $self->{'operator'},
82 $self->{right}->reprint();
83};
84
85#######################################################################
86package MyPostOperator;
87@ISA = qw( MyToken );
88
89sub reprint
90{
91 my ($self) = @_;
92 return
93 sprintf "%s %s",
94 $self->{left}->reprint(),
95 $self->{'operator'};
96};
97
98#######################################################################
99package MyPreOperator;
100@ISA = qw( MyToken );
101
102sub reprint
103{
104 my ($self) = @_;
105 return
106 sprintf "%s %s",
107 $self->{'operator'},
108 $self->{right}->reprint();
109};
110
111#######################################################################
112package MyAtom;
113@ISA = qw( MyToken );
114
115sub reprint
116{
117 my ($self) = @_;
118
119 return
120 sprintf "%s",
121 $self->{'value'};
122};
123
124#######################################################################
125package MyStatement;
126@ISA = qw( MyToken );
127
128sub reprint
129{
130 my ($self) = @_;
131
132 return
133 sprintf "%s;\n",
134 $self->{'value'};
135};
136
137#######################################################################
138package MyComment;
139@ISA = qw( MyToken );
140
141sub reprint
142{
143 my ($self, %args) = @_;
144 my $il = $args{'indent'} || 1;
145 my $i = "\t" x ($il -1 );
146
147 my $value = $self->{'value'};
148 $value =~ s,#\s*,# ,;
149 $value =~ s,//\s*,\n\n$i// ,;
150 return
151 $value."\n";
152};
153
154#######################################################################
155package MyCommentMultiLine;
156@ISA = qw( MyToken );
157
158sub reprint
159{
160 my ($self, %args) = @_;
161 my $il = $args{'indent'}-1 || 0;
162 my $i = "\t" x $il;
163
164 my $value = $self->{'value'};
165 $value =~ s,/\*\s*\n?,,;
166 $value =~ s,\n?\s*\*/,,;
167 my @lines = map { s/^\s*\*?[ \t]*/$i * /; $_ } split /\n/, $value;
168 unshift @lines, "/*";
169 push @lines, "$i */";
170
171 return
172 sprintf "%s\n",
173 join ("\n", @lines)
174};
175
176#######################################################################
177package MyCommentDoc;
178@ISA = qw( MyToken );
179
180sub reprint
181{
182 my ($self, %args) = @_;
183 my $il = $args{'indent'}-1 || 0;
184 my $i = "\t" x $il;
185
186 my $value = $self->{'value'};
187 $value =~ s,^/\*\*[ \t]*\n?,,;
188 $value =~ s,\n?[ \t]*\*/$,,;
189 $value =~ s/\t/ /g;
190 my @lines = split /\n/, $value;
191
192 my $maxwhitespace;
193 for (@lines) {
194 my ($leadwhitespace) = ($_ =~ /^(\s*)/);
195 $maxwhitespace = (!defined ($maxwhitespace) || length($leadwhitespace) < $maxwhitespace) ?
196 length($leadwhitespace) :
197 $maxwhitespace;
198 };
199 my $leadwhitespace = " " x $maxwhitespace;
200 @lines = map { s/^$leadwhitespace//; s/^/$i /; $_ } @lines;
201
202 unshift @lines, "/**";
203 push @lines, "$i */";
204
205 return
206 sprintf "%s\n",
207 join ("\n", @lines)
208};
209
210#######################################################################
211package MyConditionalBlock;
212@ISA = qw( MyToken );
213
214sub reprint
215{
216 my ($self, %args) = @_;
217 my $il = $args{'indent'} || 0;
218 my $i = "\t" x $il;
219
220 my $block = $self->{block}->reprint(indent => $il, noend=>1);
221 if ($block =~ /^\s*\{/) {
222 $block = "\t" x ($il-1) . $block;
223 $isblock = 1;
224 } else {
225 $block = "\t" x ($il) . $block;
226 $isblock = 0;
227 };
228
229
230 my $elseblock;
231 if ($self->{type} eq 'ifelse') {
232 $elseblock = $self->{elseblock}->reprint(indent => $il, noend=>1);
233 if ($elseblock =~ /^\s*\{/) {
234 $elseblock = "\t" x ($il-1) . $elseblock;
235 $elseisblock = 1;
236 } else {
237 $elseblock = "\t" x ($il) . $elseblock;
238 $elseisblock = 0;
239 };
240 };
241
242 if ($self->{type} eq 'if' || $self->{type} eq 'while') {
243 return
244 $self->{type}.
245 " (".
246 $self->{condition}->reprint().
247 ")\n".
248 $block.
249 ($isblock ? ";\n" : "");
250 } elsif ($self->{type} eq 'ifelse') {
251 return
252 "if".
253 " (".
254 $self->{condition}->reprint().
255 ")\n".
256 $block.
257 ($elseisblock ? "\n" : "").
258 "\t"x($il-1) . "else\n".
259 $elseblock.
260 ($elseisblock ? ";\n" : "");
261 } elsif ($self->{type} eq 'dowhile') {
262 return
263 "do\n".
264 $block.
265 " while (".
266 $self->{condition}->reprint().
267 ");\n";
268 } elsif ($self->{type} eq 'for') {
269 return
270 $self->{type}.
271 " (".
272 $self->{part1}->reprint().
273 "; ".
274 $self->{part2}->reprint().
275 "; ".
276 $self->{part3}->reprint().
277 ")\n".
278 $block.
279 ($isblock ? ";\n" : "");
280 } elsif ($self->{type} eq 'foreach') {
281 return
282 $self->{type}.
283 " (".
284 $self->{part1}->reprint().
285 " as ".
286 $self->{part2}->reprint().
287 ")\n".
288 $block.
289 ($isblock ? ";\n" : "");
290 };
291
292};
293
294#######################################################################
295package MyParam;
296@ISA = qw( MyToken );
297
298sub reprint
299{
300 my ($self, %args) = @_;
301 my $il = $args{'indent'} || 1;
302 my $i = "\t" x $il;
303
304 my $statements = join (", ", map { $_->reprint() } @{$self->{'statements'}});
305
306 return
307 $statements;
308};
309
310#######################################################################
311package MyFunction;
312@ISA = qw( MyToken );
313
314sub reprint
315{
316 my ($self, %args) = @_;
317 my $il = $args{'indent'} || 1;
318 my $i = "\t" x $il;
319
320 return
321 $self->{name}->reprint().
322 " (".
323 ((defined $self->{params}) ? $self->{params}->reprint() : "").
324 ")";
325};
326
327#######################################################################
328package MyBlock;
329@ISA = qw( MyToken );
330
331sub reprint
332{
333 my ($self, %args) = @_;
334 my $il = $args{'indent'} || 1;
335 my $i = "\t" x $il;
336
337 my $statements = join ($i, map { $_->reprint(indent => $il + 1) } @{$self->{'statements'}});
338
339 $statements = $i.$statements if ( substr($statements,0,1) ne "\n" );
340
341 return
342 ((defined $args{'nobraces'}) ? "" : "{\n").
343 $statements.
344 "\t" x ($il-1).
345 ((defined $args{'nobraces'}) ? "" : "}").
346 ((defined $args{'noend'}) ? "" : ";\n");
347};
348
349#######################################################################
350package MyFunctionDefinition;
351@ISA = qw( MyToken );
352
353sub reprint
354{
355 my ($self, %args) = @_;
356
357 my $il = $args{'indent'} || 1;
358 my $i = "\t" x ($il-1);
359
360 return
361 "\n".
362 $i."function ".
363 $self->{'header'}->reprint(). "\n".
364 $i.$self->{'block'}->reprint(indent => $il)."\n";
365};
366
367
368
369
370#######################################################################
371package main;
372
373use strict;
374use Parse::RecDescent;
375
376
377my $input;
378local $/ = undef;
379$input = <>;
380
381my $grammar = q
382{
383 Script: /<\?(php)?/ Block '?>' { MyAtom->new ( value => "<?\n" . $item[2]->reprint(nobraces=>1) ."?>\n" ) }
384
385 GroupedBlock: '{' Block '}' /;?/ { MyBlock->new ( statements => [ @{$item[2]->{'statements'}} ] ) }
386
387 Block: Statement Block { MyBlock->new ( statements => [ $item[1], @{$item[2]->{'statements'}} ] ) }
388 | Statement { MyBlock->new ( statements => [ $item[1] ] ) }
389
390 Statement: Expression ';' { MyStatement->new ( value => $item[1]->reprint() ) }
391 | ';' { MyStatement->new ( value => '' ) }
392 | GroupedBlock ';' { $item[1] }
393 | GroupedBlock
394 | Comment
395 | IfThenElseBlock
396 | IfBlock
397 | WhileBlock
398 | DoWhileBlock
399 | ForLoop
400 | ForEachLoop
401 | FunctionDefinition
402
403 FunctionDefinition: "function" FunctionCall GroupedBlock
404 { MyFunctionDefinition->new ( header => $item[2], block => $item[3] ) }
405
406
407 IfThenElseBlock: "if" "(" Expression ")" Statement "else" Statement
408 { MyConditionalBlock->new ( type => 'ifelse',
409 condition => $item[3],
410 block => $item[5],
411 elseblock => $item[7] ) }
412 IfBlock: "if" "(" Expression ")" Statement
413 { MyConditionalBlock->new ( type => 'if',
414 condition => $item[3],
415 block => $item[5] ) }
416 WhileBlock: "while" "(" Expression ")" Statement
417 { MyConditionalBlock->new ( type => 'while',
418 condition => $item[3],
419 block => $item[5] ) }
420 DoWhileBlock: "do" GroupedBlock "while" "(" Expression ")" ";"
421 { MyConditionalBlock->new ( type => 'dowhile',
422 condition => $item[5],
423 block => $item[2] ) }
424 ForLoop: "for" "(" Expression ";" Expression ";" Expression ")" Statement
425 { MyConditionalBlock->new ( type => 'for',
426 part1 => $item[3],
427 part2 => $item[5],
428 part3 => $item[7],
429 block => $item[9] ) }
430 ForEachLoop: "foreach" "(" Expression "as" Expression ")" Statement
431 { MyConditionalBlock->new ( type => 'foreach',
432 part1 => $item[3],
433 part2 => $item[5],
434 block => $item[7] ) }
435 Expression: "(" Expression ")" { $item[2] }
436 | FunctionCall Operator Expression
437 { MyBinaryOperator->new ( left=>$item[1], operator=>$item[2], right=>$item[3] ) }
438 | Atom Operator Expression
439 { MyBinaryOperator->new ( left=>$item[1], operator=>$item[2], right=>$item[3] ) }
440 | Atom Operator { MyPostOperator->new ( left=>$item[1], operator=>$item[2] ) }
441 | PreOperator Expression { MyPreOperator->new ( right=>$item[2], operator=>$item[1] ) }
442 | FunctionCall
443 | Atom
444
445
446 Comment: CommentHash
447 | CommentSlash
448 | CommentDoc
449 | CommentMultiLine
450
451 CommentHash: /#.*?$/m { MyComment->new ( value => $item[1] ) }
452 CommentSlash: /\/\/.*?$/m { MyComment->new ( value => $item[1] ) }
453 CommentDoc: /\/\*\*.*?\*\//s { MyCommentDoc->new ( value => $item[1] ) }
454 CommentMultiLine: /\/\*.*?\*\//s { MyCommentMultiLine->new ( value => $item[1] ) }
455
456 Operator: '==='
457 | '!=='
458 | '+='
459 | '-='
460 | '=='
461 | '!='
462 | '=>'
463 | '<='
464 | '>='
465 | '++'
466 | '--'
467 | '&&'
468 | '.='
469 | '||'
470 | '&'
471 | '|'
472 | '>'
473 | '<'
474 | '='
475 | '/'
476 | '+'
477 | '-'
478 | '*'
479 | '.'
480 | ':'
481 | '?'
482
483 PreOperator: "new"
484 | "print"
485 | "return"
486 | "echo"
487 | "not"
488 | "++"
489 | "--"
490 | "-"
491 | "+"
492 | "1"
493 | "!"
494
495
496
497 FunctionCall: Atom "(" FunctionParameter ")"
498 { MyFunction->new ( name => $item[1], params => $item[3] ) }
499 | Atom "(" ")"
500 { MyFunction->new ( name => $item[1] ) }
501
502 Atom: Variable
503 | String
504 | Identifier
505 | Numerical
506
507
508 FunctionParameter: Expression "," FunctionParameter
509 { MyParam->new ( statements => [ $item[1], @{$item[3]->{'statements'}} ] ) }
510 | Expression { MyParam->new ( statements => [ $item[1] ] ) }
511
512
513 Variable: '$' Identifier Array
514 { MyAtom->new ( value => '$'.$item[2]->reprint() . $item[3]->reprint() ) }
515 | '$' Identifier { MyAtom->new ( value => '$'.$item[2]->reprint() ) }
516
517
518 Array: "[" "]" Array { MyAtom->new ( value => '[]'.$item[3]->reprint() ) }
519 | "[" Expression "]" Array
520 { MyAtom->new ( value => '['.$item[2]->reprint().']'.$item[4]->reprint() ) }
521 | "[" Expression "]" { MyAtom->new ( value => '['.$item[2]->reprint().']' ) }
522 | "[" "]" { MyAtom->new ( value => '[]' ) }
523
524
525 Identifier: SimpleIdentifier "->" Identifier
526 { MyAtom->new ( value => $item[1]->reprint() ."->" .$item[3]->reprint() ) }
527 | SimpleIdentifier
528
529 SimpleIdentifier: /[a-zA-Z][a-zA-Z0-9_]*/ { MyAtom->new ( value => $item[1] ) }
530
531 Numerical: /[\d]+(\.[\d+])?/ { MyAtom->new ( value => $item[1] ) }
532
533 String: EmptyDQString
534 | NotEmptyDQString
535 | EmptySQString
536 | NotEmptySQString
537 NotEmptyDQString: /".*?[^\\\\]"/s { MyAtom->new ( value => $item[1] ) }
538 EmptyDQString: '""' { MyAtom->new ( value => '""' ) }
539 NotEmptySQString: /'.*?[^\\\\]'/s { MyAtom->new ( value => $item[1] ) }
540 EmptySQString: "''" { MyAtom->new ( value => "''" ) }
541};
542
543#$::RD_HINT = 1;
544my $parser = new Parse::RecDescent ($grammar);
545my $tree = $parser->Script($input);
546
547print $tree->reprint();
548
549
550
551# vim:set ts=4:
552# vim:set shiftwidth=4:
This page took 0.502501 seconds and 4 git commands to generate.