_scanner = new Doctrine_Query_Scanner($input); $this->_printer = new Doctrine_Query_Printer(true); } public function getProduction($name) { if ( ! isset($this->_productions[$name])) { $class = 'Doctrine_Query_Production_' . $name; $this->_productions[$name] = new $class($this); } return $this->_productions[$name]; } /** * Attempts to match the given token with the current lookahead token. * * If they match, updates the lookahead token; otherwise raises a syntax * error. * * @param int|string token type or value */ public function match($token) { if (is_string($token)) { $isMatch = ($this->lookahead['value'] === $token); } else { $isMatch = ($this->lookahead['type'] === $token); } if ($isMatch) { //$this->_printer->println($this->lookahead['value']); $this->lookahead = $this->_scanner->scan(); $this->_errorDistance++; } else { $this->syntaxError(); } } public function syntaxError() { $this->_error('Unexpected "' . $this->lookahead['value'] . '"'); } public function semanticalError($message) { $this->_error($message); } protected function _error($message) { if ($this->_errorDistance >= self::MIN_ERROR_DISTANCE) { $message .= 'at line ' . $this->lookahead['line'] . ', column ' . $this->lookahead['column']; $this->_errors[] = $message; } $this->_errorDistance = 0; } /** * Returns the scanner object associated with this object. * * @return Doctrine_Query_Scanner */ public function getScanner() { return $this->_scanner; } public function getPrinter() { return $this->_printer; } /** * Parses a query string. * * @throws Doctrine_Query_Parser_Exception if errors were detected in the query string */ public function parse() { $this->lookahead = $this->_scanner->scan(); $this->getProduction('QueryLanguage')->execute(); $this->match(Doctrine_Query_Token::T_EOS); if (count($this->_errors)) { $msg = 'Query string parsing failed (' . implode('; ', $this->_errors) . ').'; throw new Doctrine_Query_Parser_Exception($msg); } } }