1<?php 2 3// @rodneyrehm 4// http://stackoverflow.com/a/7917979/99923 5class ParensParser 6{ 7 // something to keep track of parens nesting 8 protected $stack = null; 9 // current level 10 protected $current = null; 11 12 // input string to parse 13 protected $string = null; 14 // current character offset in string 15 protected $position = null; 16 // start of text-buffer 17 protected $buffer_start = null; 18 19 public function parse($string) 20 { 21 if (!$string) { 22 // no string, no data 23 return array(); 24 } 25 26 if ($string[0] == '[') { 27 // killer outer parens, as they're unnecessary 28 $string = substr($string, 1, -1); 29 } 30 31 $this->current = array(); 32 $this->stack = array(); 33 34 $this->string = $string; 35 $this->length = strlen($this->string); 36 // look at each character 37 for ($this->position=0; $this->position < $this->length; $this->position++) { 38 switch ($this->string[$this->position]) { 39 case '[': 40 $this->push(); 41 // push current scope to the stack an begin a new scope 42 array_push($this->stack, $this->current); 43 $this->current = array(); 44 break; 45 46 case ']': 47 $this->push(); 48 // save current scope 49 $t = $this->current; 50 // get the last scope from stack 51 $this->current = array_pop($this->stack); 52 // add just saved scope to current scope 53 $this->current[] = $t; 54 break; 55 /* 56 case ' ': 57 // make each word its own token 58 $this->push(); 59 break; 60 */ 61 default: 62 // remember the offset to do a string capture later 63 // could've also done $buffer .= $string[$position] 64 // but that would just be wasting resources… 65 if ($this->buffer_start === null) { 66 $this->buffer_start = $this->position; 67 } 68 } 69 } 70 71 return $this->current; 72 } 73 74 protected function push() 75 { 76 if ($this->buffer_start !== null) { 77 // extract string from buffer start to current position 78 $buffer = substr($this->string, $this->buffer_start, $this->position - $this->buffer_start); 79 // clean buffer 80 $this->buffer_start = null; 81 // throw token into current scope 82 $this->current[] = $buffer; 83 } 84 } 85} 86