label = $label; } } function _processtoken_id($token){ return $token; } function _processtoken_symbol($token){ return new Symbol($token); } class VTTokenizer{ function __construct($expr){ $tokenTypes = array( "SPACE" => array('\s+', '_processtoken_id'), "SYMBOL" => array('[a-zA-Z][\w]*', '_processtoken_symbol'), "ESCAPED_SYMBOL" => array('?:`([^`]+)`', '_processtoken_symbol'), "STRING" => array('?:"((?:\\\\"|[^"])+)"', 'stripcslashes'), "FLOAT" => array('\d+[.]\d+', 'floatval'), "INTEGER" => array('\d+', 'intval'), 'OPERATOR' => array('[+]|[-]|[*]|>=|<=|[<]|[>]|==|\/', '_processtoken_symbol'), // NOTE: Any new Operator added should be updated in VTParser.inc::$precedence and operation at VTExpressionEvaluater 'OPEN_BRACKET' => array('[(]', '_processtoken_symbol'), 'CLOSE_BRACKET' => array('[)]', '_processtoken_symbol'), 'COMMA' => array('[,]', '_processtoken_symbol') ); $tokenReArr = array(); $tokenNames = array(); $this->tokenTypes = $tokenTypes; foreach($tokenTypes as $tokenName => $code){ list($re, $processtoken) = $code; $tokenReArr[] = '('.$re.')'; $tokenNames[] = $tokenName; } $this->tokenNames = $tokenNames; $tokenRe = '/'.implode('|', $tokenReArr).'/'; $this->EOF = new VTToken("EOF"); $matches = array(); preg_match_all($tokenRe, $expr, $matches, PREG_SET_ORDER); $this->matches = $matches; $this->idx = 0; } function nextToken(){ $matches = $this->matches; $idx = $this->idx; if($idx == sizeof($matches)){ return $this->EOF; }else{ $match = $matches[$idx]; $this->idx = $idx + 1; $i=1; while($match[$i]==null){ $i+=1; } $tokenName = $this->tokenNames[$i-1]; $token = new VTToken($tokenName); $token->value = $this->tokenTypes[$tokenName][1]($match[$i]); return $token; } } } class SpaceFilter{ function __construct($tokens){ $this->tokens = $tokens; } function nextToken(){ do{ $token = $this->tokens->nextToken(); }while($token->label == "SPACE"); return $token; } } ?>