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

Source for file Parser.php

Documentation is available at Parser.php

  1. <?php
  2. // ----------------------------------------------------------------------------------
  3. // Class: RDF_N3_Parser
  4. // ----------------------------------------------------------------------------------
  5. /**
  6.  * PHP Notation3 Parser
  7.  *
  8.  * This parser can parse a subset of n3, reporting triples to a callback function
  9.  * or constructing a RAP Model ( http://www.wiwiss.fu-berlin.de/suhl/bizer/rdfapi )
  10.  *
  11.  * Supported N3 features:
  12.  * <ul>
  13.  *    <li>Standard things, repeated triples ( ; and , ), blank nodes using [ ], self-reference ('<>')</li>
  14.  *    <li>@prefix mappings</li>
  15.  *    <li>= maps to owl#sameAs</li>
  16.  *    <li>a maps to rdf-syntax-ns#type</li>
  17.  *    <li>Literal datytype- and xmlLanguageTag support
  18.  * </ul>
  19.  * Un-supported N3 Features include:
  20.  * <ul>
  21.  *    <li>Reification using { }</li>
  22.  *    <li>. and ^ operators for tree traversal</li>
  23.  *    <li>Any log operators, like log:forAll etc.</li>
  24.  * </ul>
  25.  *
  26.  * This parser is based on n3.py from Epp released 2nd March, 2002.
  27.  * by Sean B. Palmer
  28.  * ( http://infomesh.net/2002/eep/20020302-013802/n3.py )
  29.  *
  30.  * This parser is released under the GNU GPL license.
  31.  * ( http://www.gnu.org/licenses/gpl.txt )
  32.  *
  33.  * @author Sean B. Palmer <sean@mysterylights.com>, Gunnar AA. Grimnes <ggrimnes@csd.abdn.ac.uk>, Daniel Westphal <mail@d-westphal.de>
  34.  * @version V0.7
  35.  * @package syntax
  36.  * @access public
  37.  */
  38.  
  39. class RDF_N3_Parser extends RDF_Object
  40. {
  41.     /* ==================== Variables ==================== */
  42.  
  43.     var $Tokens;
  44.     var $bNode;
  45.     var $RDF_NS$DAML_NS$OWL_NS;
  46.     var $debug;
  47.  
  48.     /* ==================== Public Methods ==================== */
  49.  
  50.     /**
  51.      *
  52.      * @access public
  53.      */
  54.     function RDF_N3_Parser()
  55.     {
  56.         // Regular expressions:
  57.         $Name '[A-Za-z0-9_@\.]+[^\.,;\[\] ]';
  58.         $URI '<[^> ]*>';
  59.         $bNode '_:' $Name;
  60.         $Univar '\?' $Name;
  61.         $QName '(?:[A-Za-z][A-Za-z0-9_@\.]*)?:' $Name;
  62.         $Literal '"(\\\"|[^"])*"'# '"(?:\\"|[^"])*"'
  63.         // $Literal = '"[^"\\\\]*(?:\\.\\[^"\\]*)*"'; # '"(?:\\"|[^"])*"'
  64.         $LangTag '@[A-Za-z\-]*[^ \^\.\;\,]';
  65.         $Datatype '(\^\^)[^ ,\.;)]+';
  66.         $Datatype_URI '(\^\^)' $URI;
  67.         // $LLiteral = '"""[^"\\\\]*(?:(?:.|"(?!""))[^"\\\\]*)*"""';
  68.         $LLiteral '"""[^"\\\\]*(?:(?:\\\\.|"(?!""))[^"\\\\]*)*"""';
  69.         // '"""[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
  70.         $Comment '# .*$';
  71.         $Prefix '(?:[A-Za-z][A-Za-z0-9_]*)?:';
  72.         $PrefixDecl '@prefix';
  73.         $WS '[ \t]';
  74.         $this->RDF_NS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'# for 'a' keyword
  75.         $this->DAML_NS = 'http://www.daml.org/2001/03/daml+oil#'# for '=' keyword
  76.         $this->OWL_NS = 'http://www.w3.org/2002/07/owl#';
  77.         // $t = array( $LLiteral, $URI); //, $Literal, $PrefixDecl, $QName, $bNode, $Prefix,
  78.         // $Univar, 'a', '{', '}', '\(', '\)', '\[', '\]', ',', ';', '\.', $WS, $Comment);
  79.         $t = array(
  80.             $Datatype_URI$Datatype$LLiteral$URI$Literal,
  81.             $PrefixDecl$QName$bNode$Prefix$Univar,
  82.             'a''=''{''}''\(''\)''\[''\]'','';''\.',
  83.             $WS$Comment$LangTag
  84.         );
  85.         $this->Tokens = '/(' join($t'|'')/m';
  86.  
  87.         $this->bNode = 0;
  88.         $this->debug = 0;
  89.         $this->bNodeMap = array();
  90.         $this->FixBnodes = RDF_FIX_BLANKNODES;
  91.     }
  92.  
  93.     /**
  94.      * Sets, if BlankNode labels should be replaced by the generic label from the constants.php file
  95.      * default is "false" -> the used label in n3 is parsed to the model
  96.      *
  97.      * @param boolean 
  98.      * @access public
  99.      */
  100.     function setFixBnodes($set)
  101.     {
  102.         if (($set = trueOR ($set = false)) {
  103.             $this->FixBnodes $set;
  104.         }
  105.     }
  106.  
  107.     /**
  108.      * This parses a N3 string and prints out the triples
  109.      *
  110.      * @param string $s 
  111.      * @access public
  112.      */
  113.     function parse($s)
  114.     {
  115.         // """Get a string, tokenize, create list, convert to Eep store."""
  116.         $stat $this->n3tolist($s);
  117.         foreach ($stat as $t{
  118.             if (count($t> 3{
  119.                 $object $t[2];
  120.  
  121.                 for ($i = 3; $i < 5; $i++{
  122.                     if ($t[$i][0== '@'{
  123.                         $object .= $t[$i];
  124.                     }
  125.                     if (substr($t[$i]02== '^^'{
  126.                         $object .= $t[$i];
  127.                     }
  128.                 }
  129.             else {
  130.                 $object $t[2];
  131.             ;
  132.  
  133.             print '('.$t[0].', '.$t[1].', '.$object.")\n";
  134.         }
  135.         // return [[eep.Article(t[0]), eep.Article(t[1]), eep.Article(t[2])]
  136.         // for t in n3tolist(s)]
  137.     }
  138.  
  139.     /**
  140.      * This parses a N3 string and calls func($subject, $predicate, $object) with each trioke
  141.      *
  142.      * @param string $s 
  143.      * @param string $func 
  144.      * @access public
  145.      */
  146.     function uparse($s$func)
  147.     {
  148.         // """Get a string, tokenize, create list, convert to Eep store."""
  149.         $stat $this->n3tolist($s);
  150.         foreach ($stat as $t{
  151.             if (count($t> 3{
  152.                 $object $t[2];
  153.  
  154.                 for ($i = 3; $i < 5; $i++{
  155.                     if ($t[$i][0== '@'{
  156.                         $object .= $t[$i];
  157.                     }
  158.                     if (substr($t[$i]02== '^^'{
  159.                         $object .= $t[$i];
  160.                     }
  161.                 }
  162.             else {
  163.                 $object $t[2];
  164.             ;
  165.             // print "(".$t[0].", ".$t[1].", ".$t[2].")";
  166.             $func($t[0]$t[1]$object);
  167.         }
  168.         // return [[eep.Article(t[0]), eep.Article(t[1]), eep.Article(t[2])]
  169.         // for t in n3tolist(s)]
  170.     }
  171.  
  172.     /**
  173.      * This parses a N3 string and prints out the triples
  174.      *
  175.      * @param string $s 
  176.      * @access public
  177.      * @return object Model 
  178.      */
  179.  
  180.     function parse2model($s)
  181.     {
  182.         $m =new RDF_Model_Memory();
  183.         // """Get a string, tokenize, create list, convert to Eep store."""
  184.         $stat $this->n3tolist($s);
  185.  
  186.         foreach ($stat as $t{
  187.             $s $this->toRDFNode($t[0]$t);
  188.             $p $this->toRDFNode($t[1]$t);
  189.             $o $this->toRDFNode($t[2]$t);
  190.  
  191.             $new_statement =RDF_Statement::factory($s$p$o);
  192.             if (PEAR::isError($new_statement)) {
  193.                 return $new_statement;
  194.             }
  195.  
  196.             $result $m->add($new_statement);
  197.             if (PEAR::isError($result)) {
  198.                 return $result;
  199.             }
  200.         }
  201.         return $m;
  202.     }
  203.  
  204.     /**
  205.      * Generate a new Model_Memory from an URI or file.
  206.      *
  207.      * @access public
  208.      * @param  $path 
  209.      * @throws PhpError
  210.      * @return object Model_Memory 
  211.      */
  212.     function &generateModel($path)
  213.     {
  214.         $handle fopen($path'r'or die("N3 Parser: Could not open File: '$path' - Stopped parsing.");
  215.         $done = false;
  216.         $input "";
  217.         while (!$done{
  218.             $input .= fread($handle512);
  219.             $done feof($handle);
  220.         ;
  221.  
  222.         fclose($handle);
  223.  
  224.         return $this->parse2model($input);
  225.     }
  226.  
  227.     /* ==================== protected Methods from here ==================== */
  228.     // General list processing functions
  229.     /**
  230.      * Returns FALSE if argument is a whitespace character
  231.      *
  232.      * @access protected
  233.      * @param string $s 
  234.      */
  235.     function isWS($s)
  236.     {
  237.         if ($s{0== '#'{
  238.             return false;
  239.         }
  240.         $ws = array(""" ""\t""\n""\r");
  241.         return !in_array($s$ws);
  242.     }
  243.  
  244.     /**
  245.      * Callback function for trimming whitespace from lines
  246.      *
  247.      * @access protected
  248.      * @param string 
  249.      */
  250.     function trimLine(&$l$i)
  251.     {
  252.         $l trim($l);
  253.     }
  254.  
  255.     /**
  256.      * Returns true if the string is not a comment
  257.      *
  258.      * @access protected
  259.      * @param string $s 
  260.      * @returns boolean
  261.      */
  262.     function notComment($s)
  263.     {
  264.         if ($s == ""{
  265.             return false;
  266.         }
  267.         $N3Comment '/^[ \t]*\#/';
  268.  
  269.         return !preg_match($N3Comment$s);
  270.     }
  271.  
  272.     /**
  273.      * Removes all whitespace tokens from list
  274.      *
  275.      * @access protected
  276.      * @param array $list 
  277.      */
  278.     function filterWs($list)
  279.     {
  280.         // """Filter whitespace from a list."""
  281.         return array_filter($listarray($this'isWS'));
  282.     }
  283.  
  284.     /**
  285.      * Gets a slice of an array.
  286.      * Returns the wanted slice, as well as the remainder of the array.
  287.      * e.g. getSpan(['p', 'q', 'r'], 1, 2) gives (['q'], ['p', 'r'])
  288.      *
  289.      * @return array 
  290.      * @access protected
  291.      * @param array $list 
  292.      * @param integer $start 
  293.      * @param integer $end 
  294.      */
  295.     function getSpan($list$start$end)
  296.     {
  297.         $pre array_slice($list0$start);
  298.         $post array_slice($list$end);
  299.  
  300.         return array(
  301.             array_slice($list$start$end $start),
  302.             $this->array_concat($pre$post)
  303.         );
  304.     }
  305.  
  306.     /**
  307.      * Concatenates two arrays
  308.      *
  309.      * @param array $a 
  310.      * @param array $b 
  311.      * @returns array
  312.      * @access protected
  313.      */
  314.     function array_concat($a$b)
  315.     {
  316.         array_splice($acount($a)0$b);
  317.         return $a;
  318.     }
  319.  
  320.     /**
  321.      * Returns an array with all indexes where item appears in list
  322.      *
  323.      * @param array $list 
  324.      * @param string $item 
  325.      * @returns array
  326.      * @access protected
  327.      */
  328.     function posns($list$item)
  329.     {
  330.         $res = array();
  331.         $i = 0;
  332.         foreach ($list as $v{
  333.             if ($v === $item{
  334.                 $res[$i;
  335.             }
  336.             $i++;
  337.         }
  338.         $res[$i;
  339.         return $res;
  340.     }
  341.  
  342.     /* More N3 specific functions */
  343.  
  344.     /**
  345.      * Returns a list of tokens
  346.      *
  347.      * @param string $s 
  348.      * @returns array
  349.      * @access protected
  350.      */
  351.     function toke($s)
  352.     {
  353.         // print "$s\n";
  354.         // """Notation3 tokenizer. Takes in a string, returns a raw token list."""
  355.         if (strlen($s== 0die('Document has no content!');
  356.         $s str_replace("\r\n""\n"$s);
  357.         $s str_replace("\r""\n"$s);
  358.  
  359.         $res = array();
  360.         $newres = array();
  361.  
  362.         preg_match_all($this->Tokens$s$newres);
  363.  
  364.         $res $this->array_concat($res$newres[0]);
  365.  
  366.         return $res;
  367.     }
  368.  
  369.     /**
  370.      * Returns a list with the elements between start and end as one quoted string
  371.      * e.g. listify(["a","b","c","d"],1,2) => ["a","b c", "d"]
  372.      *
  373.      * @param array $list 
  374.      * @param integer $start 
  375.      * @param integer $end 
  376.      * @returns array
  377.      * @access protected
  378.      */
  379.     function listify($list$start$end)
  380.     {
  381.         // Re-form a list, merge elements start->end into one quoted element
  382.         // Start and end are offsets...
  383.         $l $end $start;
  384.  
  385.         $s array_slice($list0$start);
  386.         $m array_slice($list$start$l);
  387.         $e array_slice($list$end);
  388.         // array_push($s,"\"".join($m," ")."\"");
  389.         array_push($s$m);
  390.  
  391.         return $this->array_concat($s$e);
  392.     }
  393.  
  394.     /**
  395.      * Returns an array with prefixes=>namespace mappings
  396.      *
  397.      * @param array $list 
  398.      * @access protected
  399.      * @returns array
  400.      */
  401.     function getPrefixes($list)
  402.     {
  403.         $prefixes = array();
  404.         $ns = 1;
  405.         $name = 2;
  406.         foreach ($list as $l{
  407.             if ($l == '@prefix'{
  408.                 // while '@prefix' in list {
  409.                 $pos current($list);
  410.                 // pos = list.index('@prefix')
  411.                 $r $this->getSpan($list$pos($pos + 4))# processes the prefix tokens
  412.                 $binding $r[0];
  413.                 $list $r[1];
  414.                 $prefixes[$binding[$ns]] substr($binding[$name]1-1);
  415.             }
  416.         }
  417.  
  418.         if (count($prefixes< 1$list array_slice($list0);
  419.  
  420.         return array($prefixes$list);
  421.     }
  422.  
  423.     /**
  424.      * Callback function for replacing "a" elements with the right RDF uri.
  425.      *
  426.      * @param string $l 
  427.      * @access protected
  428.      */
  429.     function replace_a_type(&$l$p)
  430.     {
  431.         if ($l == 'a'{
  432.             $l '<' $this->RDF_NS . 'type>';
  433.         }
  434.     }
  435.  
  436.     /**
  437.      * Callback function for replacing "=" elements with the right DAML+OIL uri.
  438.      *
  439.      * @param string $l 
  440.      * @access protected
  441.      */
  442.     function replace_equal(&$l$p)
  443.     {
  444.         if ($l == '='{
  445.             $l '<' $this->OWL_NS . 'sameAs>';
  446.         }
  447.     }
  448.  
  449.     /**
  450.      * Callback function for replacing "this" elements with the right RDF uri.
  451.      *
  452.      * @param string $l 
  453.      * @access protected
  454.      */
  455.     function replace_this($l$p)
  456.     {
  457.         if ($l == 'this'{
  458.             $l '<urn:urn-n:this>';
  459.         }
  460.     }
  461.  
  462.     /**
  463.      * Applies stuff :)
  464.      * Expands namespace prefixes etc.
  465.      *
  466.      * @param array $prefixes 
  467.      * @param array $list 
  468.      * @returns $list
  469.      * @access protected
  470.      */
  471.     function applyStuff($prefixes$list)
  472.     {
  473.         array_walk($listarray($this'replace_a_type'));
  474.         array_walk($listarray($this'replace_equal'));
  475.         array_walk($listarray($this'replace_this'));
  476.  
  477.         for ($i = 0;$i count($list);$i++{
  478.             // for i in range(len(list)) {
  479.             // if (!strstr('<_"?.;,{}[]()',$list[$i]{0})) {
  480.             // if a <> resource occours, change it to the parsed filename or local URI + timestamp
  481.             if ($list[$i== '<>'{
  482.                 if (!isset($path)) {
  483.                     if (!isset($_SERVER['SERVER_ADDR'])) {
  484.                         $_SERVER['SERVER_ADDR''localhost';
  485.                     }
  486.                     if (!isset($_SERVER['REQUEST_URI'])) {
  487.                         $_SERVER['REQUEST_URI''/rdfapi-php';
  488.                     }
  489.                     $list[$i'<http://' $_SERVER['SERVER_ADDR'.
  490.                         $_SERVER['REQUEST_URI''#generate_timestamp_' time('>';
  491.                 else {
  492.                     $list[$i'<' $path '>';
  493.                 }
  494.             }
  495.  
  496.             if ((!strstr('<_"?.;,{}[]()@'$list[$i{
  497.                             0}
  498.                         ))AND (substr($list[$i]03!= '^^<')) {
  499.                 $_r explode(':'$list[$i]);
  500.  
  501.                 $ns $_r[0':';
  502.                 $name $_r[1];
  503.  
  504.                 if (isset($prefixes[$ns])) {
  505.                     $list[$i'<' $prefixes[$ns$name '>';
  506.                 else if (isset($prefixes[substr($ns2)])) {
  507.                     $list[$i'^^' $prefixes[substr($ns2)$name '';
  508.                 else {
  509.                     die('Prefix not declared:' $ns);
  510.                 }
  511.             else {
  512.                 if ($list[$i{
  513.                         0== '"'// Congratulations - it's a literal!
  514.                     if (substr($list[$i]03== '"""'{
  515.                         if (substr($list[$i]-33== '"""'// A big literal...
  516.                             $lit substr($list[$i]3-3);
  517.                             // print "++$lit++";
  518.                             $lit str_replace('\n''\\n'$lit);
  519.  
  520.                             $lit preg_replace('/[^\\]"/''\\"'$lit);
  521.  
  522.                             $list[$i'"' $lit '"';
  523.                         else {
  524.                             die ("Incorrect string formatting: " substr($list[$i]-33));
  525.                         }
  526.                     else {
  527.                         if (strstr($list[$i]"\n")) die('Newline in literal: ' $list[$i]);
  528.                     }
  529.                 }
  530.             }
  531.  
  532.             if (substr($list[$i]02== '^^'{
  533.                 if ($list[$i][2!= '<'{
  534.                     $list[$i'^^<' substr($list[$i]2'>';
  535.                 ;
  536.             ;
  537.         }
  538.  
  539.         return $list;
  540.     }
  541.  
  542.     /**
  543.      * Returns an array of triples extracted from the list of n3 tokens
  544.      *
  545.      * @param array $list 
  546.      * @returns array
  547.      * @access protected
  548.      */
  549.     function getStatements($list)
  550.     {
  551.         $statements = array();
  552.  
  553.         while (in_array('.'$list)) {
  554.             // for ($i=0;$i<count($list); $i++) {
  555.             // if ($list[$i]==".") {
  556.             // while '.' in list {
  557.             $pos array_search('.'$list);
  558.  
  559.             $r $this->getSpan($list0$pos + 1);
  560.  
  561.             $statement $r[0];
  562.             $list $r[1];
  563.  
  564.             array_pop($statement);
  565.             $statements[$statement;
  566.         }
  567.  
  568.         return $statements;
  569.     }
  570.  
  571.     /**
  572.      * Gets a list of triples with same subject
  573.      * e.g. :Gunnar :firstname "Gunnar" ; :lastname "Grimnes.
  574.      *
  575.      * @param array $list 
  576.      * @returns array
  577.      * @acces protected
  578.      */
  579.     function getPovs($list)
  580.     {
  581.         $povs = array();
  582.         while (in_array(';'$list)) {
  583.             $r $this->posns($list';');
  584.             $pos array_slice($r02);
  585.             $r $this->getSpan($list$pos[0]$pos[1]);
  586.             $pov $r[0];
  587.             $list $r[1];
  588.  
  589.             $povs[array_slice($pov1);
  590.         }
  591.  
  592.         return array($list$povs);
  593.     }
  594.  
  595.     /**
  596.      * * Gets a list of triples with same predicate
  597.      * e.g. :Gunnar :likes "Cheese", "Wine".
  598.      *
  599.      * @access protected
  600.      * @param array $list 
  601.      * @returns array
  602.      */
  603.     function getObjs($list)
  604.     {
  605.         $objs = array();
  606.         while (in_array(','$list)) {
  607.             $pos array_search(','$list);
  608.             // for ($i=0;$i<count($list); $i++) {
  609.             // if ($list[$i]==",") {
  610.             // while ',' in list {
  611.             $get_array_fields = 2;
  612.             if (isset ($list[$pos + 2])) {
  613.                 if (@$list[$pos + 2][0== '@'{
  614.                     $get_array_fields++;
  615.                 }
  616.                 if (@$list[$pos + 2][0== '^'{
  617.                     $get_array_fields++;
  618.                 }
  619.             ;
  620.             if (isset ($list[$pos + 3])) {
  621.                 if (@$list[$pos + 3][0== '^'{
  622.                     $get_array_fields++;
  623.                 }
  624.             }
  625.  
  626.             $r $this->getSpan($list$pos($pos $get_array_fields));
  627.  
  628.             $obj $r[0];
  629.             if (!isset($obj[2])) {
  630.                 $obj[2' ';
  631.             }
  632.             if (!isset($obj[3])) {
  633.                 $obj[3' ';
  634.             }
  635.  
  636.             $list $r[1];
  637.  
  638.             $objs[$obj;
  639.         }
  640.  
  641.         return array($list$objs);
  642.     }
  643.  
  644.     /**
  645.      * Does the real work, returns a list of subject, predicate, object triples.
  646.      *
  647.      * @param array $list 
  648.      * @returns array
  649.      * @access protected
  650.      */
  651.     function statementize($list)
  652.     {
  653.         if (count($list== 1 && preg_match('/_' . RDF_BNODE_PREFIX . '[0-9]+_/'$list[0])) {
  654.             if ($this->debug{
  655.                 print "Ignored bNode exists statement. $list\n";
  656.             }
  657.             return array();
  658.         }
  659.  
  660.         if (count($list== 3{
  661.             return array($list);
  662.         }
  663.         if (count($list< 3{
  664.             die('Error: statement too short!');
  665.         }
  666.         // Get all ;
  667.         $r $this->getPovs($list);
  668.         $spo $r[0];
  669.         $po $r[1];
  670.         $all = array();
  671.         // (spo, po), all = getPovs(list), []
  672.         $subject $spo[0];
  673.         foreach ($po as $pop{
  674.             // for pop in po {
  675.             $r $this->getObjs($pop);
  676.  
  677.             $myPo $r[0];
  678.             $obj $r[1];
  679.             // myPo, obj = getObjs(pop)
  680.             if (!isset($myPo[2])) {
  681.                 $myPo[2' ';
  682.             }
  683.             if (!isset($myPo[3])) {
  684.                 $myPo[3' ';
  685.             }
  686.  
  687.             $predicate $myPo[0];
  688.             $all[= array($subject$predicate$myPo[1]$myPo[2]$myPo[3]);
  689.             // all.append([subject, predicate, myPo[1]])
  690.             foreach ($obj as $o$all[= array($subject$predicate$o[1]$o[2]$o[3]);
  691.             // for x in obj: all.append([subject, predicate, x])
  692.         }
  693.  
  694.         $r $this->getObjs($spo);
  695.         $spo $r[0];
  696.  
  697.         $objs $r[1];
  698.         // spo, objs = getObjs(spo)
  699.         $subject $spo[0];
  700.         $predicate $spo[1];
  701.  
  702.         if (!isset($spo[3])) {
  703.             $spo[3' ';
  704.         }
  705.         if (!isset($spo[4])) {
  706.             $spo[4' ';
  707.         }
  708.  
  709.         $all[= array($subject$predicate$spo[2]$spo[3]$spo[4]);
  710.  
  711.         foreach ($objs as $obj$all[= array($subject$predicate$obj[1]$obj[2]$obj[3]);
  712.  
  713.         return $all;
  714.     }
  715.  
  716.     /**
  717.      * Makes lists of elements in list into a seperate array element.
  718.      * e.g. doLists(["a","b","[","c","]","d"], "[","]")=> ["a","b", ["c"], "d"]
  719.      *
  720.      * @param array $list 
  721.      * @param string $schar 
  722.      * @param string $echar 
  723.      * @returns array
  724.      * @access protected
  725.      */
  726.     function doLists($list$schar$echar)
  727.     {
  728.         while (in_array($schar$list)) {
  729.             // while schar in list {
  730.             $ndict = array();
  731.             $nestingLevel = 0;
  732.             $biggest = 0;
  733.             for ($i = 0;$i count($list);$i++{
  734.                 if ($list[$i== $schar{
  735.                     $nestingLevel += 1;
  736.                     if (!in_array($nestingLevelarray_keys($ndict))) {
  737.                         $ndict[$nestingLevel= array(array($i));
  738.                     else {
  739.                         $ndict[$nestingLevel][= array($i);
  740.                     }
  741.                 }
  742.                 if ($list[$i== $echar{
  743.                     if (!in_array($nestingLevelarray_keys($ndict))) {
  744.                         $ndict[$nestingLevel= array(array($i));
  745.                     else {
  746.                         $ndict[$nestingLevel][count($ndict[$nestingLevel])-1][$i;
  747.                         $nestingLevel -= 1;
  748.                         // elif type(list[i]) == type([]) {
  749.                         // list[i] = doLists(list[i], schar, echar)
  750.                     }
  751.                 }
  752.             }
  753.             foreach (array_keys($ndictas $key{
  754.                 if ($key $biggest{
  755.                     $biggest $key;
  756.                 }
  757.             }
  758.  
  759.             $tol $ndict[$biggest][0];
  760.             $list $this->listify($list$tol[0]($tol[1+ 1));
  761.         }
  762.         return $list;
  763.     }
  764.  
  765.     /**
  766.      * Apply doLists for all different types of list.
  767.      *
  768.      * @param array 
  769.      * @returns array
  770.      * @access protected
  771.      */
  772.     function listStuff($list)
  773.     {
  774.         // y, z = zip(['[', ']'], ['{', '}'], ['(', ')'])
  775.         // return map(doLists, [list, list, list], y, z).pop()
  776.         $list $this->doLists($list'['']');
  777.         $list $this->doLists($list'{''}');
  778.         return $this->doLists($list'('')');
  779.     }
  780.  
  781.     /**
  782.      * Generates a new node id.
  783.      *
  784.      * @access protected
  785.      * @returns string
  786.      */
  787.     function bnodeID()
  788.     {
  789.         $this->bNode++;
  790.         return '_' . RDF_BNODE_PREFIX . $this->bNode . '_';
  791.     }
  792.  
  793.     /**
  794.      * This makes bNodes out of variables like _:a etc.
  795.      *
  796.      * @access protected
  797.      * @param array $list 
  798.      * @returns array
  799.      */
  800.     function fixAnon($list)
  801.     {
  802.         // $map=array();
  803.         for ($i = 0;$i count($list);$i++{
  804.             $l $list[$i];
  805.             if (substr($l02== '_:'{
  806.                 if (!isset($this->bNodeMap[$l])) {
  807.                     $a $this->bnodeID();
  808.                     $this->bNodeMap[$l$a;
  809.                 else $a $this->bNodeMap[$l];
  810.                 $list[$i$a;
  811.             }
  812.         }
  813.         return $list;
  814.     }
  815.  
  816.     /**
  817.      * This makes [ ] lists into bnodes.
  818.      *
  819.      * @access protected
  820.      * @param array $list 
  821.      * @return array 
  822.      */
  823.     function expandLists($list)
  824.     {
  825.         for ($i = 0;$i count($list);$i++{
  826.             if (is_array($list[$i])) {
  827.                 if ($list[$i][0== '['{
  828.                     $bnode $this->bnodeID();
  829.                     $prop $list[$i];
  830.                     $list[$i$bnode;
  831.                     $list[$bnode;
  832.                     $list $this->array_concat($listarray_slice($prop1-1));
  833.                     $list['.';
  834.                 else {
  835.                     die('Only [ ] lists are supported!');
  836.                 }
  837.             }
  838.         }
  839.         return $list;
  840.     }
  841.  
  842.     /**
  843.      * Main work-horse function. This converts a N3 string to a list of statements
  844.      *
  845.      * @param string $s 
  846.      * @returns array
  847.      * @access protected
  848.      */
  849.     function n3tolist($s)
  850.     {
  851.         // """Convert an N3 string into a list of triples as strings."""
  852.         $result = array();
  853.  
  854.         $t $this->filterWs($this->toke($s))# tokenize the stream, and filter whitespace tokens
  855.  
  856.         if ($this->debug{
  857.             print "Filter WS:\n";
  858.             var_dump($t);
  859.         }
  860.         $r $this->getPrefixes($t)# get the prefix directives, and add to a dict
  861.         $prefixes $r[0];
  862.         $t $r[1];
  863.         if ($this->debug{
  864.             print "Prefixes:\n";
  865.             var_dump($prefixes);
  866.             print "***\n";
  867.             var_dump($t);
  868.         }
  869.         $t $this->applyStuff($prefixes$t)#apply prefixes, keywords, and string formatting
  870.         if ($this->debug{
  871.             print "Stuff applied:\n";
  872.             var_dump($t);
  873.         }
  874.  
  875.         $t $this->fixAnon($t)# fix _:a anons
  876.         if ($this->debug{
  877.             print "Fix anon:\n";
  878.             var_dump($t);
  879.         }
  880.  
  881.         $t $this->listStuff($t)# apply list stuff: todo
  882.         if ($this->debug{
  883.             print "Lists done:\n";
  884.             var_dump($t);
  885.         }
  886.         $t $this->expandLists($t);
  887.         if ($this->debug{
  888.             print "Lists applied:\n";
  889.             var_dump($t);
  890.         }
  891.         $t $this->getStatements($t)# get all of the "statements" from the stream
  892.  
  893.         foreach ($t as $stat{
  894.             $stats $this->statementize($stat);
  895.  
  896.             foreach ($stats as $y{
  897.                 $result[$y;
  898.             }
  899.         }
  900.         // for x in [statementize(stat) for stat in t] {
  901.         // for y in x: result.append(y)
  902.         return $result;
  903.     }
  904.  
  905.     /**
  906.      * Constructs a RAP RDFNode from URI/Literal/Bnode
  907.      *
  908.      * @access protected
  909.      * @param string $s 
  910.      * @returns object RDFNode
  911.      */
  912.     function toRDFNode($s$state)
  913.     {
  914.         if ($s{0== '"'{
  915.             $lang = null;
  916.  
  917.             if (count($state> 3{
  918.                 for ($i = 3; $i count($state)$i++{
  919.                     if ($state[$i][0== '@'{
  920.                         $lang substr($state[3]1);
  921.                     }
  922.                     if (substr($state[$i]02== '^^'{
  923.                         $dtype substr($state[$i]2);
  924.                         if ($dtype[0== '<'{
  925.                             $dtype substr($dtype1-1);
  926.                         }
  927.                     }
  928.                 }
  929.             }
  930.  
  931.             $new_literal =RDF_Literal::factory(substr($s1-1)$lang);
  932.             if (PEAR::isError($new_literal)) {
  933.                 return $new_literal;
  934.             }
  935.             if (isset($dtype)) {
  936.                 $new_literal->setDatatype($dtype);
  937.             }
  938.             return $new_literal;
  939.         }
  940.  
  941.         if (strstr($s'_' . RDF_BNODE_PREFIX)) {
  942.             if (($this->FixBnodes|| (!array_search($s$this->bNodeMap))) {
  943.                 return RDF_BlankNode::factory(substr($s1-1));
  944.             else {
  945.                 return RDF_BlankNode::factory(substr(array_search($s$this->bNodeMap)2));
  946.             }
  947.         }
  948.  
  949.         return RDF_Resource::factory(substr($s1-1));
  950.     }
  951. //end: N3Parser
  952.  
  953. ?>

Documentation generated on Mon, 11 Mar 2019 15:39:51 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.