コード例 #1
0
ファイル: Parser.php プロジェクト: ray58750034/shorp
	public function parse($source){
		$root = new Node();
		$char = new Char();
		$tokenParsers = $this->initParsers();

		$token = $this->resetToken();
		$len = strlen($source);
		
		$parent = array(&$root);
		$current = new Node();
		
		$inBracket = false;

		for($i =0; $i<$len; ++$i){
			$c = $source[$i];
			// handle text first
			if(in_array($c, array('"', "'", '['))){				
				$ret = $this->findCDataEnd($source, $this->match[$c], $i+1);
				$i = $ret[1];
				if(!$inBracket && $c == '['){
					$this->proceedToken($token, $current, $tokenParsers);
					$this->resetToken($token);
					$current->setAttribute('[]', $ret[0]);
				}else{
					$token[$token[0]] .= $ret[0];					
				}				
			}
			
			// ',' ')' and '=' for attributes setting in '()'
			elseif($c == ',' || $c ==')'){
				if($token[$token[0]] != ''){				
					if($token[0] == 1){
						$current->setAtAttribute($token[1]);
						$this->resetToken($token);
					}else if($token[0] == 2){
						$current->setAttribute($token[1], $token[2]);
						$this->resetToken($token);
					}else{
						// should be error...
					}
				}
				if($c == ')'){
					$inBracket = false;
				}
			}else if($c == '='){
				$token[0] = 2;
			}
			
			// handle '()' and '{}' bracket
			else if(in_array($c, array('(', '{', '}'))){
				$this->proceedToken($token, $current, $tokenParsers);
				$this->resetToken($token);

				if($c == '{'){
					array_push($parent, $current);
					$current = new Node();
					
				}elseif($c == '}'){
					$p = array_pop($parent);
					if(!$current->isEmpty()){
						$p->addChild($current);
					}
					if(!$p->isEmpty()){
						$pp = end($parent);
						$pp->addChild($p);
					}
					$current = new Node();
				}elseif($c == '('){
					$inBracket = true;
				}
			}
			
			// handle tokens
			elseif($char->isSpecialChar($c)){
				$this->proceedToken($token, $current, $tokenParsers);
				$this->resetToken($token);
				$token[$token[0]] .= $c;
			}elseif($char->isTokenChar($c)){
				$token[$token[0]] .= $c;
			}
			else{				
				$this->proceedToken($token, $current, $tokenParsers);
				$this->resetToken($token);
				if(!$current->isEmpty() && !$inBracket){
					$p = end($parent);
					$p->addChild($current);
					
					$current = new Node();
				}				
			}
		}
		
			$this->proceedToken($token, $current, $tokenParsers);
		if(!$current->isEmpty() && !$inBracket){
			$p = end($parent);
			$p->addChild($current);
		}
		return $root;
	}