rdql
[ class tree: rdql ] [ index: rdql ] [ all elements ]

Source for file Parser.php

Documentation is available at Parser.php

  1. <?php
  2. // ----------------------------------------------------------------------------------
  3. // Class: RDF_RDQL_Parser
  4. // ----------------------------------------------------------------------------------
  5. /**
  6.  * This class contains methods for parsing an RDQL query string into PHP variables.
  7.  * The output of the RDQLParser is an array with variables and constraints
  8.  * of each query clause (Select, From, Where, And, Using).
  9.  * To perform an RDQL query this array has to be passed to the RDQLEngine.
  10.  *
  11.  * @version  V0.7
  12.  * @author   Radoslaw Oldakowski <radol@gmx.de>
  13.  *
  14.  * @package rdql
  15.  * @access public
  16.  */
  17.  
  18.  
  19. class RDF_RDQL_Parser extends RDF_Object {
  20. /**
  21.  * Parsed query variables and constraints.
  22.  * { } are only used within the parser class and are not returned as parsed query.
  23.  * ( [] stands for an integer index - 0..N )
  24.  *
  25.  * @var     array   ['selectVars'][] = ?VARNAME
  26.  *                   ['sources'][]{['value']} = URI | QName
  27.  *                                {['is_qname'] = boolean}
  28.  *                   ['patterns'][]['subject']['value'] = VARorURI
  29.  *                                           {['is_qname'] = boolean}
  30.  *                                 ['predicate']['value'] = VARorURI
  31.  *                                             {['is_qname'] = boolean}
  32.  *                                 ['object']['value'] = VARorURIorLiterl
  33.  *                                          {['is_qname'] = boolean}
  34.  *                                           ['is_literal'] = boolean
  35.  *                                           ['l_lang'] = string
  36.  *                                           ['l_dtype'] = string
  37.  *                                          {['l_dtype_is_qname'] = boolean}
  38.  *                   ['filters'][]['string'] = string
  39.  *                                ['evalFilterStr'] = string
  40.  *                                ['reqexEqExprs'][]['var'] = ?VARNAME
  41.  *                                                  ['operator'] = (eq | ne)
  42.  *                                                  ['regex'] = string
  43.  *                                ['strEqExprs'][]['var'] = ?VARNAME
  44.  *                                                ['operator'] = (eq | ne)
  45.  *                                                ['value'] = string
  46.  *                                                ['value_type'] = ('variable' | 'URI' | 'QName' | 'Literal')
  47.  *                                                ['value_lang'] = string
  48.  *                                                ['value_dtype'] = string
  49.  *                                               {['value_dtype_is_qname'] = boolean}
  50.  *                                ['numExpr']['vars'][] = ?VARNAME
  51.  *                  {['ns'][PREFIX] = NAMESPACE}
  52.  
  53.      * @access private
  54.      */
  55.     var $parsedQuery;
  56.  
  57.     /**
  58.      * Query string divided into a sequence of tokens.
  59.      * A token is either: ' ' or "\n" or "\r" or "\t" or ',' or '(' or ')'
  60.      * or a string containing any characters except from the above.
  61.      *
  62.      * @var array 
  63.      * @access private
  64.      */
  65.     var $tokens;
  66.  
  67.     /**
  68.      * Parse the given RDQL query string and return an array with query variables and constraints.
  69.      *
  70.      * @param string $queryString 
  71.      * @return array $this->parsedQuery
  72.      * @access public
  73.      */
  74.     function &parseQuery($queryString)
  75.     {
  76.         $cleanQueryString $this->removeComments($queryString);
  77.         $this->tokenize($cleanQueryString);
  78.         $this->startParsing();
  79.         if ($this->parsedQuery['selectVars'][0== '*'{
  80.             $this->parsedQuery['selectVars'$this->findAllQueryVariables();
  81.         else {
  82.             $this->_checkSelectVars();
  83.         }
  84.         $this->replaceNamespacePrefixes();
  85.  
  86.         return $this->parsedQuery;
  87.     }
  88.  
  89.     /**
  90.      * Remove comments from the passed query string.
  91.      *
  92.      * @param string $query 
  93.      * @return string 
  94.      * @throws PHPError
  95.      * @access private
  96.      */
  97.     function removeComments($query)
  98.     {
  99.         $last strlen($query)-1;
  100.         $query .= ' ';
  101.         $clean '';
  102.         for ($i = 0; $i <= $last$i++{
  103.             // don't search for comments inside a 'literal'@lang^^dtype or "literal"@lang^^dtype
  104.             if ($query{$i== "'" || $query{$i== '"'{
  105.                 $quotMark $query{$i};
  106.                 do {
  107.                     $clean .= $query{$i++};
  108.                 while ($i $last && $query{$i!= $quotMark);
  109.                 $clean .= $query{$i};
  110.                 // language
  111.                 if ($query{$i+1== '@'{
  112.                     do {
  113.                         if ($query{$i+1== '^' && $query{$i+2== '^'{
  114.                             break;
  115.                         }
  116.                         $clean .= $query{++$i};
  117.                     while ($i $last && $query{$i!= ' ' && $query{$i!= "\t"
  118.                         && $query{$i!= "\n" && $query{$i!= "\r");
  119.                 }
  120.                 // datatype
  121.                 if ($query{$i+1== '^' && $query{$i+2== '^'{
  122.                     do {
  123.                         $clean .= $query{++$i};
  124.                     while ($i $last && $query{$i!= ' ' && $query{$i!= "\t"
  125.                         && $query{$i!= "\n" && $query{$i!= "\r");
  126.                 }
  127.                 // don't search for comments inside an <URI> either
  128.             elseif ($query{$i== '<'{
  129.                 do {
  130.                     $clean .= $query{$i++};
  131.                 while ($i $last && $query{$i!= '>');
  132.                 $clean .= $query{$i};
  133.             elseif ($query{$i== '/'{
  134.                 // clear: // comment
  135.                 if ($i $last && $query{$i+1== '/'{
  136.                     while ($i $last && $query{$i!= "\n" && $query{$i!= "\r"{
  137.                         ++$i;
  138.                     }
  139.                     $clean .= ' ';
  140.                     // clear: /*comment*/
  141.                 elseif ($i $last-2 && $query{$i+1== '*'{
  142.                     $i += 2;
  143.                     while ($i $last && ($query{$i!= '*' || $query{$i+1!= '/')) {
  144.                         ++$i;
  145.                     }
  146.                     if ($i >= $last && ($query{$last-1!= '*' || $query{$last!= '/')) {
  147.                         $errmsg "unterminated comment - '*/' missing";
  148.                         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SYNTAXnullnull$errmsg);
  149.                     }
  150.                     ++$i;
  151.                 else {
  152.                     $clean .= $query{$i};
  153.                 }
  154.             else {
  155.                 $clean .= $query{$i};
  156.             }
  157.         }
  158.         return $clean;
  159.     }
  160.  
  161.     /**
  162.      * Divide the query string into tokens.
  163.      * A token is either: ' ' or "\n" or "\r" or '\t' or ',' or '(' or ')'
  164.      * or a string containing any character except from the above.
  165.      *
  166.      * @param string $queryString 
  167.      * @access private
  168.      */
  169.     function tokenize($queryString)
  170.     {
  171.         $queryString trim($queryString" \r\n\t");
  172.         $specialChars = array (" ""\t""\r""\n"",""("")");
  173.         $len strlen($queryString);
  174.         $this->tokens[0'';
  175.         $n = 0;
  176.  
  177.         for ($i = 0; $i $len; ++$i{
  178.             if (!in_array($queryString{$i}$specialChars)) {
  179.                 $this->tokens[$n.= $queryString{$i};
  180.             else {
  181.                 if ($this->tokens[$n!= ''{
  182.                     ++$n;
  183.                 }
  184.                 $this->tokens[$n$queryString{$i};
  185.                 $this->tokens[++$n'';
  186.             }
  187.         }
  188.     }
  189.  
  190.     /**
  191.      * Start parsing of the tokenized query string.
  192.      *
  193.      * @access private
  194.      */
  195.     function startParsing()
  196.     {
  197.         $this->parseSelect();
  198.     }
  199.  
  200.     /**
  201.      * Parse the SELECT clause of an RDQL query.
  202.      * When the parsing of the SELECT clause is finished, this method will call
  203.      * a suitable method to parse the subsequent clause.
  204.      *
  205.      * @throws PhpError
  206.      * @access private
  207.      */
  208.     function parseSelect()
  209.     {
  210.         $this->_clearWhiteSpaces();
  211.         // Check if the queryString contains a "SELECT" token
  212.         if (strcasecmp('SELECT'current($this->tokens))) {
  213.             $errmsg current($this->tokens"' - SELECT keyword expected";
  214.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  215.         }
  216.         unset($this->tokens[key($this->tokens)]);
  217.         $this->_clearWhiteSpaces();
  218.         // Parse SELECT *
  219.         if (current($this->tokens== '*'{
  220.             unset($this->tokens[key($this->tokens)]);
  221.             $this->parsedQuery['selectVars'][0'*';
  222.             $this->_clearWhiteSpaces();
  223.             if (strcasecmp('FROM'current($this->tokens))
  224.                 && strcasecmp('SOURCE'current($this->tokens))
  225.                 && strcasecmp('WHERE'current($this->tokens))
  226.             {
  227.                 $errmsg htmlspecialchars(current($this->tokens)) .
  228.                     ' - SOURCE or WHERE clause expected';
  229.                 return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SYNTAXnullnull$errmsg);
  230.             }
  231.         }
  232.         // Parse SELECT ?Var (, ?Var)*
  233.         $commaExpected = false;
  234.         $comma = false;
  235.         while (current($this->tokens!= null{
  236.             $k key($this->tokens);
  237.             $token $this->tokens[$k];
  238.  
  239.             switch ($token{
  240.             case ',':
  241.                 if (!$commaExpected{
  242.                     $errmsg 'unexpected comma';
  243.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  244.                 }
  245.                 $comma = true;
  246.                 $commaExpected = false;
  247.                 break;
  248.             case '(':
  249.             case ')':
  250.                 $errmsg = "'$token' - illegal input";
  251.                 return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  252.                 break;
  253.             default :
  254.                 if (!strcasecmp('FROM'$token|| !strcasecmp('SOURCE'$token)) {
  255.                     if ($comma{
  256.                         $errmsg 'unexpected comma';
  257.                         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  258.                     }
  259.                     unset($this->tokens[$k]);
  260.                     return $this->parseFrom();
  261.                 elseif (!strcasecmp('WHERE'$token&& !$comma{
  262.                     if ($comma{
  263.                         $errmsg 'unexpected comma';
  264.                         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  265.                     }
  266.                     unset($this->tokens[$k]);
  267.                     return $this->parseWhere();
  268.                 }
  269.                 if ($token{0== '?'{
  270.                     $this->parsedQuery['selectVars'][$this->_validateVar($token'SELECT');
  271.                     $commaExpected = true;
  272.                     $comma = false;
  273.                 else {
  274.                     $errmsg = "'$token' - '?' missing";
  275.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  276.                 }
  277.             }
  278.             unset($this->tokens[$k]);
  279.             $this->_clearWhiteSpaces();
  280.         }
  281.         $errmsg 'WHERE clause missing';
  282.         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  283.     }
  284.  
  285.     /**
  286.      * Parse the FROM/SOURCES clause of an RDQL query
  287.      * When the parsing of this clause is finished, parseWhere() will be called.
  288.      *
  289.      * @throws PhpError
  290.      * @access private
  291.      */
  292.     function parseFrom()
  293.     {
  294.         $comma = false;
  295.         $commaExpected = false;
  296.         $i = -1;
  297.         while (current($this->tokens!= null{
  298.             $this->_clearWhiteSpaces();
  299.             if (!strcasecmp('WHERE'current($this->tokens))
  300.                 && count($this->parsedQuery['sources']!= 0
  301.             {
  302.                 if ($comma{
  303.                     $errmsg 'unexpected comma';
  304.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SELECTnullnull$errmsg);
  305.                 }
  306.                 unset($this->tokens[key($this->tokens)]);
  307.                 return $this->parseWhere();
  308.             }
  309.             if (current($this->tokens== ','{
  310.                 if ($commaExpected{
  311.                     $comma = true;
  312.                     $commaExpected = false;
  313.                     unset($this->tokens[key($this->tokens)]);
  314.                 else {
  315.                     $errmsg 'unecpected comma';
  316.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_SOURCEnullnull$errmsg);
  317.                 }
  318.             else {
  319.                 $token current($this->tokens);
  320.                 $this->parsedQuery['sources'][++$i]['value'$this->_validateURI($tokenRDF_RDQL_ERROR_SOURCE);
  321.                 if ($token{0!= '<'{
  322.                     $this->parsedQuery['sources'][$i]['is_qname'= TRUE;
  323.                 }
  324.                 $commaExpected = TRUE;
  325.                 $comma = FALSE;
  326.             }
  327.         }
  328.         $errmsg 'WHERE clause missing';
  329.         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  330.     }
  331.  
  332.     /**
  333.      * *'
  334.      * Parse the WHERE clause of an RDQL query.
  335.      * When the parsing of the WHERE clause is finished, this method will call
  336.      * a suitable method to parse the subsequent clause if provided.
  337.      *
  338.      * @throws PhpError
  339.      * @access private
  340.      */
  341.     function parseWhere()
  342.     {
  343.         $comma = false;
  344.         $commaExpected = false;
  345.         $i = 0;
  346.  
  347.         do {
  348.             $this->_clearWhiteSpaces();
  349.             if (!strcasecmp('AND'current($this->tokens))
  350.                 && count($this->parsedQuery['patterns']!= 0
  351.             {
  352.                 if ($comma{
  353.                     $errmsg 'unexpected comma';
  354.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  355.                 }
  356.                 unset($this->tokens[key($this->tokens)]);
  357.                 return $this->parseAnd();
  358.             elseif (!strcasecmp('USING'current($this->tokens))
  359.                 && count($this->parsedQuery['patterns']!= 0
  360.             {
  361.                 if ($comma{
  362.                     $errmsg 'unexpected comma';
  363.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  364.                 }
  365.                 unset($this->tokens[key($this->tokens)]);
  366.                 return $this->parseUsing();
  367.             }
  368.  
  369.             if (current($this->tokens== ','{
  370.                 $comma = true;
  371.                 $this->_checkComma($commaExpected'WHERE');
  372.             else {
  373.                 if (current($this->tokens!= '('{
  374.                     $errmsg current($this->tokens"' - '(' expected";
  375.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  376.                 }
  377.                 unset($this->tokens[key($this->tokens)]);
  378.                 $this->_clearWhiteSpaces();
  379.  
  380.                 $this->parsedQuery['patterns'][$i]['subject'=
  381.                     $this->_validateVarUri(current($this->tokens));
  382.                 $this->_checkComma(true'WHERE');
  383.                 $this->parsedQuery['patterns'][$i]['predicate'=
  384.                     $this->_validateVarUri(current($this->tokens));
  385.                 $this->_checkComma(true'WHERE');
  386.                 $this->parsedQuery['patterns'][$i++]['object'=
  387.                     $this->_validateVarUriLiteral(current($this->tokens));
  388.                 $this->_clearWhiteSpaces();
  389.  
  390.                 if (current($this->tokens!= ')'{
  391.                     $errmsg current($this->tokens"' - ')' expected";
  392.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  393.                 }
  394.                 unset($this->tokens[key($this->tokens)]);
  395.                 $this->_clearWhiteSpaces();
  396.                 $commaExpected = true;
  397.                 $comma = false;
  398.             }
  399.         while (current($this->tokens!= null);
  400.  
  401.         if ($comma{
  402.             $errmsg 'unexpected comma';
  403.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  404.         }
  405.     }
  406.  
  407.     /**
  408.      * Parse the AND clause of an RDQL query
  409.      *
  410.      * @throws PhpError
  411.      * @access private
  412.      * @toDo clear comments
  413.      */
  414.     function parseAnd()
  415.     {
  416.         $this->_clearWhiteSpaces();
  417.         $n = 0;
  418.         $filterStr '';
  419.  
  420.         while (current($this->tokens!= null{
  421.             $k key($this->tokens);
  422.             $token $this->tokens[$k];
  423.  
  424.             if (!strcasecmp('USING'$token)) {
  425.                 $this->parseFilter($n$filterStr);
  426.                 unset($this->tokens[$k]);
  427.                 return $this->parseUsing();
  428.             elseif ($token == ','{
  429.                 $this->parseFilter($n$filterStr);
  430.                 $filterStr '';
  431.                 $token '';
  432.                 ++$n;
  433.             }
  434.             $filterStr .= $token;
  435.             unset($this->tokens[$k]);
  436.         }
  437.         $this->parseFilter($n$filterStr);
  438.     }
  439.  
  440.     /**
  441.      * Parse the USING clause of an RDQL query
  442.      *
  443.      * @throws PhpError
  444.      * @access private
  445.      */
  446.     function parseUsing()
  447.     {
  448.         $commaExpected = false;
  449.         $comma = false;
  450.  
  451.         do {
  452.             $this->_clearWhiteSpaces();
  453.             if (current($this->tokens== ','{
  454.                 $comma = true;
  455.                 $this->_checkComma($commaExpected'USING');
  456.             else {
  457.                 $prefix $this->_validatePrefix(current($this->tokens));
  458.                 $this->_clearWhiteSpaces();
  459.  
  460.                 if (strcasecmp('FOR'current($this->tokens))) {
  461.                     $errmsg "keyword 'FOR' missing in the namespace declaration";
  462.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_USINGnullnull$errmsg);
  463.                 }
  464.                 unset($this->tokens[key($this->tokens)]);
  465.                 $this->_clearWhiteSpaces();
  466.  
  467.                 $this->parsedQuery['ns'][$prefix=
  468.                     $this->_validateUri(current($this->tokens)'USING');
  469.                 $this->_clearWhiteSpaces();
  470.                 $commaExpected = true;
  471.                 $comma = false;
  472.             }
  473.         while (current($this->tokens!= null);
  474.  
  475.         if ($comma{
  476.             $errmsg 'unexpected comma';
  477.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  478.         }
  479.     }
  480.  
  481.     /**
  482.      * Check if a filter from the AND clause contains an equal number of '(' and ')'
  483.      * and parse filter expressions.
  484.      *
  485.      * @param integer $n 
  486.      * @param string $filter 
  487.      * @throws PHPError
  488.      * @access private
  489.      */
  490.     function parseFilter($n$filter)
  491.     {
  492.         if ($filter == null{
  493.             $errmsg 'unexpected comma';
  494.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_ANDnullnull$errmsg);
  495.         }
  496.         $paren substr_count($filter'('substr_count($filter')');
  497.         if ($paren != 0{
  498.             if ($paren > 0{
  499.                 $errmsg = "'{htmlspecialchars($filter)}' - ')' missing ";
  500.             elseif ($paren < 0{
  501.                 $errmsg = "'{htmlspecialchars($filter)}' - too many ')' ";
  502.             }
  503.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_ANDnullnull$errmsg);
  504.         }
  505.  
  506.         $this->parsedQuery['filters'][$n$this->parseExpressions($filter);
  507.     }
  508.  
  509.     /**
  510.      * Parse expressions inside the passed filter:
  511.      * 1)  regex equality expressions:    ?var [~~ | =~ | !~ ] REG_EX
  512.      * 2a) string equality expressions:   ?var  [eq | ne] "literal"@lang^^dtype.
  513.      * 2b) string equality expressions:   ?var [eq | ne] <URI> or ?var [eq | ne] prefix:local_name
  514.      * 3)  numerical expressions: e.q.    (?var1 - ?var2)*4 >= 20
  515.      *
  516.      * In cases 1-2 parse each expression of the given filter into an array of variables.
  517.      * For each parsed expression put a place holder (e.g. ##RegEx_1##) into the filterStr.
  518.      * The RDQLengine will then replace each place holder with the outcomming boolean value
  519.      * of the corresponding expression.
  520.      * The remaining filterStr contains only numerical expressions and place holders.
  521.      *
  522.      * @param string $filteStr 
  523.      * @return array ['string'] = string
  524.      *                    ['evalFilterStr'] = string
  525.      *                    ['reqexEqExprs'][]['var'] = ?VARNAME
  526.      *                                      ['operator'] = (eq | ne)
  527.      *                                      ['regex'] = string
  528.      *                    ['strEqExprs'][]['var'] = ?VARNAME
  529.      *                                   ['operator'] = (eq | ne)
  530.      *                                   ['value'] = string
  531.      *                                   ['value_type'] = ('variable' | 'URI' 'QName' | | 'Literal')
  532.      *                                   ['value_lang'] = string
  533.      *                                   ['value_dtype'] = string
  534.      *                                   ['value_dtype_is_qname'] = boolean
  535.      *                    ['numExpr']['vars'][] = ?VARNAME
  536.      * @access private
  537.      */
  538.     function parseExpressions($filterStr)
  539.     {
  540.         $parsedFilter['string'$filterStr;
  541.         $parsedFilter['regexEqExprs'= array();
  542.         $parsedFilter['strEqExprs'= array();
  543.         $parsedFilter['numExprVars'= array();
  544.         // parse regex string equality expressions, e.g. ?x ~~ !//foo.com/r!i
  545.         $reg_ex  "/(\?[a-zA-Z0-9_]+)\s+([~!=]~)\s+(['|\"])?([^\s'\"]+)(['|\"])?/";
  546.         $eqExprs = array();
  547.         preg_match_all($reg_ex$filterStr$eqExprs);
  548.         foreach ($eqExprs[0as $i => $eqExpr{
  549.             $this->_checkRegExQuotation($filterStr$eqExprs[3][$i]$eqExprs[5][$i]);
  550.             $parsedFilter['regexEqExprs'][$i]['var'$this->_isDefined($eqExprs[1][$i]);
  551.             $parsedFilter['regexEqExprs'][$i]['operator'$eqExprs[2][$i];
  552.             $parsedFilter['regexEqExprs'][$i]['regex'$eqExprs[4][$i];
  553.  
  554.             $filterStr str_replace($eqExpr" ##RegEx_$i## "$filterStr);
  555.         }
  556.         // parse ?var  [eq | ne] "literal"@lang^^dtype
  557.         $reg_ex  "/(\?[a-zA-Z0-9_]+)\s+(eq|ne)\s+(\'[^\']*\'|\"[^\"]*\")";
  558.         $reg_ex .= "(@[a-zA-Z]+)?(\^{2}\S+:?\S+)?/i";
  559.         preg_match_all($reg_ex$filterStr$eqExprs);
  560.         foreach ($eqExprs[0as $i => $eqExpr{
  561.             $parsedFilter['strEqExprs'][$i]['var'$this->_isDefined($eqExprs[1][$i]);
  562.             $parsedFilter['strEqExprs'][$i]['operator'strtolower($eqExprs[2][$i]);
  563.             $parsedFilter['strEqExprs'][$i]['value'trim($eqExprs[3][$i],"'\"");
  564.             $parsedFilter['strEqExprs'][$i]['value_type''Literal';
  565.             $parsedFilter['strEqExprs'][$i]['value_lang'substr($eqExprs[4][$i]1);
  566.             $dtype substr($eqExprs[5][$i]2);
  567.             if ($dtype{
  568.                 $parsedFilter['strEqExprs'][$i]['value_dtype'$this->_validateUri($dtypeRDF_RDQL_ERROR_AND);
  569.                 if ($dtype{0!= '<'{
  570.                     $parsedFilter['strEqExprs'][$i]['value_dtype_is_qname'= true;
  571.                 }
  572.             else {
  573.                 $parsedFilter['strEqExprs'][$i]['value_dtype''';
  574.             }
  575.  
  576.             $filterStr str_replace($eqExprs[0][$i]" ##strEqExpr_$i## "$filterStr);
  577.         }
  578.         // parse ?var [eq | ne] ?var
  579.         $ii count($parsedFilter['strEqExprs']);
  580.         $reg_ex  "/(\?[a-zA-Z0-9_]+)\s+(eq|ne)\s+(\?[a-zA-Z0-9_]+)/i";
  581.         preg_match_all($reg_ex$filterStr$eqExprs);
  582.         foreach ($eqExprs[0as $i => $eqExpr{
  583.             $parsedFilter['strEqExprs'][$ii]['var'$this->_isDefined($eqExprs[1][$i]);
  584.             $parsedFilter['strEqExprs'][$ii]['operator'strtolower($eqExprs[2][$i]);
  585.             $parsedFilter['strEqExprs'][$ii]['value'$this->_isDefined($eqExprs[3][$i]);
  586.             $parsedFilter['strEqExprs'][$ii]['value_type''variable';
  587.  
  588.             $filterStr str_replace($eqExprs[0][$i]" ##strEqExpr_$ii## "$filterStr);
  589.             $ii++;
  590.         }
  591.         // parse ?var [eq | ne] <URI> or ?var [eq | ne] prefix:local_name
  592.         $reg_ex  "/(\?[a-zA-Z0-9_]+)\s+(eq|ne)\s+((<\S+>)|(\S+:\S*))/i";
  593.         preg_match_all($reg_ex$filterStr$eqExprs);
  594.         foreach ($eqExprs[0as $i => $eqExpr{
  595.             $parsedFilter['strEqExprs'][$ii]['var'$this->_isDefined($eqExprs[1][$i]);
  596.             $parsedFilter['strEqExprs'][$ii]['operator'strtolower($eqExprs[2][$i]);
  597.             if ($eqExprs[4][$i]{
  598.                 $parsedFilter['strEqExprs'][$ii]['value'trim($eqExprs[4][$i]"<>");
  599.                 $parsedFilter['strEqExprs'][$ii]['value_type''URI';
  600.             else if($eqExprs[5][$i]{
  601.                 $this->_validateQName($eqExprs[5][$i]RDF_RDQL_ERROR_AND);
  602.                 $parsedFilter['strEqExprs'][$ii]['value'$eqExprs[5][$i];
  603.                 $parsedFilter['strEqExprs'][$ii]['value_type''QName';
  604.             }
  605.  
  606.             $filterStr str_replace($eqExprs[0][$i]" ##strEqExpr_$ii## "$filterStr);
  607.             $ii++;
  608.         }
  609.         $parsedFilter['evalFilterStr'$filterStr;
  610.  
  611.         // all that is left are numerical expressions and place holders for the above expressions
  612.         preg_match_all("/\?[a-zA-Z0-9_]+/"$filterStr$vars);
  613.         foreach ($vars[0as $var{
  614.             $parsedFilter['numExprVars'][$this->_isDefined($var);
  615.         }
  616.  
  617.         return $parsedFilter;
  618.     }
  619.  
  620.     /**
  621.      * Find all query variables used in the WHERE clause.
  622.      *
  623.      * @return array [] = ?VARNAME
  624.      * @access private
  625.      */
  626.     function findAllQueryVariables()
  627.     {
  628.         $vars = array();
  629.         foreach ($this->parsedQuery['patterns'as $pattern{
  630.             $count = 0;
  631.             foreach ($pattern as $v{
  632.                if ($v['value'&& $v['value']{0== '?'{
  633.                     ++$count;
  634.                     if (!in_array($v['value']$vars)) {
  635.                         $vars[$v['value'];
  636.                     }
  637.                 }
  638.             }
  639.             if (!$count{
  640.                 $errmsg 'pattern contains no variables';
  641.                 return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  642.             }
  643.         }
  644.  
  645.         return $vars;
  646.     }
  647.  
  648.     /**
  649.      * Replace all namespace prefixes in the pattern and constraint clause of an RDQL query
  650.      * with the namespaces declared in the USING clause and default namespaces.
  651.      *
  652.      * @access private
  653.      */
  654.     function replaceNamespacePrefixes()
  655.     {
  656.         if (!isset($this->parsedQuery['ns'])) {
  657.             $this->parsedQuery['ns'= array();
  658.         }
  659.         // add default namespaces
  660.         // if in an RDQL query a reserved prefix (e.g. rdf: rdfs:) is used
  661.         // it will be overridden by the default namespace defined in constants.php
  662.         $this->parsedQuery['ns'array_merge($this->parsedQuery['ns']$GLOBALS['_RDF_RDQL_default_prefixes']);
  663.  
  664.         // replace namespace prefixes in the FROM clause
  665.         if (isset($this->parsedQuery['sources'])) {
  666.             foreach ($this->parsedQuery['sources'as $n => $source{
  667.                 if (isset($source['is_qname'])) {
  668.                     $this->parsedQuery['sources'][$n$this->_replaceNamespacePrefix($source['value']RDF_RDQL_ERROR_SOURCE);
  669.                 else {
  670.                     foreach ($this->parsedQuery['ns'as $prefix => $uri{
  671.                         $source['value'eregi_replace("$prefix:"$uri$source['value']);
  672.                     }
  673.                    $this->parsedQuery['sources'][$n$source['value'];
  674.                 }
  675.             }
  676.         }
  677.  
  678.         // replace namespace prefixes in the where clause
  679.         foreach ($this->parsedQuery['patterns'as $n => $pattern{
  680.             foreach ($pattern as $key => $v{
  681.                 if ($v['value'&& $v['value']{0!= '?'{
  682.                     if (isset($v['is_qname'])) {
  683.                         $this->parsedQuery['patterns'][$n][$key]['value']
  684.                             = $this->_replaceNamespacePrefix($v['value']RDF_RDQL_ERROR_WHERE);
  685.                         unset($this->parsedQuery['patterns'][$n][$key]['is_qname']);
  686.                     else // is quoted URI (== <URI>) or Literal
  687.                         if (isset($this->parsedQuery['patterns'][$n][$key]['is_literal'])) {
  688.                             if (isset($this->parsedQuery['patterns'][$n][$key]['l_dtype_is_qname'])) {
  689.                                 $this->parsedQuery['patterns'][$n][$key]['l_dtype']
  690.                                     = $this->_replaceNamespacePrefix($v['l_dtype']RDF_RDQL_ERROR_WHERE);
  691.                                 unset($this->parsedQuery['patterns'][$n][$key]['l_dtype_is_qname']);    
  692.                             else {
  693.                                 foreach ($this->parsedQuery['ns'as $prefix => $uri{
  694.                                     $this->parsedQuery['patterns'][$n][$key]['l_dtype']
  695.                                         = eregi_replace("$prefix:"$uri$this->parsedQuery['patterns'][$n][$key]['l_dtype']);
  696.                                 }
  697.                             }
  698.                         else {
  699.                             foreach ($this->parsedQuery['ns'as $prefix => $uri{
  700.                                 $this->parsedQuery['patterns'][$n][$key]['value']
  701.                                     = eregi_replace("$prefix:"$uri$this->parsedQuery['patterns'][$n][$key]['value']);
  702.                             }
  703.                         }
  704.                     }
  705.                 }
  706.             }
  707.         }
  708.  
  709.         // replace prefixes in the constraint clause
  710.         if (isset($this->parsedQuery['filters'])) {
  711.             foreach ($this->parsedQuery['filters'as $n => $filter{
  712.                 foreach ($filter['strEqExprs'as $i => $expr{
  713.                     if ($expr['value_type'== 'QName'{
  714.                         $this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value']
  715.                             = $this->_replaceNamespacePrefix($expr['value']RDF_RDQL_ERROR_AND);
  716.                         $this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value_type''URI';
  717.                     }
  718.                     if ($expr['value_type'== 'URI'{
  719.                         foreach ($this->parsedQuery['ns'as $prefix => $uri{
  720.                             $this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value']
  721.                                 = eregi_replace("$prefix:"$uri$this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value']);
  722.                         }
  723.                     elseif ($expr['value_type'== 'Literal'{
  724.                         if (isset($expr['value_dtype_is_qname'])) {
  725.                             $this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value_dtype']
  726.                                 = $this->_replaceNamespacePrefix($expr['value_dtype']RDF_RDQL_ERROR_AND);
  727.                             unset($this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value_dtype_is_qname']);
  728.                         else {
  729.                             foreach ($this->parsedQuery['ns'as $prefix => $uri{
  730.                                 $this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value_dtype']
  731.                                     = eregi_replace("$prefix:"$uri$this->parsedQuery['filters'][$n]['strEqExprs'][$i]['value_dtype']);
  732.                             }
  733.                         }
  734.                     }
  735.                 }
  736.             }
  737.         }
  738.  
  739.         unset($this->parsedQuery['ns']);
  740.     }
  741.  
  742.     // =============================================================================
  743.     // *************************** helper functions ********************************
  744.     // =============================================================================
  745.     /**
  746.      * Remove whitespace-tokens from the array $this->tokens
  747.      *
  748.      * @access private
  749.      */
  750.     function _clearWhiteSpaces()
  751.     {
  752.         while (current($this->tokens== ' '
  753.             || current($this->tokens== "\n"
  754.             || current($this->tokens== "\t"
  755.             || current($this->tokens== "\r"
  756.         {
  757.             unset($this->tokens[key($this->tokens)]);
  758.         }
  759.     }
  760.  
  761.     /**
  762.      * Check if the query string of the given clause contains an undesired ','.
  763.      * If a comma was correctly placed then remove it and clear all whitespaces.
  764.      *
  765.      * @param string $commaExpected 
  766.      * @param string $clause_error 
  767.      * @throws PHPError
  768.      * @access private
  769.      */
  770.     function _checkComma($commaExpected$clause_error)
  771.     {
  772.         $this->_clearWhiteSpaces();
  773.         if (current($this->tokens== ','{
  774.             if (!$commaExpected{
  775.                 $errmsg 'unexpected comma';
  776.                 return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  777.             else {
  778.                 unset($this->tokens[key($this->tokens)]);
  779.                 $this->_checkComma(false$clause_error);
  780.             }
  781.         }
  782.     }
  783.  
  784.     /**
  785.      * Check if the given token is either a variable (?var) or the first token of an URI (<URI>).
  786.      * In case of an URI this function returns the whole URI string.
  787.      *
  788.      * @param string $token 
  789.      * @return array ['value'] = string
  790.      * @throws PHPError
  791.      * @access private
  792.      */
  793.     function _validateVarUri($token)
  794.     {
  795.         if ($token{0== '?'{
  796.             $token_res['value'$this->_validateVar($tokenRDF_RDQL_ERROR_WHERE);
  797.         else {
  798.             $token_res['value'$this->_validateUri($tokenRDF_RDQL_ERROR_WHERE);
  799.             if ($token{0!= '<'{
  800.                 $token_res['is_qname'= true;
  801.             }
  802.         }
  803.         return $token_res;
  804.     }
  805.  
  806.     /**
  807.      * Check if the given token is either a variable (?var) or the first token
  808.      * of either an URI (<URI>) or a literal ("Literal").
  809.      * In case of a literal return an array with literal properties (value, language, datatype).
  810.      * In case of a variable or an URI return only ['value'] = string.
  811.      *
  812.      * @param string $token 
  813.      * @return array ['value'] = string
  814.      *                  ['is_qname'] = boolean
  815.      *                  ['is_literal'] = boolean
  816.      *                  ['l_lang'] = string
  817.      *                  ['l_dtype'] = string
  818.      * @throws PHPError
  819.      * @access private
  820.      */
  821.     function _validateVarUriLiteral($token)
  822.     {
  823.         if ($token{0== '?'{
  824.             $statement_object['value'$this->_validateVar($tokenRDF_RDQL_ERROR_WHERE);
  825.         elseif ($token{0== "'" || $token{0== '"'{
  826.             $statement_object $this->_validateLiteral($token);
  827.         elseif ($token{0== '<'{
  828.             $statement_object['value'$this->_validateUri($tokenRDF_RDQL_ERROR_WHERE);
  829.         elseif (ereg(':'$token)) {
  830.             $statement_object['value'$this->_validateUri($tokenRDF_RDQL_ERROR_WHERE);
  831.             $statement_object['is_qname'= TRUE;
  832.         else {
  833.             $errmsg = " '$token' - ?Variable, &lt;URI&gt;, QName, or \"LITERAL\" expected";
  834.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHRnullnull$errmsg);
  835.         }
  836.         return $statement_object;
  837.     }
  838.  
  839.     /**
  840.      * Check if the given token is a valid variable name (?var).
  841.      *
  842.      * @param string $token 
  843.      * @param string $clause 
  844.      * @return string 
  845.      * @throws PHPError
  846.      * @access private
  847.      */
  848.     function _validateVar($token$clause_error)
  849.     {
  850.         $match = array();
  851.         preg_match("/\?[a-zA-Z0-9_]+/"$token$match);
  852.         if (!isset($match[0]|| $match[0!= $token{
  853.             $errmsg htmlspecialchars($token"' - variable name contains illegal characters";
  854.             return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  855.         }
  856.         unset($this->tokens[key($this->tokens)]);
  857.         return $token;
  858.     }
  859.  
  860.     /**
  861.      * Check if $token is the first token of a valid URI (<URI>) and return the whole URI string
  862.      *
  863.      * @param string $token 
  864.      * @param string $clause_error 
  865.      * @return string 
  866.      * @throws PHPError
  867.      * @access private
  868.      */
  869.     function _validateUri($token$clause_error)
  870.     {
  871.         if ($token{0!= '<'{
  872.             if (strpos($token':'&& $this->_validateQName($token$clause_error)) {
  873.                 unset($this->tokens[key($this->tokens)]);
  874.                 return rtrim($token':');
  875.             }
  876.             if ($clause_error == RDF_RDQL_ERROR_WHERE{
  877.                 $errmsg htmlspecialchars($token)
  878.                     . "' - ?Variable or &lt;URI&gt; or QName expected";
  879.             else {
  880.                 $errmsg htmlspecialchars($token)
  881.                     . "' - &lt;URI&gt; or QName expected";
  882.             }
  883.             return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  884.         else {
  885.             $token_res $token;
  886.             while ($token{strlen($token)-1!= '>' && $token != null{
  887.                 if ($token == '(' || $token == ')' || $token == ','
  888.                     || $token == ' ' || $token == "\n" || $token == "\r"
  889.                 {
  890.                     $errmsg htmlspecialchars($token_res)
  891.                         . "' - illegal input: '$token' - '>' missing";
  892.                     return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  893.                 }
  894.                 unset($this->tokens[key($this->tokens)]);
  895.                 $token current($this->tokens);
  896.                 $token_res .= $token;
  897.             }
  898.             if ($token == null{
  899.                 $errmsg htmlspecialchars($token_res)
  900.                     . "' - '>' missing";
  901.                 return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  902.             }
  903.             unset($this->tokens[key($this->tokens)]);
  904.             return trim($token_res'<>');
  905.         }
  906.     }
  907.  
  908.     /**
  909.      * Check if $token is the first token of a valid literal ("LITERAL") and
  910.      * return an array with literal properties (value, language, datatype).
  911.      *
  912.      * @param string $token 
  913.      * @return array ['value'] = string
  914.      *                    ['is_literal'] = boolean
  915.      *                    ['l_lang'] = string
  916.      *                    ['l_dtype'] = string
  917.      *                    ['l_dtype_is_qname'] = boolean
  918.      * @throws PHPError
  919.      * @access private
  920.      */
  921.     function _validateLiteral($token)
  922.     {
  923.         $quotation_mark $token{0};
  924.         $statement_object = array (
  925.             'value' => '',
  926.             'is_literal' => true,
  927.             'l_lang' => '',
  928.             'l_dtype' => ''
  929.         );
  930.         $this->tokens[key($this->tokens)substr($token1);
  931.  
  932.         $return = false;
  933.         foreach ($this->tokens as $k => $token{
  934.             if ($token != null && $token{strlen($token)-1== $quotation_mark{
  935.                 $token rtrim($token$quotation_mark);
  936.                 $return = true;
  937.                 // parse @language (^^datatype)?
  938.             elseif (strpos($token$quotation_mark '@')
  939.                 || substr($token02== $quotation_mark '@'
  940.             {
  941.                 $lang substr($tokenstrpos($token$quotation_mark '@'+ 2);
  942.                 if (strpos($lang'^^'|| substr($lang02== '^^'{
  943.                     $dtype substr($langstrpos($lang'^^'+ 2);
  944.                     if (!$dtype{
  945.                         $errmsg $quotation_mark $statement_object['value']
  946.                             . $token " - datatype expected";
  947.                         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  948.                     }
  949.                     $statement_object['l_dtype'$this->_validateUri($dtypeRDF_RDQL_ERROR_WHERE);
  950.                     if ($dtype{0!= '<'{
  951.                         $statement_object['l_dtype_is_qname'= true;
  952.                     }
  953.                     $lang substr($lang0strpos($lang'^^'));
  954.                 }
  955.                 if (!$lang{
  956.                     $errmsg $quotation_mark $statement_object['value']
  957.                         . $token " - language expected";
  958.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  959.                 }
  960.                 $statement_object['l_lang'$lang;
  961.                 $token substr($token0strpos($token$quotation_mark '@'));
  962.                 $return = true;
  963.                 // parse ^^datatype
  964.             elseif (strpos($token$quotation_mark '^^'|| substr($token03== $quotation_mark '^^'{
  965.                 $dtype substr($tokenstrpos($token$quotation_mark '^^'+ 3);
  966.                 if (!$dtype{
  967.                     $errmsg $quotation_mark $statement_object['value']
  968.                         . $token " - datatype expected";
  969.                     return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  970.                 }
  971.                 $statement_object['l_dtype'$this->_validateUri($dtypeRDF_RDQL_ERROR_WHERE);
  972.                 if ($dtype{0!= '<'{
  973.                     $statement_object['l_dtype_is_qname'= true;
  974.                 }
  975.                 $token substr($token0strpos($token$quotation_mark '^^'));
  976.                 $return = true;
  977.             elseif (strpos($token$quotation_mark)) {
  978.                 $errmsg = "'$token' - illegal input";
  979.                 return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  980.             }
  981.             $statement_object['value'.= $token;
  982.             unset($this->tokens[$k]);
  983.             if ($return{
  984.                 return $statement_object;
  985.             }
  986.         }
  987.         $errmsg = "quotation end mark: $quotation_mark missing";
  988.         return RDF_RDQL::raiseError(RDF_RDQL_ERROR_WHEREnullnull$errmsg);
  989.     }
  990.  
  991.     /**
  992.      * Check if the given token is a valid QName.
  993.      *
  994.      * @param   string  $token 
  995.      * @param   string  $clause_error 
  996.      * @return  boolean 
  997.      * @throws  PHPError
  998.      * @access    private
  999.      */
  1000.     function _validateQName($token$clause_error)
  1001.     {
  1002.         $parts explode(':'$token);
  1003.         if (count($parts> 2{
  1004.             $errmsg = "illegal QName: '$token'";
  1005.             return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  1006.         }
  1007.         if (!$this->_validateNCName($parts[0])) {
  1008.             $errmsg = "illegal prefix in QName: '$token'";
  1009.             return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  1010.         }
  1011.         if ($parts[1&& !$this->_validateNCName($parts[1])) {
  1012.             $errmsg = "illegal local part in QName: '$token'";
  1013.             return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  1014.         }
  1015.  
  1016.         return true;
  1017.     }
  1018.  
  1019.     /**
  1020.      * Check if the given token is a valid NCName.
  1021.      *
  1022.      * @param   string  $token 
  1023.      * @return  boolean 
  1024.      * @access    private
  1025.      */ 
  1026.     function _validateNCName($token)
  1027.     {
  1028.         preg_match("/[a-zA-Z_]+[a-zA-Z_0-9.\-]*/"$token$match);
  1029.         if (isset($match[0]&& $match[0== $token{
  1030.             return true;
  1031.         }
  1032.         return false;
  1033.     }
  1034.  
  1035.     /**
  1036.      * Check if the given token is a valid namespace prefix.
  1037.      *
  1038.      * @param string $token 
  1039.      * @return string 
  1040.      * @throws PHPError
  1041.      * @access private
  1042.      */
  1043.     function _validatePrefix($token)
  1044.     {
  1045.         if (!$this->_validateNCName($token)) {
  1046.             $errmsg "'" htmlspecialchars($token)
  1047.                 . "' - illegal input, namespace prefix expected";
  1048.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_USINGnullnull$errmsg);
  1049.         }
  1050.         unset($this->tokens[key($this->tokens)]);
  1051.         return $token;
  1052.     }
  1053.  
  1054.     /**
  1055.      * Replace a prefix in a given QName and return a full URI.
  1056.      *
  1057.      * @param   string  $qName 
  1058.      * @param   string  $clasue_error 
  1059.      * @return  string 
  1060.      * @throws  PHPError
  1061.      * @access    private
  1062.      */ 
  1063.      function _replaceNamespacePrefix($qName$clause_error)
  1064.      {
  1065.         $qName_parts explode(':'$qName);
  1066.         if (!array_key_exists($qName_parts[0]$this->parsedQuery['ns'])) {
  1067.             $errmsg "undefined prefix: '" .$qName_parts[0. "' in: '$qName'";
  1068.             return RDF_RDQL::raiseError($clause_errornullnull$errmsg);
  1069.         }
  1070.         return $this->parsedQuery['ns'][$qName_parts[0]] .$qName_parts[1];
  1071.      }
  1072.  
  1073.     /**
  1074.      * Check if all variables from the SELECT clause are defined in the WHERE clause
  1075.      *
  1076.      * @access private
  1077.      */
  1078.     function _checkSelectVars()
  1079.     {
  1080.         foreach ($this->parsedQuery['selectVars'as $var{
  1081.             $this->_isDefined($var);
  1082.         }
  1083.     }
  1084.  
  1085.     /**
  1086.      * Check if the given variable is defined in the WHERE clause.
  1087.      *
  1088.      * @param  $var string
  1089.      * @return string 
  1090.      * @throws PHPError
  1091.      * @access private
  1092.      */
  1093.     function _isDefined($var)
  1094.     {
  1095.         $allQueryVars $this->findAllQueryVariables();
  1096.  
  1097.         if (!in_array($var$allQueryVars)) {
  1098.             $errmsg = "'$var' - variable must be defined in the WHERE clause";
  1099.             return RDF_RDQL::raiseError(RDF_RDQL_ERRORnullnull$errmsg);
  1100.         }
  1101.         return $var;
  1102.     }
  1103.  
  1104.     /**
  1105.      * Throw an error if the regular expression from the AND clause is not quoted.
  1106.      *
  1107.      * @param string $filterString 
  1108.      * @param string $lQuotMark 
  1109.      * @param string $rQuotMark 
  1110.      * @throws PHPError
  1111.      * @access private
  1112.      */
  1113.     function _checkRegExQuotation($filterString$lQuotMark$rQuotMark)
  1114.     {
  1115.         if (!$lQuotMark{
  1116.             $errmsg = "'$filterString' - regular expressions must be quoted";
  1117.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_ANDnullnull$errmsg);
  1118.         }
  1119.  
  1120.         if ($lQuotMark != $rQuotMark{
  1121.             $errmsg = "'$filterString' - quotation end mark in the regular expression missing";
  1122.             return RDF_RDQL::raiseError(RDF_RDQL_ERROR_ANDnullnull$errmsg);
  1123.         }
  1124.     }
  1125. // end: Class RDQLParser
  1126.  
  1127. ?>

Documentation generated on Mon, 11 Mar 2019 13:55:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.