n3 1.26.0 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -7
- package/browser/n3.min.js +1 -1
- package/lib/IRIs.js +4 -3
- package/lib/N3DataFactory.js +34 -6
- package/lib/N3Lexer.js +35 -17
- package/lib/N3Parser.js +206 -44
- package/lib/N3Store.js +23 -24
- package/lib/N3Util.js +0 -6
- package/lib/N3Writer.js +11 -9
- package/lib/index.js +2 -9
- package/package.json +24 -12
- package/src/IRIs.js +7 -6
- package/src/N3DataFactory.js +38 -9
- package/src/N3Lexer.js +37 -17
- package/src/N3Parser.js +229 -53
- package/src/N3Store.js +21 -22
- package/src/N3Util.js +0 -5
- package/src/N3Writer.js +11 -7
- package/src/index.js +0 -3
- package/lib/BaseIRI.js +0 -93
- package/lib/Util.js +0 -9
- package/src/BaseIRI.js +0 -101
- package/src/Util.js +0 -3
package/lib/N3Parser.js
CHANGED
|
@@ -34,10 +34,6 @@ class N3Parser {
|
|
|
34
34
|
if (!(this._supportsNamedGraphs = !(isTurtle || isN3))) this._readPredicateOrNamedGraph = this._readPredicate;
|
|
35
35
|
// Support triples in other graphs
|
|
36
36
|
this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
|
|
37
|
-
// Whether the log:isImpliedBy predicate is supported
|
|
38
|
-
this._isImpliedBy = options.isImpliedBy;
|
|
39
|
-
// Support nesting of triples
|
|
40
|
-
this._supportsRDFStar = format === '' || /star|\*$/.test(format);
|
|
41
37
|
// Disable relative IRIs in N-Triples or N-Quads mode
|
|
42
38
|
if (isLineMode) this._resolveRelativeIRI = iri => {
|
|
43
39
|
return null;
|
|
@@ -45,11 +41,13 @@ class N3Parser {
|
|
|
45
41
|
this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' : options.blankNodePrefix.replace(/^(?!_:)/, '_:');
|
|
46
42
|
this._lexer = options.lexer || new _N3Lexer.default({
|
|
47
43
|
lineMode: isLineMode,
|
|
48
|
-
n3: isN3
|
|
49
|
-
isImpliedBy: this._isImpliedBy
|
|
44
|
+
n3: isN3
|
|
50
45
|
});
|
|
51
46
|
// Disable explicit quantifiers by default
|
|
52
47
|
this._explicitQuantifiers = !!options.explicitQuantifiers;
|
|
48
|
+
// Disable parsing of unsupported versions by default
|
|
49
|
+
this._parseUnsupportedVersions = !!options.parseUnsupportedVersions;
|
|
50
|
+
this._version = options.version;
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
// ## Static class methods
|
|
@@ -126,6 +124,12 @@ class N3Parser {
|
|
|
126
124
|
}
|
|
127
125
|
}
|
|
128
126
|
|
|
127
|
+
// ### `_readBeforeTopContext` is called once only at the start of parsing.
|
|
128
|
+
_readBeforeTopContext(token) {
|
|
129
|
+
if (this._version && !this._isValidVersion(this._version)) return this._error(`Detected unsupported version as media type parameter: "${this._version}"`, token);
|
|
130
|
+
return this._readInTopContext(token);
|
|
131
|
+
}
|
|
132
|
+
|
|
129
133
|
// ### `_readInTopContext` reads a token when in the top context
|
|
130
134
|
_readInTopContext(token) {
|
|
131
135
|
switch (token.type) {
|
|
@@ -144,6 +148,11 @@ class N3Parser {
|
|
|
144
148
|
this._sparqlStyle = true;
|
|
145
149
|
case '@base':
|
|
146
150
|
return this._readBaseIRI;
|
|
151
|
+
// It could be a version declaration
|
|
152
|
+
case 'VERSION':
|
|
153
|
+
this._sparqlStyle = true;
|
|
154
|
+
case '@version':
|
|
155
|
+
return this._readVersion;
|
|
147
156
|
// It could be a graph
|
|
148
157
|
case '{':
|
|
149
158
|
if (this._supportsNamedGraphs) {
|
|
@@ -203,6 +212,11 @@ class N3Parser {
|
|
|
203
212
|
this._saveContext('blank', this._graph, this._subject = this._factory.blankNode(), null, null);
|
|
204
213
|
return this._readBlankNodeHead;
|
|
205
214
|
case '(':
|
|
215
|
+
const stack = this._contextStack,
|
|
216
|
+
parent = stack.length && stack[stack.length - 1];
|
|
217
|
+
if (parent.type === '<<') {
|
|
218
|
+
return this._error('Unexpected list in reified triple', token);
|
|
219
|
+
}
|
|
206
220
|
// Start a new list
|
|
207
221
|
this._saveContext('list', this._graph, this.RDF_NIL, null, null);
|
|
208
222
|
this._subject = null;
|
|
@@ -234,8 +248,12 @@ class N3Parser {
|
|
|
234
248
|
return this._completeSubjectLiteral;
|
|
235
249
|
} else this._subject = this._factory.literal(token.value, this._factory.namedNode(token.prefix));
|
|
236
250
|
break;
|
|
251
|
+
case '<<(':
|
|
252
|
+
if (!this._n3Mode) return this._error('Disallowed triple term as subject', token);
|
|
253
|
+
this._saveContext('<<(', this._graph, null, null, null);
|
|
254
|
+
this._graph = null;
|
|
255
|
+
return this._readSubject;
|
|
237
256
|
case '<<':
|
|
238
|
-
if (!this._supportsRDFStar) return this._error('Unexpected RDF-star syntax', token);
|
|
239
257
|
this._saveContext('<<', this._graph, null, null, null);
|
|
240
258
|
this._graph = null;
|
|
241
259
|
return this._readSubject;
|
|
@@ -263,6 +281,7 @@ class N3Parser {
|
|
|
263
281
|
case '.':
|
|
264
282
|
case ']':
|
|
265
283
|
case '}':
|
|
284
|
+
case '|}':
|
|
266
285
|
// Expected predicate didn't come, must have been trailing semicolon
|
|
267
286
|
if (this._predicate === null) return this._error(`Unexpected ${type}`, token);
|
|
268
287
|
this._subject = null;
|
|
@@ -302,6 +321,11 @@ class N3Parser {
|
|
|
302
321
|
this._saveContext('blank', this._graph, this._subject, this._predicate, this._subject = this._factory.blankNode());
|
|
303
322
|
return this._readBlankNodeHead;
|
|
304
323
|
case '(':
|
|
324
|
+
const stack = this._contextStack,
|
|
325
|
+
parent = stack.length && stack[stack.length - 1];
|
|
326
|
+
if (parent.type === '<<') {
|
|
327
|
+
return this._error('Unexpected list in reified triple', token);
|
|
328
|
+
}
|
|
305
329
|
// Start a new list
|
|
306
330
|
this._saveContext('list', this._graph, this._subject, this._predicate, this.RDF_NIL);
|
|
307
331
|
this._subject = null;
|
|
@@ -311,8 +335,11 @@ class N3Parser {
|
|
|
311
335
|
if (!this._n3Mode) return this._error('Unexpected graph', token);
|
|
312
336
|
this._saveContext('formula', this._graph, this._subject, this._predicate, this._graph = this._factory.blankNode());
|
|
313
337
|
return this._readSubject;
|
|
338
|
+
case '<<(':
|
|
339
|
+
this._saveContext('<<(', this._graph, this._subject, this._predicate, null);
|
|
340
|
+
this._graph = null;
|
|
341
|
+
return this._readSubject;
|
|
314
342
|
case '<<':
|
|
315
|
-
if (!this._supportsRDFStar) return this._error('Unexpected RDF-star syntax', token);
|
|
316
343
|
this._saveContext('<<', this._graph, this._subject, this._predicate, null);
|
|
317
344
|
this._graph = null;
|
|
318
345
|
return this._readSubject;
|
|
@@ -344,6 +371,11 @@ class N3Parser {
|
|
|
344
371
|
this._subject = null;
|
|
345
372
|
return this._readBlankNodeTail(token);
|
|
346
373
|
} else {
|
|
374
|
+
const stack = this._contextStack,
|
|
375
|
+
parentParent = stack.length > 1 && stack[stack.length - 2];
|
|
376
|
+
if (parentParent.type === '<<') {
|
|
377
|
+
return this._error('Unexpected compound blank node expression in reified triple', token);
|
|
378
|
+
}
|
|
347
379
|
this._predicate = null;
|
|
348
380
|
return this._readPredicate(token);
|
|
349
381
|
}
|
|
@@ -445,6 +477,11 @@ class N3Parser {
|
|
|
445
477
|
if (!this._n3Mode) return this._error('Unexpected graph', token);
|
|
446
478
|
this._saveContext('formula', this._graph, this._subject, this._predicate, this._graph = this._factory.blankNode());
|
|
447
479
|
return this._readSubject;
|
|
480
|
+
case '<<':
|
|
481
|
+
this._saveContext('<<', this._graph, null, null, null);
|
|
482
|
+
this._graph = null;
|
|
483
|
+
next = this._readSubject;
|
|
484
|
+
break;
|
|
448
485
|
default:
|
|
449
486
|
if ((item = this._readEntity(token)) === undefined) return;
|
|
450
487
|
}
|
|
@@ -452,6 +489,9 @@ class N3Parser {
|
|
|
452
489
|
// Create a new blank node if no item head was assigned yet
|
|
453
490
|
if (list === null) this._subject = list = this._factory.blankNode();
|
|
454
491
|
|
|
492
|
+
// When reading a reified triple, store the list as subject in the stack, as this will be overridden when reading the triple.
|
|
493
|
+
if (token.type === '<<') stack[stack.length - 1].subject = this._subject;
|
|
494
|
+
|
|
455
495
|
// Is this the first element of the list?
|
|
456
496
|
if (previousList === null) {
|
|
457
497
|
// This list is either the subject or the object of its parent
|
|
@@ -487,51 +527,82 @@ class N3Parser {
|
|
|
487
527
|
}
|
|
488
528
|
|
|
489
529
|
// ### `_completeLiteral` completes a literal with an optional datatype or language
|
|
490
|
-
_completeLiteral(token) {
|
|
530
|
+
_completeLiteral(token, component) {
|
|
491
531
|
// Create a simple string literal by default
|
|
492
532
|
let literal = this._factory.literal(this._literalValue);
|
|
533
|
+
let readCb;
|
|
493
534
|
switch (token.type) {
|
|
494
535
|
// Create a datatyped literal
|
|
495
536
|
case 'type':
|
|
496
537
|
case 'typeIRI':
|
|
497
538
|
const datatype = this._readEntity(token);
|
|
498
539
|
if (datatype === undefined) return; // No datatype means an error occurred
|
|
540
|
+
if (datatype.value === _IRIs.default.rdf.langString || datatype.value === _IRIs.default.rdf.dirLangString) {
|
|
541
|
+
return this._error('Detected illegal (directional) languaged-tagged string with explicit datatype', token);
|
|
542
|
+
}
|
|
499
543
|
literal = this._factory.literal(this._literalValue, datatype);
|
|
500
544
|
token = null;
|
|
501
545
|
break;
|
|
502
546
|
// Create a language-tagged string
|
|
503
547
|
case 'langcode':
|
|
548
|
+
if (token.value.length > 8) return this._error('Detected language tag of length larger than 8', token);
|
|
504
549
|
literal = this._factory.literal(this._literalValue, token.value);
|
|
550
|
+
this._literalLanguage = token.value;
|
|
505
551
|
token = null;
|
|
552
|
+
readCb = this._readDirCode.bind(this, component);
|
|
506
553
|
break;
|
|
507
554
|
}
|
|
508
555
|
return {
|
|
509
556
|
token,
|
|
510
|
-
literal
|
|
557
|
+
literal,
|
|
558
|
+
readCb
|
|
511
559
|
};
|
|
512
560
|
}
|
|
561
|
+
_readDirCode(component, listItem, token) {
|
|
562
|
+
// Attempt to read a dircode
|
|
563
|
+
if (token.type === 'dircode') {
|
|
564
|
+
const term = this._factory.literal(this._literalValue, {
|
|
565
|
+
language: this._literalLanguage,
|
|
566
|
+
direction: token.value
|
|
567
|
+
});
|
|
568
|
+
if (component === 'subject') this._subject = term;else this._object = term;
|
|
569
|
+
this._literalLanguage = undefined;
|
|
570
|
+
token = null;
|
|
571
|
+
}
|
|
572
|
+
if (component === 'subject') return token === null ? this._readPredicateOrNamedGraph : this._readPredicateOrNamedGraph(token);
|
|
573
|
+
return this._completeObjectLiteralPost(token, listItem);
|
|
574
|
+
}
|
|
513
575
|
|
|
514
576
|
// Completes a literal in subject position
|
|
515
577
|
_completeSubjectLiteral(token) {
|
|
516
|
-
|
|
578
|
+
const completed = this._completeLiteral(token, 'subject');
|
|
579
|
+
this._subject = completed.literal;
|
|
580
|
+
|
|
581
|
+
// Postpone completion if the literal is only partially completed (such as lang+dir).
|
|
582
|
+
if (completed.readCb) return completed.readCb.bind(this, false);
|
|
517
583
|
return this._readPredicateOrNamedGraph;
|
|
518
584
|
}
|
|
519
585
|
|
|
520
586
|
// Completes a literal in object position
|
|
521
587
|
_completeObjectLiteral(token, listItem) {
|
|
522
|
-
const completed = this._completeLiteral(token);
|
|
588
|
+
const completed = this._completeLiteral(token, 'object');
|
|
523
589
|
if (!completed) return;
|
|
524
590
|
this._object = completed.literal;
|
|
525
591
|
|
|
592
|
+
// Postpone completion if the literal is only partially completed (such as lang+dir).
|
|
593
|
+
if (completed.readCb) return completed.readCb.bind(this, listItem);
|
|
594
|
+
return this._completeObjectLiteralPost(completed.token, listItem);
|
|
595
|
+
}
|
|
596
|
+
_completeObjectLiteralPost(token, listItem) {
|
|
526
597
|
// If this literal was part of a list, write the item
|
|
527
598
|
// (we could also check the context stack, but passing in a flag is faster)
|
|
528
599
|
if (listItem) this._emit(this._subject, this.RDF_FIRST, this._object, this._graph);
|
|
529
600
|
// If the token was consumed, continue with the rest of the input
|
|
530
|
-
if (
|
|
601
|
+
if (token === null) return this._getContextEndReader();
|
|
531
602
|
// Otherwise, consume the token now
|
|
532
603
|
else {
|
|
533
604
|
this._readCallback = this._getContextEndReader();
|
|
534
|
-
return this._readCallback(
|
|
605
|
+
return this._readCallback(token);
|
|
535
606
|
}
|
|
536
607
|
}
|
|
537
608
|
|
|
@@ -552,7 +623,8 @@ class N3Parser {
|
|
|
552
623
|
// ### `_readPunctuation` reads punctuation between quads or quad parts
|
|
553
624
|
_readPunctuation(token) {
|
|
554
625
|
let next,
|
|
555
|
-
graph = this._graph
|
|
626
|
+
graph = this._graph,
|
|
627
|
+
startingAnnotation = false;
|
|
556
628
|
const subject = this._subject,
|
|
557
629
|
inversePredicate = this._inversePredicate;
|
|
558
630
|
switch (token.type) {
|
|
@@ -564,6 +636,7 @@ class N3Parser {
|
|
|
564
636
|
// A dot just ends the statement, without sharing anything with the next
|
|
565
637
|
case '.':
|
|
566
638
|
this._subject = null;
|
|
639
|
+
this._tripleTerm = null;
|
|
567
640
|
next = this._contextStack.length ? this._readSubject : this._readInTopContext;
|
|
568
641
|
if (inversePredicate) this._inversePredicate = false;
|
|
569
642
|
break;
|
|
@@ -575,19 +648,23 @@ class N3Parser {
|
|
|
575
648
|
case ',':
|
|
576
649
|
next = this._readObject;
|
|
577
650
|
break;
|
|
651
|
+
// ~ is allowed in the annotation syntax
|
|
652
|
+
case '~':
|
|
653
|
+
next = this._readReifierInAnnotation;
|
|
654
|
+
startingAnnotation = true;
|
|
655
|
+
break;
|
|
578
656
|
// {| means that the current triple is annotated with predicate-object pairs.
|
|
579
657
|
case '{|':
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
object = this._object;
|
|
584
|
-
this._subject = this._factory.quad(subject, predicate, object, this.DEFAULTGRAPH);
|
|
658
|
+
// Continue using the last triple as reified triple subject for the predicate-object pairs.
|
|
659
|
+
this._subject = this._readTripleTerm();
|
|
660
|
+
startingAnnotation = true;
|
|
585
661
|
next = this._readPredicate;
|
|
586
662
|
break;
|
|
587
|
-
// |} means that the current
|
|
663
|
+
// |} means that the current reified triple in annotation syntax is finalized.
|
|
588
664
|
case '|}':
|
|
589
|
-
if (this.
|
|
665
|
+
if (!this._annotation) return this._error('Unexpected annotation syntax closing', token);
|
|
590
666
|
this._subject = null;
|
|
667
|
+
this._annotation = false;
|
|
591
668
|
next = this._readPunctuation;
|
|
592
669
|
break;
|
|
593
670
|
default:
|
|
@@ -599,11 +676,14 @@ class N3Parser {
|
|
|
599
676
|
return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
|
|
600
677
|
}
|
|
601
678
|
// A quad has been completed now, so return it
|
|
602
|
-
if (subject !== null) {
|
|
679
|
+
if (subject !== null && (!startingAnnotation || startingAnnotation && !this._annotation)) {
|
|
603
680
|
const predicate = this._predicate,
|
|
604
681
|
object = this._object;
|
|
605
682
|
if (!inversePredicate) this._emit(subject, predicate, object, graph);else this._emit(object, predicate, subject, graph);
|
|
606
683
|
}
|
|
684
|
+
if (startingAnnotation) {
|
|
685
|
+
this._annotation = true;
|
|
686
|
+
}
|
|
607
687
|
return next;
|
|
608
688
|
}
|
|
609
689
|
|
|
@@ -657,6 +737,20 @@ class N3Parser {
|
|
|
657
737
|
return this._readDeclarationPunctuation;
|
|
658
738
|
}
|
|
659
739
|
|
|
740
|
+
// ### `_isValidVersion` checks if the given version is valid for this parser to handle.
|
|
741
|
+
_isValidVersion(version) {
|
|
742
|
+
return this._parseUnsupportedVersions || N3Parser.SUPPORTED_VERSIONS.includes(version);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// ### `_readVersion` reads version string declaration
|
|
746
|
+
_readVersion(token) {
|
|
747
|
+
if (token.type !== 'literal') return this._error('Expected literal to follow version declaration', token);
|
|
748
|
+
if (token.end - token.start !== token.value.length + 2) return this._error('Version declarations must use single quotes', token);
|
|
749
|
+
this._versionCallback(token.value);
|
|
750
|
+
if (!this._isValidVersion(token.value)) return this._error(`Detected unsupported version: "${token.value}"`, token);
|
|
751
|
+
return this._readDeclarationPunctuation;
|
|
752
|
+
}
|
|
753
|
+
|
|
660
754
|
// ### `_readNamedGraphLabel` reads the label of a named graph
|
|
661
755
|
_readNamedGraphLabel(token) {
|
|
662
756
|
switch (token.type) {
|
|
@@ -792,22 +886,13 @@ class N3Parser {
|
|
|
792
886
|
return this._readPath;
|
|
793
887
|
}
|
|
794
888
|
|
|
795
|
-
// ### `
|
|
796
|
-
|
|
797
|
-
if (token.type !== '>>') {
|
|
798
|
-
// An entity means this is a quad (only allowed if not already inside a graph)
|
|
799
|
-
if (this._supportsQuads && this._graph === null && (this._graph = this._readEntity(token)) !== undefined) return this._readRDFStarTail;
|
|
800
|
-
return this._error(`Expected >> to follow "${this._object.id}"`, token);
|
|
801
|
-
}
|
|
802
|
-
return this._readRDFStarTail(token);
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
// ### `_readRDFStarTail` reads the end of a nested RDF-star triple
|
|
806
|
-
_readRDFStarTail(token) {
|
|
807
|
-
if (token.type !== '>>') return this._error(`Expected >> but got ${token.type}`, token);
|
|
889
|
+
// ### `_readTripleTermTail` reads the end of a triple term
|
|
890
|
+
_readTripleTermTail(token) {
|
|
891
|
+
if (token.type !== ')>>') return this._error(`Expected )>> but got ${token.type}`, token);
|
|
808
892
|
// Read the quad and restore the previous context
|
|
809
893
|
const quad = this._factory.quad(this._subject, this._predicate, this._object, this._graph || this.DEFAULTGRAPH);
|
|
810
|
-
this._restoreContext('<<', token);
|
|
894
|
+
this._restoreContext('<<(', token);
|
|
895
|
+
|
|
811
896
|
// If the triple was the subject, continue by reading the predicate.
|
|
812
897
|
if (this._subject === null) {
|
|
813
898
|
this._subject = quad;
|
|
@@ -820,6 +905,77 @@ class N3Parser {
|
|
|
820
905
|
}
|
|
821
906
|
}
|
|
822
907
|
|
|
908
|
+
// ### `_readReifiedTripleTailOrReifier` reads a reifier or the end of a nested reified triple
|
|
909
|
+
_readReifiedTripleTailOrReifier(token) {
|
|
910
|
+
if (token.type === '~') {
|
|
911
|
+
return this._readReifier;
|
|
912
|
+
}
|
|
913
|
+
return this._readReifiedTripleTail(token);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// ### `_readReifiedTripleTail` reads the end of a nested reified triple
|
|
917
|
+
_readReifiedTripleTail(token) {
|
|
918
|
+
if (token.type !== '>>') return this._error(`Expected >> but got ${token.type}`, token);
|
|
919
|
+
// Read the triple term and restore the previous context
|
|
920
|
+
this._tripleTerm = null;
|
|
921
|
+
const reifier = this._readTripleTerm();
|
|
922
|
+
this._restoreContext('<<', token);
|
|
923
|
+
|
|
924
|
+
// // If we're in a list, continue processing that list
|
|
925
|
+
const stack = this._contextStack,
|
|
926
|
+
parent = stack.length && stack[stack.length - 1];
|
|
927
|
+
if (parent && parent.type === 'list') {
|
|
928
|
+
this._emit(this._subject, this.RDF_FIRST, reifier, this._graph);
|
|
929
|
+
return this._getContextEndReader();
|
|
930
|
+
}
|
|
931
|
+
// If the triple was the subject, continue by reading the predicate.
|
|
932
|
+
else if (this._subject === null) {
|
|
933
|
+
this._subject = reifier;
|
|
934
|
+
return this._readPredicateOrReifierTripleEnd;
|
|
935
|
+
}
|
|
936
|
+
// If the triple was the object, read context end.
|
|
937
|
+
else {
|
|
938
|
+
this._object = reifier;
|
|
939
|
+
return this._getContextEndReader();
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
_readPredicateOrReifierTripleEnd(token) {
|
|
943
|
+
if (token.type === '.') {
|
|
944
|
+
this._subject = null;
|
|
945
|
+
return this._readPunctuation(token);
|
|
946
|
+
}
|
|
947
|
+
return this._readPredicate(token);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
// ### `_readReifier` reads the triple term identifier after a tilde when in a reifying triple.
|
|
951
|
+
_readReifier(token) {
|
|
952
|
+
this._reifier = this._readEntity(token);
|
|
953
|
+
return this._readReifiedTripleTail;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// ### `_readReifier` reads the optional triple term identifier after a tilde when in annotation syntax.
|
|
957
|
+
_readReifierInAnnotation(token) {
|
|
958
|
+
// If next token is a reifier, read it as such.
|
|
959
|
+
if (token.type === 'IRI' || token.type === 'typeIRI' || token.type === 'type' || token.type === 'prefixed' || token.type === 'blank' || token.type === 'var') {
|
|
960
|
+
this._reifier = this._readEntity(token);
|
|
961
|
+
return this._readPunctuation;
|
|
962
|
+
}
|
|
963
|
+
// Otherwise, emit and assert triple term.
|
|
964
|
+
this._readTripleTerm();
|
|
965
|
+
this._subject = null;
|
|
966
|
+
return this._readPunctuation(token);
|
|
967
|
+
}
|
|
968
|
+
_readTripleTerm() {
|
|
969
|
+
const stack = this._contextStack,
|
|
970
|
+
parent = stack.length && stack[stack.length - 1];
|
|
971
|
+
const parentGraph = parent ? parent.graph : undefined;
|
|
972
|
+
const reifier = this._reifier || this._factory.blankNode();
|
|
973
|
+
this._reifier = null;
|
|
974
|
+
this._tripleTerm = this._tripleTerm || this._factory.quad(this._subject, this._predicate, this._object);
|
|
975
|
+
this._emit(reifier, this.RDF_REIFIES, this._tripleTerm, parentGraph || this.DEFAULTGRAPH);
|
|
976
|
+
return reifier;
|
|
977
|
+
}
|
|
978
|
+
|
|
823
979
|
// ### `_getContextEndReader` gets the next reader function at the end of a context
|
|
824
980
|
_getContextEndReader() {
|
|
825
981
|
const contextStack = this._contextStack;
|
|
@@ -831,8 +987,10 @@ class N3Parser {
|
|
|
831
987
|
return this._readListItem;
|
|
832
988
|
case 'formula':
|
|
833
989
|
return this._readFormulaTail;
|
|
990
|
+
case '<<(':
|
|
991
|
+
return this._readTripleTermTail;
|
|
834
992
|
case '<<':
|
|
835
|
-
return this.
|
|
993
|
+
return this._readReifiedTripleTailOrReifier;
|
|
836
994
|
}
|
|
837
995
|
}
|
|
838
996
|
|
|
@@ -947,25 +1105,28 @@ class N3Parser {
|
|
|
947
1105
|
// ## Public methods
|
|
948
1106
|
|
|
949
1107
|
// ### `parse` parses the N3 input and emits each parsed quad through the onQuad callback.
|
|
950
|
-
parse(input, quadCallback, prefixCallback) {
|
|
1108
|
+
parse(input, quadCallback, prefixCallback, versionCallback) {
|
|
951
1109
|
// The second parameter accepts an object { onQuad: ..., onPrefix: ..., onComment: ...}
|
|
952
1110
|
// As a second and third parameter it still accepts a separate quadCallback and prefixCallback for backward compatibility as well
|
|
953
|
-
let onQuad, onPrefix, onComment;
|
|
954
|
-
if (quadCallback && (quadCallback.onQuad || quadCallback.onPrefix || quadCallback.onComment)) {
|
|
1111
|
+
let onQuad, onPrefix, onComment, onVersion;
|
|
1112
|
+
if (quadCallback && (quadCallback.onQuad || quadCallback.onPrefix || quadCallback.onComment || quadCallback.onVersion)) {
|
|
955
1113
|
onQuad = quadCallback.onQuad;
|
|
956
1114
|
onPrefix = quadCallback.onPrefix;
|
|
957
1115
|
onComment = quadCallback.onComment;
|
|
1116
|
+
onVersion = quadCallback.onVersion;
|
|
958
1117
|
} else {
|
|
959
1118
|
onQuad = quadCallback;
|
|
960
1119
|
onPrefix = prefixCallback;
|
|
1120
|
+
onVersion = versionCallback;
|
|
961
1121
|
}
|
|
962
1122
|
// The read callback is the next function to be executed when a token arrives.
|
|
963
1123
|
// We start reading in the top context.
|
|
964
|
-
this._readCallback = this.
|
|
1124
|
+
this._readCallback = this._readBeforeTopContext;
|
|
965
1125
|
this._sparqlStyle = false;
|
|
966
1126
|
this._prefixes = Object.create(null);
|
|
967
1127
|
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2) : `b${blankNodePrefix++}_`;
|
|
968
1128
|
this._prefixCallback = onPrefix || noop;
|
|
1129
|
+
this._versionCallback = onVersion || noop;
|
|
969
1130
|
this._inversePredicate = false;
|
|
970
1131
|
this._quantified = Object.create(null);
|
|
971
1132
|
|
|
@@ -1017,14 +1178,15 @@ function initDataFactory(parser, factory) {
|
|
|
1017
1178
|
parser.RDF_FIRST = factory.namedNode(_IRIs.default.rdf.first);
|
|
1018
1179
|
parser.RDF_REST = factory.namedNode(_IRIs.default.rdf.rest);
|
|
1019
1180
|
parser.RDF_NIL = factory.namedNode(_IRIs.default.rdf.nil);
|
|
1181
|
+
parser.RDF_REIFIES = factory.namedNode(_IRIs.default.rdf.reifies);
|
|
1020
1182
|
parser.N3_FORALL = factory.namedNode(_IRIs.default.r.forAll);
|
|
1021
1183
|
parser.N3_FORSOME = factory.namedNode(_IRIs.default.r.forSome);
|
|
1022
1184
|
parser.ABBREVIATIONS = {
|
|
1023
1185
|
'a': factory.namedNode(_IRIs.default.rdf.type),
|
|
1024
1186
|
'=': factory.namedNode(_IRIs.default.owl.sameAs),
|
|
1025
|
-
'>': factory.namedNode(_IRIs.default.log.implies)
|
|
1026
|
-
'<': factory.namedNode(_IRIs.default.log.isImpliedBy)
|
|
1187
|
+
'>': factory.namedNode(_IRIs.default.log.implies)
|
|
1027
1188
|
};
|
|
1028
1189
|
parser.QUANTIFIERS_GRAPH = factory.namedNode('urn:n3:quantifiers');
|
|
1029
1190
|
}
|
|
1191
|
+
N3Parser.SUPPORTED_VERSIONS = ['1.2', '1.2-basic', '1.1'];
|
|
1030
1192
|
initDataFactory(N3Parser.prototype, _N3DataFactory.default);
|
package/lib/N3Store.js
CHANGED
|
@@ -10,7 +10,8 @@ var _IRIs = _interopRequireDefault(require("./IRIs"));
|
|
|
10
10
|
var _N3Util = require("./N3Util");
|
|
11
11
|
var _N3Writer = _interopRequireDefault(require("./N3Writer"));
|
|
12
12
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
-
function
|
|
13
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
14
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
14
15
|
// **N3Store** objects store N3 quads by graph in memory.
|
|
15
16
|
|
|
16
17
|
const ITERATOR = Symbol('iter');
|
|
@@ -146,7 +147,7 @@ class N3Store {
|
|
|
146
147
|
this._graphs = Object.create(null);
|
|
147
148
|
|
|
148
149
|
// Shift parameters if `quads` is not given
|
|
149
|
-
if (!options && quads && !quads[0]
|
|
150
|
+
if (!options && quads && !quads[0]) options = quads, quads = null;
|
|
150
151
|
options = options || {};
|
|
151
152
|
this._factory = options.factory || _N3DataFactory.default;
|
|
152
153
|
this._entityIndex = options.entityIndex || new N3EntityIndex({
|
|
@@ -158,7 +159,7 @@ class N3Store {
|
|
|
158
159
|
this._termToNewNumericId = this._entityIndex._termToNewNumericId.bind(this._entityIndex);
|
|
159
160
|
|
|
160
161
|
// Add quads if passed
|
|
161
|
-
if (quads) this.
|
|
162
|
+
if (quads) this.addQuads(quads);
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
// ## Public properties
|
|
@@ -578,7 +579,7 @@ class N3Store {
|
|
|
578
579
|
// and returns `true` if it returns truthy for any of them.
|
|
579
580
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
580
581
|
some(callback, subject, predicate, object, graph) {
|
|
581
|
-
for (const quad of this.readQuads(subject, predicate, object, graph)) if (callback(quad
|
|
582
|
+
for (const quad of this.readQuads(subject, predicate, object, graph)) if (callback(quad)) return true;
|
|
582
583
|
return false;
|
|
583
584
|
}
|
|
584
585
|
|
|
@@ -1082,28 +1083,26 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
1082
1083
|
if (subject && !(subjectId = newStore._termToNumericId(subject)) || predicate && !(predicateId = newStore._termToNumericId(predicate)) || object && !(objectId = newStore._termToNumericId(object))) return newStore;
|
|
1083
1084
|
const graphs = n3Store._getGraphs(graph);
|
|
1084
1085
|
for (const graphKey in graphs) {
|
|
1085
|
-
let subjects, predicates, objects
|
|
1086
|
-
if (
|
|
1087
|
-
if (
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId]);
|
|
1096
|
-
}
|
|
1097
|
-
} else if (subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId])) {
|
|
1098
|
-
predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId]);
|
|
1099
|
-
objects = indexMatch(content.objects, [objectId, subjectId, predicateId]);
|
|
1086
|
+
let subjects, predicates, objects;
|
|
1087
|
+
if (!subjectId && predicateId) {
|
|
1088
|
+
if (predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId])) {
|
|
1089
|
+
subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId]);
|
|
1090
|
+
objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId]);
|
|
1091
|
+
}
|
|
1092
|
+
} else if (objectId) {
|
|
1093
|
+
if (objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId])) {
|
|
1094
|
+
subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId]);
|
|
1095
|
+
predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId]);
|
|
1100
1096
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
objects
|
|
1105
|
-
};
|
|
1097
|
+
} else if (subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId])) {
|
|
1098
|
+
predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId]);
|
|
1099
|
+
objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId]);
|
|
1106
1100
|
}
|
|
1101
|
+
if (subjects) newStore._graphs[graphKey] = {
|
|
1102
|
+
subjects,
|
|
1103
|
+
predicates,
|
|
1104
|
+
objects
|
|
1105
|
+
};
|
|
1107
1106
|
}
|
|
1108
1107
|
newStore._size = null;
|
|
1109
1108
|
}
|
package/lib/N3Util.js
CHANGED
|
@@ -8,7 +8,6 @@ exports.isBlankNode = isBlankNode;
|
|
|
8
8
|
exports.isDefaultGraph = isDefaultGraph;
|
|
9
9
|
exports.isLiteral = isLiteral;
|
|
10
10
|
exports.isNamedNode = isNamedNode;
|
|
11
|
-
exports.isQuad = isQuad;
|
|
12
11
|
exports.isVariable = isVariable;
|
|
13
12
|
exports.prefix = prefix;
|
|
14
13
|
exports.prefixes = prefixes;
|
|
@@ -36,11 +35,6 @@ function isVariable(term) {
|
|
|
36
35
|
return !!term && term.termType === 'Variable';
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
// Tests whether the given term represents a quad
|
|
40
|
-
function isQuad(term) {
|
|
41
|
-
return !!term && term.termType === 'Quad';
|
|
42
|
-
}
|
|
43
|
-
|
|
44
38
|
// Tests whether the given term represents the default graph
|
|
45
39
|
function isDefaultGraph(term) {
|
|
46
40
|
return !!term && term.termType === 'DefaultGraph';
|
package/lib/N3Writer.js
CHANGED
|
@@ -7,9 +7,8 @@ exports.default = void 0;
|
|
|
7
7
|
var _IRIs = _interopRequireDefault(require("./IRIs"));
|
|
8
8
|
var _N3DataFactory = _interopRequireWildcard(require("./N3DataFactory"));
|
|
9
9
|
var _N3Util = require("./N3Util");
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
12
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
13
|
// **N3Writer** writes N3 documents.
|
|
15
14
|
|
|
@@ -78,7 +77,8 @@ class N3Writer {
|
|
|
78
77
|
this._prefixIRIs = Object.create(null);
|
|
79
78
|
options.prefixes && this.addPrefixes(options.prefixes);
|
|
80
79
|
if (options.baseIRI) {
|
|
81
|
-
this.
|
|
80
|
+
this._baseMatcher = new RegExp(`^${escapeRegex(options.baseIRI)}${options.baseIRI.endsWith('/') ? '' : '[#?]'}`);
|
|
81
|
+
this._baseLength = options.baseIRI.length;
|
|
82
82
|
}
|
|
83
83
|
} else {
|
|
84
84
|
this._lineMode = true;
|
|
@@ -156,9 +156,7 @@ class N3Writer {
|
|
|
156
156
|
}
|
|
157
157
|
let iri = entity.value;
|
|
158
158
|
// Use relative IRIs if requested and possible
|
|
159
|
-
if (this.
|
|
160
|
-
iri = this._baseIri.toRelative(iri);
|
|
161
|
-
}
|
|
159
|
+
if (this._baseMatcher && this._baseMatcher.test(iri)) iri = iri.substr(this._baseLength);
|
|
162
160
|
// Escape special characters
|
|
163
161
|
if (escape.test(iri)) iri = iri.replace(escapeAll, characterReplacer);
|
|
164
162
|
// Try to represent the IRI as prefixed name
|
|
@@ -173,7 +171,8 @@ class N3Writer {
|
|
|
173
171
|
if (escape.test(value)) value = value.replace(escapeAll, characterReplacer);
|
|
174
172
|
|
|
175
173
|
// Write a language-tagged literal
|
|
176
|
-
|
|
174
|
+
const direction = literal.direction ? `--${literal.direction}` : '';
|
|
175
|
+
if (literal.language) return `"${value}"@${literal.language}${direction}`;
|
|
177
176
|
|
|
178
177
|
// Write dedicated literals per data type
|
|
179
178
|
if (this._lineMode) {
|
|
@@ -285,7 +284,7 @@ class N3Writer {
|
|
|
285
284
|
IRIlist += IRIlist ? `|${prefixIRI}` : prefixIRI;
|
|
286
285
|
prefixList += (prefixList ? '|' : '') + this._prefixIRIs[prefixIRI];
|
|
287
286
|
}
|
|
288
|
-
IRIlist =
|
|
287
|
+
IRIlist = escapeRegex(IRIlist, /[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
|
|
289
288
|
this._prefixRegex = new RegExp(`^(?:${prefixList})[^\/]*$|` + `^(${IRIlist})([_a-zA-Z0-9][\\-_a-zA-Z0-9]*)$`);
|
|
290
289
|
}
|
|
291
290
|
// End a prefix block with a newline
|
|
@@ -381,4 +380,7 @@ function characterReplacer(character) {
|
|
|
381
380
|
}
|
|
382
381
|
}
|
|
383
382
|
return result;
|
|
383
|
+
}
|
|
384
|
+
function escapeRegex(regex) {
|
|
385
|
+
return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
|
|
384
386
|
}
|