. */ class it_syntaxconverter { var $mode; # Either 'old', 'new', 'test' var $changes = 0; var $whitespace = array ( T_WHITESPACE => true, T_COMMENT => true, ); var $arrayoptional = array ( T_VARIABLE => true, T_STRING => true, ); # # Constructor # function it_syntaxconverter($string, $mode = "old") { if (defined('T_ML_COMMENT')) $this->whitespace[T_ML_COMMENT] = true; # PHP4 if (defined('T_DOC_COMMENT')) $this->whitespace[T_DOC_COMMENT] = true; # PHP5 $this->input = $string; $this->mode = $mode; $this->tokens = token_get_all($this->input); $this->count = count($this->tokens); $this->position = 0; $this->old = $this->parse(); $this->new = $this->convert($this->old); $this->output = $this->text($this->new); } # # Build parse tree from source string # function parse() { $result = array(); while ($this->position < $this->count) { $token = $this->tokens[$this->position++]; if (is_string($token)) { if ($token == '(') $result[] = array('LIST', $this->parse_list()); else $result[] = array('TEXT', $token); } else $result[] = $token; } return $result; } function parse_list() { $result = array(); while ($this->position < $this->count) { list($token, $element) = $this->parse_element(); $result[] = $element; if ($token == ')') break; } return $result; } function parse_element() { $result = array(); while ($this->position < $this->count) { $token = $this->tokens[$this->position++]; if (is_string($token)) { if ($token == '(') $result[] = array('LIST', $this->parse_list()); else if (($token == ',') || ($token == ')')) break; else $result[] = array('TEXT', $token); } else $result[] = $token; } return array($token, $result); } # # Modify parse tree to old syntax # function convert($tokens) { $result = array(); $op = ''; foreach ($tokens as $token) { list($id, $elements) = $token; if ($id == 'LIST') { if (empty($this->arrayoptional[$op])) { $list = array(); foreach ($elements as $element) $list[] = $this->convert($element); $result[] = array($id, $list); } else $result[] = array('LIST', $this->convert_list($elements)); } else $result[] = $token; if (empty($this->whitespace[$id])) $op = $id; } return $result; } function convert_list($elements) { if ($this->mode != 'new') { $result = $this->convert_list_namedparameters($elements); $result = $this->convert_list_trailingcomma($result); } else $result = $this->convert_list_arrayparameters($elements); return $result; } # # Remove array() around named parameter lists # function convert_list_arrayparameters($elements) { $result = array(); $locked = false; foreach ($elements as $element) { $element = $this->convert($element); if ($locked) { $result[] = $element; $locked = false; } else { $elementlist = $this->convert_pure_assoc_array($element); foreach ($elementlist as $element) $result[] = $element; $locked = count($elementlist) != 1; } } return $result; } function convert_pure_assoc_array($tokens) { $result = array(); $element = array(); $array = false; $locked = false; foreach ($tokens as $token) { list($id, $elements) = $token; if ($array) { if (($id == 'LIST') && $this->only_double_arrow($elements)) { foreach ($elements as $listelements) { $listelements = $this->convert($listelements); foreach ($listelements as $listelement) $element[] = $listelement; $result[] = $element; $element = array(); } # Continue with last element $element = array_pop($result); } else { $element[] = $array; $element[] = $token; } $array = false; $locked = true; } else if (!$locked && ($id == T_ARRAY)) { $array = $token; } else if (empty($this->whitespace[$id])) { if ($locked) { # Encountered something after array, abort $result = array(); $element = $tokens; break; } else { $element[] = $token; $locked = true; } } else $element[] = $token; } if ($element) $result[] = $element; return $result; } function only_double_arrow($elements) { $result = $elements; # Has to contain elements, empty is false foreach ($elements as $element) { if (!$this->has_double_arrow($element)) { $result = false; break; } } return $result; } # # Add array() around named parameter lists # function convert_list_namedparameters($elements) { $namedparams = array(); foreach ($elements as $element) { $element = $this->convert($element); if (!$this->has_double_arrow($element)) { if ($namedparams) { $result[] = $this->make_array($namedparams); $namedparams = array(); } $result[] = $element; } else $namedparams[] = $element; } if ($namedparams) $result[] = $this->make_array($namedparams); return $result; } # # Remove trailing comma by adding content to previous element # function convert_list_trailingcomma($elements) { $result = $elements; $last = count($result) - 1; if (($last > 0) && $this->is_empty($result[$last])) { $this->changes++; $element = array_pop($result); $last--; foreach ($element as $token) $result[$last][] = $token; } return $result; } function has_double_arrow($element) { $result = false; foreach ($element as $token) { list($id, $text) = $token; if ($id == T_DOUBLE_ARROW) { $result = true; break; } } return $result; } function make_array($namedparams) { $result = array(); $head = array(); $body = array(); $this->changes++; $namedparam = $namedparams[0]; foreach ($namedparam as $token) { list($id, $text) = $token; if ($body || (($id != 'LIST') && empty($this->whitespace[$id]))) $body[] = $token; else $result[] = $token; } $namedparams[0] = $body; $result[] = array(T_ARRAY, "array"); $result[] = array('LIST', $namedparams); return $result; } function is_empty($element) { $result = true; foreach ($element as $token) { list($id, $text) = $token; if (empty($this->whitespace[$id])) { $result = false; break; } } return $result; } # # Convert parse tree back to string # function text($tokens) { $result = ""; foreach ($tokens as $token) { list($id, $data) = $token; if ($id == 'LIST') { $list = array(); foreach ($data as $element) $list[] .= $this->text($element); $result .= "(" . join(",", $list) . ")"; } else $result .= $data; } return $result; } }