Skip to content

Commit

Permalink
Merge pull request #9 from sweetrdf/issue7
Browse files Browse the repository at this point in the history
Issue7
  • Loading branch information
zozlak authored Apr 19, 2024
2 parents 82a1efa + 27be9e7 commit da522d6
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 25 deletions.
41 changes: 20 additions & 21 deletions src/quickRdfIo/NQuadsParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ class NQuadsParser implements iParser, iQuadIterator {
const BLANKNODE3_STRICT = '[-0-9_:A-Za-z\x{00B7}\x{00C0}-\x{00D6}\x{00D8}-\x{00F6}\x{00F8}-\x{02FF}\x{0300}-\x{037D}\x{037F}-\x{1FFF}\x{200C}-\x{200D}\x{203F}-\x{2040}\x{2070}-\x{218F}\x{2C00}-\x{2FEF}\x{3001}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFFD}\x{10000}-\x{EFFFF}.]';
const BLANKNODE4_STRICT = '[-0-9_:A-Za-z\x{00B7}\x{00C0}-\x{00D6}\x{00D8}-\x{00F6}\x{00F8}-\x{02FF}\x{0300}-\x{037D}\x{037F}-\x{1FFF}\x{200C}-\x{200D}\x{203F}-\x{2040}\x{2070}-\x{218F}\x{2C00}-\x{2FEF}\x{3001}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFFD}\x{10000}-\x{EFFFF}]';
const BLANKNODE = '(_:[^\s<.]+)';
const LITERAL_STRICT = '"((?>[^\x{22}\x{5C}\x{0A}\x{0D}]|\\\\[tbnrf"\'\\\\]|\\\\u[0-9A-Fa-f]{4}|\\\\U[0-9A-Fa-f]{8})*)"';
const LITERAL = '"((?>[^"]|\\")*)"';
const LITERAL = '"((?>[^\x{22}\x{5C}\x{0A}\x{0D}]|\\\\[tbnrf"\'\\\\]|\\\\u[0-9A-Fa-f]{4}|\\\\U[0-9A-Fa-f]{8})*)"';
const STAR_START = '%\\G\s*<<%';
const STAR_END = '%\\G\s*>>%';
const READ_BUF_SIZE = 8096;
Expand Down Expand Up @@ -155,7 +154,7 @@ public function __construct(iDataFactory $dataFactory, bool $strict = false,
$iri = self::IRIREF_STRICT;
$blank = '(' . self::BLANKNODE1_STRICT . self::BLANKNODE2_STRICT . '(?:' . self::BLANKNODE3_STRICT . '*' . self::BLANKNODE4_STRICT . ')?)';
$lang = self::LANGTAG_STRICT;
$literal = self::LITERAL_STRICT;
$literal = self::LITERAL;
$lineEnd = "\\s*\\.$comment$eol";
$flags = 'u';
} else {
Expand All @@ -166,7 +165,7 @@ public function __construct(iDataFactory $dataFactory, bool $strict = false,
$lang = self::LANGTAG;
$literal = self::LITERAL;
$lineEnd = "\\s*\\.";
$flags = '';
$flags = 'u';
}
$graph = '';
if ($mode === self::MODE_QUADS || $mode === self::MODE_QUADS_STAR) {
Expand Down Expand Up @@ -259,9 +258,9 @@ private function quadGenerator(): Generator {
while (true) {
$n++;
$this->line = $this->readLine();
$ret = preg_match($this->regexp, $this->line, $matches, PREG_UNMATCHED_AS_NULL);
if ($ret === 0 && !empty(trim($this->line))) {
throw new RdfIoException("Can't parse line $n: " . $this->line);
$ret = (int) preg_match($this->regexp, $this->line, $matches, PREG_UNMATCHED_AS_NULL);
if (0 === $ret && !empty(trim($this->line))) {
throw new RdfIoException("Can't parse line $n with error '" . preg_last_error_msg() . "': " . $this->line);
}
if (($matches[3] ?? null) !== null) {
yield $this->makeQuad($matches);
Expand Down Expand Up @@ -320,10 +319,10 @@ private function starQuadGenerator(): Generator {
$this->level = 0;
$this->line = $this->readLine();
try {
yield $this->parseStar();
yield $this->parseStar($n);
} catch (RdfIoException $e) {
$ret = preg_match($this->regexpCommentLine, $this->line);
if ($ret === 0) {
if (0 === (int) $ret) {
throw $e;
}
}
Expand All @@ -333,23 +332,23 @@ private function starQuadGenerator(): Generator {
}
}

private function parseStar(): iQuad {
private function parseStar(int $line): iQuad {
//echo str_repeat("\t", $this->level) . "parsing " . substr($this->line, $this->offset);
$matches = null;
if (preg_match(self::STAR_START, $this->line, $matches, 0, $this->offset)) {
$this->offset += strlen($matches[0]);
$this->level++;
$sbj = $this->parseStar();
$sbj = $this->parseStar($line);
$ret = preg_match($this->regexpPred, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Failed parsing predicate " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Failed parsing predicate on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);

Check failure on line 346 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.

Check failure on line 346 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
$pred = $this->dataFactory::namedNode($matches[1]);

Check failure on line 347 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $iri of static method rdfInterface\DataFactoryInterface::namedNode() expects string|Stringable, string|null given.

Check failure on line 347 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $iri of static method rdfInterface\DataFactoryInterface::namedNode() expects string|Stringable, string|null given.
} else {
$ret = preg_match($this->regexpSbjPred, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Failed parsing subject and predicate " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Failed parsing subject and predicate on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);

Check failure on line 353 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.

Check failure on line 353 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
if ($matches[1] !== null) {
Expand All @@ -362,7 +361,7 @@ private function parseStar(): iQuad {
if (preg_match(self::STAR_START, $this->line, $matches, 0, $this->offset)) {
$this->offset += strlen($matches[0]);
$this->level++;
$obj = $this->parseStar();
$obj = $this->parseStar($line);
$ret = preg_match($this->regexpGraph, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
$this->offset += strlen($matches[0]);

Check failure on line 366 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.

Check failure on line 366 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
if (($matches[1] ?? null) !== null) {
Expand All @@ -371,9 +370,9 @@ private function parseStar(): iQuad {
$graph = $this->dataFactory::blankNode($matches[2]);
}
} else {
$ret = preg_match($this->regexpObjGraph, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Can't parse object " . substr($this->line, $this->offset));
$ret = (int) preg_match($this->regexpObjGraph, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if (0 === $ret) {
throw new RdfIoException("Can't parse object on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);

Check failure on line 377 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.

Check failure on line 377 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
if ($matches[1] !== null) {
Expand All @@ -393,8 +392,8 @@ private function parseStar(): iQuad {
}
$regexpEnd = $this->level > 0 ? self::STAR_END : $this->regexpLineEnd;
$ret = preg_match($regexpEnd, $this->line, $matches, 0, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Can't parse end " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Can't parse end on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);
$quad = $this->dataFactory::quad($sbj, $pred, $obj, $graph ?? null);
Expand Down
6 changes: 3 additions & 3 deletions src/quickRdfIo/Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ static public function getParser(string $formatOrFilename,
'application/trig' => new TriGParser($dataFactory, ['documentIRI' => $baseUri]),
'nt',
'ntriples',
'n-triples' => new NQuadsParser($dataFactory, false, NQuadsParser::MODE_TRIPLES),
'ntriplesstar',
'n-triples',
'n-triples-star',
'application/n-triples',
'text/plain' => new NQuadsParser($dataFactory, false, NQuadsParser::MODE_TRIPLES_STAR),
'nq',
'nquads',
'nquadstar',
'n-quads',
'n-quads' => new NQuadsParser($dataFactory, false, NQuadsParser::MODE_QUADS),
'nquadsstar',
'n-quads-star',
'application/n-quads' => new NQuadsParser($dataFactory, false, NQuadsParser::MODE_QUADS_STAR),
'xml',
Expand Down
17 changes: 16 additions & 1 deletion tests/NQuadsParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private function getModes(?bool $strict, ?bool $quads, ?bool $star): array {
*/
private function readTestLines(string $filename): array {
$tests = [];
$data = file($filename) ?: throw new \RuntimeException("Failed to open $filename");
$data = file($filename) ?: throw new \RuntimeException("Failed to open $filename");
foreach ($data as $n => $l) {
if (substr($l, 0, 1) !== '#') {
$tests[$n + 1] = $l;
Expand Down Expand Up @@ -249,4 +249,19 @@ public function testInputExceptions(): void {
$this->assertEquals('Input has to be a resource or Psr\Http\Message\StreamInterface object', $ex->getMessage());
}
}

/**
* https://github.com/sweetrdf/quickRdfIo/issues/7
*/
public function testIssue7(): void {
$input = __DIR__ . '/files/issue7.nt';
$df = new DF();
$dataset = new \quickRdf\Dataset();

foreach ($this->getModes(null, null, null)as $i) {
$parser = new NQuadsParser($df, $i->strict, $i->mode);
$dataset->add($parser->parseStream(fopen($input, 'r')));
$this->assertCount(2, $dataset);
}
}
}
Loading

0 comments on commit da522d6

Please sign in to comment.