|
From: <cw...@us...> - 2007-08-13 04:59:47
|
Revision: 495
http://rdfapi-php.svn.sourceforge.net/rdfapi-php/?rev=495&view=rev
Author: cweiske
Date: 2007-08-12 21:59:45 -0700 (Sun, 12 Aug 2007)
Log Message:
-----------
Add support for plain numbers and booleans in N3 files.
This fixes bug #1545380: N3 parser doesn't understand numeric literals
and allows me to go on integrating the new DAWG tests
Modified Paths:
--------------
trunk/rdfapi-php/api/syntax/N3Parser.php
trunk/rdfapi-php/test/unit/Syntax/n3Parser_test.php
Modified: trunk/rdfapi-php/api/syntax/N3Parser.php
===================================================================
--- trunk/rdfapi-php/api/syntax/N3Parser.php 2007-08-12 18:10:08 UTC (rev 494)
+++ trunk/rdfapi-php/api/syntax/N3Parser.php 2007-08-13 04:59:45 UTC (rev 495)
@@ -77,7 +77,8 @@
$Univar = '\?'.$Name;
$QName = '(?:[A-Za-z][A-Za-z0-9_@\.]*)?:'.$Name;
$Literal = '"(\\\"|[^"])*"'; # '"(?:\\"|[^"])*"'
- $Number = '[0-9]+(:?[\\.e][0-9]+)?';
+ $Number = '[-+]?[0-9]+(\\.[0-9]+)?([eE][-+]?[0-9]+)?';
+ $Boolean = '@(?:true|false)';
// $Literal = '"[^"\\\\]*(?:\\.\\[^"\\]*)*"'; # '"(?:\\"|[^"])*"'
$LangTag = '@[A-Za-z\-]*[^ \^\.\;\,]';
$Datatype = '(\^\^)[^ ,\.;)]+';
@@ -85,17 +86,23 @@
// $LLiteral = '"""[^"\\\\]*(?:(?:.|"(?!""))[^"\\\\]*)*"""';
$LLiteral = '"""[^"\\\\]*(?:(?:\\\\.|"(?!""))[^"\\\\]*)*"""';
// '"""[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
- $Comment = '#.*$';
- $Prefix = '(?:[A-Za-z][A-Za-z0-9_]*)?:';
+ $Comment = '#.*$';
+ $Prefix = '(?:[A-Za-z][A-Za-z0-9_]*)?:';
$PrefixDecl = '@prefix';
- $WS = '[ \t]';
+ $WS = '[ \t]';
$this->RDF_NS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; # for 'a' keyword
$this->DAML_NS = 'http://www.daml.org/2001/03/daml+oil#'; # for '=' keyword
$this->OWL_NS = 'http://www.w3.org/2002/07/owl#';
// $t = array( $LLiteral, $URI); //, $Literal, $PrefixDecl, $QName, $bNode, $Prefix,
// $Univar, 'a', '{', '}', '\(', '\)', '\[', '\]', ',', ';', '\.', $WS, $Comment);
- $t = array( $Datatype_URI,$Datatype,$LLiteral, $URI, $Literal, $PrefixDecl, $QName, $Number, $bNode, $Prefix, $Univar, 'a','=', '{', '}', '\(', '\)', '\[', '\]', ',', ';', '\.', $WS, $Comment,$LangTag);
+ $t = array(
+ $Datatype_URI, $Datatype, $LLiteral, $URI, $Literal,
+ $PrefixDecl, $QName, $Number, $Boolean, $bNode,
+ $Prefix, $Univar, 'a','=',
+ '{', '}', '\(', '\)', '\[', '\]', ',', ';', '\.',
+ $WS, $Comment,$LangTag
+ );
$this->Tokens = "/(".join($t,"|").")/m";
$this->bNode = 0;
@@ -545,7 +552,8 @@
array_walk($list, array($this, 'replace_equal'));
array_walk($list, array($this, 'replace_this'));
- for ($i=0; $i<count($list); $i++) {
+ for ($i = 0; $i < count($list); $i++) {
+
if ($list[$i]=='<>') {
if (!isset($path)) {
if (!isset($_SERVER['SERVER_ADDR'])) {
@@ -561,20 +569,28 @@
};
- if ((!strstr('<_"?.;,{}[]()@',$list[$i]{0}))
- && (substr($list[$i],0,3)!='^^<')
+ if (preg_match('/^[-+]?[0-9]+$/', $list[$i])) {
+ //integer
+ $list[$i] = intval($list[$i]);
+ } else if (is_numeric($list[$i])) {
+ //float or decimal
+ // After conversion we cannot distinguish between both
+ $list[$i] = floatval($list[$i]);
+ } else if ((!strstr('<_"?.;,{}[]()@', $list[$i]{0}))
+ && (substr($list[$i],0,3) != '^^<')
) {
- $_r = explode(":",$list[$i]);
- $ns = $_r[0].':';
+ //prefix or unknown
+ $_r = explode(':', $list[$i]);
+ $ns = $_r[0] . ':';
$name = $_r[1];
if (isset($prefixes[$ns])) {
$list[$i] = '<'.$prefixes[$ns].$name.'>';
- } else if (isset($prefixes[substr($ns,2)])) {
- $list[$i] = '^^'.$prefixes[substr($ns,2)].$name.'';
+ } else if (isset($prefixes[substr($ns, 2)])) {
+ $list[$i] = '^^' . $prefixes[substr($ns, 2)] . $name . '';
} else {
- #die('Prefix not declared:'.$ns);
- $this->parseError=true;
+ //die('Prefix not declared:'.$ns);
+ $this->parseError = true;
trigger_error('Prefix not declared: '.$ns, E_USER_ERROR);
break;
}
@@ -602,7 +618,9 @@
}
if (substr($list[$i],0,2)=='^^') {
- if ($list[$i][2]!='<'){$list[$i]='^^<'.substr($list[$i],2).'>';};
+ if ($list[$i][2]!='<') {
+ $list[$i] = '^^<' . substr($list[$i], 2) . '>';
+ }
};
}//foreach list item
@@ -999,67 +1017,94 @@
$t = $this->getStatements($t); # get all of the "statements" from the stream
foreach ($t as $stat) {
- $stats=$this->statementize($stat);
+ $stats = $this->statementize($stat);
foreach ($stats as $y) {
- $result[]=$y;
+ $result[]=$y;
}
}
+
// for x in [statementize(stat) for stat in t] {
// for y in x: result.append(y)
return $result;
}
- /**
- * Constructs a RAP RDFNode from URI/Literal/Bnode
- * @access private
- * @param string $s
- * @returns object RDFNode
- **/
- function toRDFNode($s,$state) {
- $ins=substr($s,1,-1);
- if ($s{0}=="\"") {
- $lang=NULL;
+ /**
+ * Constructs a RAP RDFNode from URI/Literal/Bnode
+ * @access private
+ * @param string $s
+ * @returns object RDFNode
+ **/
+ function toRDFNode($s, $state)
+ {
+ $ins = substr($s, 1, -1);
+ if ($s{0} == '"') {
+ $lang = NULL;
- if (count($state)>3) {
+ if (count($state)>3) {
+ for ($i = 3; $i < count($state); $i++) {
+ if ($state[$i][0]=='@') {
+ $lang = substr($state[3], 1);
+ }
+ if (substr($state[$i],0,2) == '^^') {
+ $dtype = substr($state[$i],2);
+ if ($dtype[0]=='<') {
+ $dtype = substr($dtype,1,-1);
+ }
+ }
+ }
+ }
- for ($i = 3; $i < count($state); $i++){
- if ($state[$i][0]=='@')$lang=substr($state[3],1);
- if (substr($state[$i],0,2)=='^^'){
+ if (UNIC_RDF) {
+ $ins = $this->str2unicode_nfc($ins);
+ }
+ $new_Literal = new Literal($ins, $lang);
+ if (isset($dtype)) {
+ $new_Literal->setDatatype($dtype);
+ }
+ return $new_Literal;
+ } else if (is_int($s)) {
+ $value = new Literal($s);
+ $value->setDatatype(XML_SCHEMA . 'integer');
+ return $value;
+ } else if (is_float($s)) {
+ $value = new Literal($s);
+ $value->setDatatype(XML_SCHEMA . 'double');
+ return $value;
+ } else if ($s == '@true') {
+ $value = new Literal(true);
+ $value->setDatatype(XML_SCHEMA . 'boolean');
+ return $value;
+ } else if ($s == '@false') {
+ $value = new Literal(false);
+ $value->setDatatype(XML_SCHEMA . 'boolean');
+ return $value;
+ }
- $dtype=substr($state[$i],2);
- if ($dtype[0]=='<') $dtype= substr($dtype,1,-1);
+ if (strstr($s, '_' . BNODE_PREFIX)) {
+ if (($this->FixBnodes) || (!array_search($s,$this->bNodeMap))) {
+ return new BlankNode($ins);
+ } else {
+ return new BlankNode(
+ trim(
+ substr(
+ array_search($s, $this->bNodeMap),
+ 2
+ )
+ )
+ );
+ };
+ }
- };
+ return new Resource($ins);
+ }//function toRDFNode($s, $state)
- };
- };
- if(UNIC_RDF){
- $ins=$this->str2unicode_nfc($ins);
- }
- $new_Literal=new Literal($ins,$lang);
- if (isset($dtype)) $new_Literal->setDatatype($dtype);
- return $new_Literal;
- };
- if (strstr($s,'_'.BNODE_PREFIX)) {
- if (($this->FixBnodes) OR (!array_search($s,$this->bNodeMap))) {
- return new BlankNode($ins);
- } else {return new BlankNode(trim(substr(array_search($s,$this->bNodeMap),2)));
- };
- }
-
- return new Resource($ins);
- }
-
-
-
-
} //end: N3Parser
?>
Modified: trunk/rdfapi-php/test/unit/Syntax/n3Parser_test.php
===================================================================
--- trunk/rdfapi-php/test/unit/Syntax/n3Parser_test.php 2007-08-12 18:10:08 UTC (rev 494)
+++ trunk/rdfapi-php/test/unit/Syntax/n3Parser_test.php 2007-08-13 04:59:45 UTC (rev 495)
@@ -1,4 +1,5 @@
<?php
+require_once RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3;
// ----------------------------------------------------------------------------------
// Class: testN3Parser
@@ -8,103 +9,207 @@
* Tests the N3Parser
*
* @version $Id$
- * @author Tobias Gau� <tob...@we...>
+ * @author Tobias Gauss <tob...@we...>
+ * @author Christian Weiske <cw...@cw...?
*
* @package unittests
* @access public
*/
- class testN3Parser extends UnitTestCase {
- function testN3Parser() {
- $this->UnitTestCase();
+class testN3Parser extends UnitTestCase
+{
- $_SESSION['n3TestInput']='
- @prefix p: <http://www.example.org/personal_details#> .
- @prefix m: <http://www.example.org/meeting_organization#> .
+ function testN3Parser() {
+ $this->UnitTestCase();
- <http://www.example.org/people#fred>
- p:GivenName "Fred";
- p:hasEmail <mailto:fr...@ex...>;
- m:attending <http://meetings.example.com/cal#m1> .
+ $_SESSION['n3TestInput']='
+ @prefix p: <http://www.example.org/personal_details#> .
+ @prefix m: <http://www.example.org/meeting_organization#> .
- <http://meetings.example.com/cal#m1>
- m:homePage <http://meetings.example.com/m1/hp> .
- ';
+ <http://www.example.org/people#fred>
+ p:GivenName "Fred";
+ p:hasEmail <mailto:fr...@ex...>;
+ m:attending <http://meetings.example.com/cal#m1> .
+ <http://meetings.example.com/cal#m1>
+ m:homePage <http://meetings.example.com/m1/hp> .
+ ';
- }
- function testIsMemmodel() {
- // Import Package
- include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
- $n3pars= new N3Parser();
- $model=$n3pars->parse2model($_SESSION['n3TestInput'],false);
- $this->assertIsA($model, 'memmodel');
- }
+ }
+ function testIsMemmodel() {
- function testParsing() {
+ // Import Package
+ $n3pars= new N3Parser();
+ $model=$n3pars->parse2model($_SESSION['n3TestInput'],false);
+ $this->assertIsA($model, 'memmodel');
+ }
- $n3pars= new N3Parser();
- $model=$n3pars->parse2model($_SESSION['n3TestInput'],false);
+ function testParsing() {
+ $n3pars= new N3Parser();
+ $model=$n3pars->parse2model($_SESSION['n3TestInput'],false);
- $model2 = new MemModel();
- // Ceate new statements and add them to the model
- $statement1 = new Statement(new Resource("http://www.example.org/people#fred"),
- new Resource("http://www.example.org/personal_details#hasEmail"),
- new Resource("mailto:fr...@ex..."));
- $statement2 = new Statement(new Resource("http://www.example.org/people#fred"),
- new Resource("http://www.example.org/meeting_organization#attending"),
- new Resource("http://meetings.example.com/cal#m1"));
- $statement3 = new Statement(new Resource("http://www.example.org/people#fred"),
- new Resource("http://www.example.org/personal_details#GivenName"),
- new Literal("Fred"));
- $statement4 = new Statement(new Resource("http://meetings.example.com/cal#m1"),
- new Resource("http://www.example.org/meeting_organization#homePage"),
- new Resource("http://meetings.example.com/m1/hp"));
+ $model2 = new MemModel();
+ // Ceate new statements and add them to the model
+ $statement1 = new Statement(new Resource("http://www.example.org/people#fred"),
+ new Resource("http://www.example.org/personal_details#hasEmail"),
+ new Resource("mailto:fr...@ex..."));
+ $statement2 = new Statement(new Resource("http://www.example.org/people#fred"),
+ new Resource("http://www.example.org/meeting_organization#attending"),
+ new Resource("http://meetings.example.com/cal#m1"));
+ $statement3 = new Statement(new Resource("http://www.example.org/people#fred"),
+ new Resource("http://www.example.org/personal_details#GivenName"),
+ new Literal("Fred"));
+ $statement4 = new Statement(new Resource("http://meetings.example.com/cal#m1"),
+ new Resource("http://www.example.org/meeting_organization#homePage"),
+ new Resource("http://meetings.example.com/m1/hp"));
- $model2->add($statement1);
- $model2->add($statement2);
- $model2->add($statement3);
- $model2->add($statement4);
+ $model2->add($statement1);
+ $model2->add($statement2);
+ $model2->add($statement3);
+ $model2->add($statement4);
- $this->assertTrue($model->containsAll($model2));
- }
- function testPrefixNotDeclared() {
- $rdfInput='
- @prefix m: <http://www.example.org/meeting_organization#>.
+ $this->assertTrue($model->containsAll($model2));
+ }
- <http://www.example.org/people#fred>
- p:GivenName "Fred";
- p:hasEmail <mailto:fr...@ex...>;
- m:attending <http://meetings.example.com/cal#m1> .
- ';
+ function testPrefixNotDeclared() {
+ $rdfInput='
+ @prefix m: <http://www.example.org/meeting_organization#>.
- $n3pars= new N3Parser();
- $model=$n3pars->parse2model($rdfInput,false);
- //var_dump($model);
- $this->assertErrorPattern('[Prefix not declared: p:]');
- }
+ <http://www.example.org/people#fred>
+ p:GivenName "Fred";
+ p:hasEmail <mailto:fr...@ex...>;
+ m:attending <http://meetings.example.com/cal#m1> .
+ ';
- function testLoneSemicolon() {
- $n3 = '<a> <b> <c> ; .';
- $parser = &new N3Parser();
- $model = &$parser->parse2model($n3, false);
- $this->assertEqual(1, $model->size());
- $this->assertNoErrors();
- }
+ $n3pars= new N3Parser();
+ $model=$n3pars->parse2model($rdfInput,false);
+ //var_dump($model);
+ $this->assertErrorPattern('[Prefix not declared: p:]');
+ }
- function testTightClosingList() {
- $n3 = '@prefix : <http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql4/manifest#> .
- @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
- <> mf:entries ( mf:syn-09) .';
- $parser = &new N3Parser();
- $model = &$parser->parse2model($n3, false);
- //if bug occured, the parser would be in an endless loop
- }
+ function testLoneSemicolon() {
+ $n3 = '<a> <b> <c> ; .';
+ $parser = &new N3Parser();
+ $model = &$parser->parse2model($n3, false);
+ $this->assertEqual(1, $model->size());
+ $this->assertNoErrors();
}
+
+ function testTightClosingList() {
+ $n3 = '@prefix : <http://www.w3.org/2001/sw/DataAccess/tests/data-r2/syntax-sparql4/manifest#> .
+ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
+ <> mf:entries ( mf:syn-09) .';
+ $parser = &new N3Parser();
+ $model = &$parser->parse2model($n3, false);
+ //if bug occured, the parser would be in an endless loop
+ }
+
+
+
+ /**
+ * Check number parsing
+ * @see http://www.w3.org/2000/10/swap/grammar/n3-report.html#node
+ */
+ function testNumbers()
+ {
+ $n3 = '@prefix : <http://example.org/#> .
+ :foo :bar 0.7 .
+ :foo :bar 42 .
+ :foo :bar 10e6 .
+
+ :foo :bar -0.7 .
+ :foo :bar -42 .
+ :foo :bar -12E-6 .
+ ';
+ $parser = &new N3Parser();
+
+ $model = &$parser->parse2model($n3, false);
+
+ $model2 = new MemModel();
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(0.7, null, XML_SCHEMA . 'double')
+ )
+ );
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(42, null, XML_SCHEMA . 'integer')
+ )
+ );
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(10e6, null, XML_SCHEMA . 'double')
+ )
+ );
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(-0.7, null, XML_SCHEMA . 'double')
+ )
+ );
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(-42, null, XML_SCHEMA . 'integer')
+ )
+ );
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(-12E-6, null, XML_SCHEMA . 'double')
+ )
+ );
+
+ $this->assertEqual(6, $model->size());
+ $this->assertTrue($model->containsAll($model2));
+ }//function testNumbers()
+
+
+
+ function testBooleans()
+ {
+ $n3 = '@prefix : <http://example.org/#> .
+ :foo :bar @true .
+ :foo :bar @false .
+ ';
+ $parser = &new N3Parser();
+ //$parser->debug = true;
+ $model = &$parser->parse2model($n3, false);
+
+ $model2 = new MemModel();
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(true, null, XML_SCHEMA . 'boolean')
+ )
+ );
+ $model2->add(
+ new Statement(
+ new Resource("http://example.org/#foo"),
+ new Resource("http://example.org/#bar"),
+ new Literal(false, null, XML_SCHEMA . 'boolean')
+ )
+ );
+
+ //var_dump($model->triples);
+ $this->assertEqual(2, $model->size());
+ $this->assertTrue($model->containsAll($model2));
+ }//function testBooleans()
+}
?>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|