Advertisement
Guest User

grom358

a guest
Dec 14th, 2008
751
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.61 KB | None | 0 0
  1. #!/usr/bin/php
  2. <?php
  3. class Token {
  4.     public $type;
  5.     public $contents;
  6.  
  7.     public function __construct($rawToken) {
  8.         if (is_array($rawToken)) {
  9.             $this->type = $rawToken[0];
  10.             $this->contents = $rawToken[1];
  11.         } else {
  12.             $this->type = -1;
  13.             $this->contents = $rawToken;
  14.         }
  15.     }
  16. }
  17.  
  18. $file = $argv[1];
  19. $code = file_get_contents($file);
  20.  
  21. $rawTokens = token_get_all($code);
  22. $tokens = array();
  23. foreach ($rawTokens as $rawToken) {
  24.     $tokens[] = new Token($rawToken);
  25. }
  26.  
  27. function skipWhitespace(&$tokens, &$i) {
  28.     global $lineNo;
  29.     $i++;
  30.     $token = $tokens[$i];
  31.     while ($token->type == T_WHITESPACE) {
  32.         $lineNo += substr($token->contents, "\n");
  33.         $i++;
  34.         $token = $tokens[$i];
  35.     }
  36. }
  37.  
  38. function nextToken(&$j) {
  39.     global $tokens, $i;
  40.     $j = $i;
  41.     do {
  42.         $j++;
  43.         $token = $tokens[$j];
  44.     } while ($token->type == T_WHITESPACE);
  45.     return $token;
  46. }
  47.  
  48. $OPERATORS = array('=', '.', '+', '-', '*', '/', '%', '||', '&&', '+=', '-=', '*=', '/=', '.=', '%=', '==', '!=', '<=', '>=', '<', '>', '===', '!==');
  49.  
  50. $IMPORT_STATEMENTS = array(T_REQUIRE, T_REQUIRE_ONCE, T_INCLUDE, T_INCLUDE_ONCE);
  51.  
  52. $CONTROL_STRUCTURES = array(T_IF, T_ELSEIF, T_FOREACH, T_FOR, T_WHILE, T_SWITCH, T_ELSE);
  53. $WHITESPACE_BEFORE = array('?', '{', '=>');
  54. $WHITESPACE_AFTER = array(',', '?', '=>');
  55.  
  56. foreach ($OPERATORS as $op) {
  57.     $WHITESPACE_BEFORE[] = $op;
  58.     $WHITESPACE_AFTER[] = $op;
  59. }
  60.  
  61. $matchingTernary = false;
  62.  
  63. // First pass - filter out unwanted tokens
  64. $filteredTokens = array();
  65. for ($i = 0, $n = count($tokens); $i < $n; $i++) {
  66.     $token = $tokens[$i];
  67.     if ($token->contents == '?') {
  68.         $matchingTernary = true;
  69.     }
  70.     if (in_array($token->type, $IMPORT_STATEMENTS) && nextToken($j)->contents == '(') {
  71.         $filteredTokens[] = $token;
  72.         if ($tokens[$i + 1]->type != T_WHITESPACE) {
  73.             $filteredTokens[] = new Token(array(T_WHITESPACE, ' '));
  74.         }
  75.         $i = $j;
  76.         do {
  77.             $i++;
  78.             $token = $tokens[$i];
  79.             if ($token->contents != ')') {
  80.                 $filteredTokens[] = $token;
  81.             }
  82.         } while ($token->contents != ')');
  83.     } elseif ($token->type == T_ELSE && nextToken($j)->type == T_IF) {
  84.         $i = $j;
  85.         $filteredTokens[] = new Token(array(T_ELSEIF, 'elseif'));
  86.     } elseif ($token->contents == ':') {
  87.         if ($matchingTernary) {
  88.             $matchingTernary = false;
  89.         } elseif ($tokens[$i - 1]->type == T_WHITESPACE) {
  90.             array_pop($filteredTokens); // Remove whitespace before
  91.         }
  92.         $filteredTokens[] = $token;
  93.     } else {
  94.         $filteredTokens[] = $token;
  95.     }
  96. }
  97. $tokens = $filteredTokens;
  98.  
  99. function isAssocArrayVariable($offset = 0) {
  100.     global $tokens, $i;
  101.     $j = $i + $offset;
  102.     return $tokens[$j]->type == T_VARIABLE &&
  103.         $tokens[$j + 1]->contents == '[' &&
  104.         $tokens[$j + 2]->type == T_STRING &&
  105.         preg_match('/[a-z_]+/', $tokens[$j + 2]->contents) &&
  106.         $tokens[$j + 3]->contents == ']';
  107. }
  108.  
  109. // Second pass - add whitespace
  110. $matchingTernary = false;
  111. $doubleQuote = false;
  112. for ($i = 0, $n = count($tokens); $i < $n; $i++) {
  113.     $token = $tokens[$i];
  114.     if ($token->contents == '?') {
  115.         $matchingTernary = true;
  116.     }
  117.     if ($token->contents == '"' && isAssocArrayVariable(1) && $tokens[$i + 5]->contents == '"') {
  118.         /*
  119.          * Handle case where the only thing quoted is the assoc array variable.
  120.          * Eg. "$value[key]"
  121.          */
  122.         $quote = $tokens[$i++]->contents;
  123.         $var = $tokens[$i++]->contents;
  124.         $openSquareBracket = $tokens[$i++]->contents;
  125.         $str = $tokens[$i++]->contents;
  126.         $closeSquareBracket = $tokens[$i++]->contents;
  127.         $quote = $tokens[$i]->contents;        
  128.         echo $var . "['" . $str . "']";
  129.         $doubleQuote = false;
  130.         continue;
  131.     }
  132.     if ($token->contents == '"') {
  133.         $doubleQuote = !$doubleQuote;
  134.     }
  135.     if ($doubleQuote && $token->contents == '"' && isAssocArrayVariable(1)) {
  136.         // don't echo "
  137.     } elseif ($doubleQuote && isAssocArrayVariable()) {
  138.         if ($tokens[$i - 1]->contents != '"') {
  139.             echo '" . ';
  140.         }
  141.         $var = $token->contents;
  142.         $openSquareBracket = $tokens[++$i]->contents;
  143.         $str = $tokens[++$i]->contents;
  144.         $closeSquareBracket = $tokens[++$i]->contents;
  145.         echo $var . "['" . $str . "']";
  146.         if ($tokens[$i + 1]->contents != '"') {
  147.             echo ' . "';
  148.         } else {
  149.             $i++; // process "
  150.             $doubleQuote = false;
  151.         }
  152.     } elseif ($token->type == T_STRING && $tokens[$i - 1]->contents == '[' && $tokens[$i + 1]->contents == ']') {
  153.         if (preg_match('/[a-z_]+/', $token->contents)) {
  154.             echo "'" . $token->contents . "'";
  155.         } else {
  156.             echo $token->contents;
  157.         }
  158.     } elseif ($token->type == T_ENCAPSED_AND_WHITESPACE || $token->type == T_STRING) {
  159.         echo $token->contents;
  160.     } elseif ($token->contents == '-' && in_array($tokens[$i + 1]->type, array(T_LNUMBER, T_DNUMBER))) {
  161.         echo '-';
  162.     } elseif (in_array($token->type, $CONTROL_STRUCTURES)) {
  163.         echo $token->contents;
  164.         if ($tokens[$i + 1]->type != T_WHITESPACE) {
  165.             echo ' ';
  166.         }
  167.     } elseif ($token->contents == '}' && in_array($tokens[$i + 1]->type, $CONTROL_STRUCTURES)) {
  168.         echo '} ';
  169.     } elseif ($token->contents == '=' && $tokens[$i + 1]->contents == '&') {
  170.         if ($tokens[$i - 1]->type != T_WHITESPACE) {
  171.             echo ' ';
  172.         }
  173.         $i++; // match &
  174.         echo '=&';
  175.         if ($tokens[$i + 1]->type != T_WHITESPACE) {
  176.             echo ' ';          
  177.         }
  178.     } elseif ($token->contents == ':' && $matchingTernary) {
  179.         $matchingTernary = false;
  180.         if ($tokens[$i - 1]->type != T_WHITESPACE) {
  181.             echo ' ';
  182.         }
  183.         echo ':';
  184.         if ($tokens[$i + 1]->type != T_WHITESPACE) {
  185.             echo ' ';
  186.         }
  187.     } elseif (in_array($token->contents, $WHITESPACE_BEFORE) && $tokens[$i - 1]->type != T_WHITESPACE &&
  188.         in_array($token->contents, $WHITESPACE_AFTER) && $tokens[$i + 1]->type != T_WHITESPACE) {
  189.         echo ' ' . $token->contents . ' ';
  190.     } elseif (in_array($token->contents, $WHITESPACE_BEFORE) && $tokens[$i - 1]->type != T_WHITESPACE) {
  191.         echo ' ' . $token->contents;
  192.     } elseif (in_array($token->contents, $WHITESPACE_AFTER) && $tokens[$i + 1]->type != T_WHITESPACE) {
  193.         echo $token->contents . ' ';
  194.     } else {
  195.         echo $token->contents;
  196.     }
  197. }
  198.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement