n3 1.14.0 → 1.16.1
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 +7 -2
- package/browser/n3.min.js +1 -1
- package/lib/N3Lexer.js +25 -27
- package/lib/N3Parser.js +17 -15
- package/lib/N3Store.js +32 -70
- package/lib/N3Util.js +1 -1
- package/package.json +1 -1
- package/src/N3Lexer.js +20 -9
- package/src/N3Parser.js +17 -11
- package/src/N3Store.js +34 -88
- package/src/N3Util.js +1 -1
package/lib/N3Lexer.js
CHANGED
|
@@ -109,7 +109,7 @@ class N3Lexer {
|
|
|
109
109
|
_tokenizeToEnd(callback, inputFinished) {
|
|
110
110
|
// Continue parsing as far as possible; the loop will return eventually
|
|
111
111
|
let input = this._input;
|
|
112
|
-
|
|
112
|
+
let currentLineLength = input.length;
|
|
113
113
|
|
|
114
114
|
while (true) {
|
|
115
115
|
// Count and skip whitespace lines
|
|
@@ -117,14 +117,10 @@ class N3Lexer {
|
|
|
117
117
|
|
|
118
118
|
while (whiteSpaceMatch = this._newline.exec(input)) {
|
|
119
119
|
// Try to find a comment
|
|
120
|
-
if (
|
|
121
|
-
line: this._line,
|
|
122
|
-
type: 'comment',
|
|
123
|
-
value: comment[1],
|
|
124
|
-
prefix: ''
|
|
125
|
-
}); // Advance the input
|
|
120
|
+
if (this._comments && (comment = this._comment.exec(whiteSpaceMatch[0]))) emitToken('comment', comment[1], '', this._line, whiteSpaceMatch[0].length); // Advance the input
|
|
126
121
|
|
|
127
122
|
input = input.substr(whiteSpaceMatch[0].length, input.length);
|
|
123
|
+
currentLineLength = input.length;
|
|
128
124
|
this._line++;
|
|
129
125
|
} // Skip whitespace on current line
|
|
130
126
|
|
|
@@ -135,18 +131,9 @@ class N3Lexer {
|
|
|
135
131
|
// If the input is finished, emit EOF
|
|
136
132
|
if (inputFinished) {
|
|
137
133
|
// Try to find a final comment
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
value: comment[1],
|
|
142
|
-
prefix: ''
|
|
143
|
-
});
|
|
144
|
-
callback(input = null, {
|
|
145
|
-
line: this._line,
|
|
146
|
-
type: 'eof',
|
|
147
|
-
value: '',
|
|
148
|
-
prefix: ''
|
|
149
|
-
});
|
|
134
|
+
if (this._comments && (comment = this._comment.exec(input))) emitToken('comment', comment[1], '', this._line, input.length);
|
|
135
|
+
input = null;
|
|
136
|
+
emitToken('eof', '', '', this._line, 0);
|
|
150
137
|
}
|
|
151
138
|
|
|
152
139
|
return this._input = input;
|
|
@@ -376,17 +363,28 @@ class N3Lexer {
|
|
|
376
363
|
} // Emit the parsed token
|
|
377
364
|
|
|
378
365
|
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
type: type,
|
|
382
|
-
value: value,
|
|
383
|
-
prefix: prefix
|
|
384
|
-
};
|
|
385
|
-
callback(null, token);
|
|
366
|
+
const length = matchLength || match[0].length;
|
|
367
|
+
const token = emitToken(type, value, prefix, line, length);
|
|
386
368
|
this.previousToken = token;
|
|
387
369
|
this._previousMarker = type; // Advance to next part to tokenize
|
|
388
370
|
|
|
389
|
-
input = input.substr(
|
|
371
|
+
input = input.substr(length, input.length);
|
|
372
|
+
} // Emits the token through the callback
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
function emitToken(type, value, prefix, line, length) {
|
|
376
|
+
const start = input ? currentLineLength - input.length : currentLineLength;
|
|
377
|
+
const end = start + length;
|
|
378
|
+
const token = {
|
|
379
|
+
type,
|
|
380
|
+
value,
|
|
381
|
+
prefix,
|
|
382
|
+
line,
|
|
383
|
+
start,
|
|
384
|
+
end
|
|
385
|
+
};
|
|
386
|
+
callback(null, token);
|
|
387
|
+
return token;
|
|
390
388
|
} // Signals the syntax error through the callback
|
|
391
389
|
|
|
392
390
|
|
package/lib/N3Parser.js
CHANGED
|
@@ -83,11 +83,11 @@ class N3Parser {
|
|
|
83
83
|
const n3Mode = this._n3Mode;
|
|
84
84
|
|
|
85
85
|
this._contextStack.push({
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
type,
|
|
87
|
+
subject,
|
|
88
|
+
predicate,
|
|
89
|
+
object,
|
|
90
|
+
graph,
|
|
91
91
|
inverse: n3Mode ? this._inversePredicate : false,
|
|
92
92
|
blankPrefix: n3Mode ? this._prefixes._ : '',
|
|
93
93
|
quantified: n3Mode ? this._quantified : null
|
|
@@ -107,16 +107,18 @@ class N3Parser {
|
|
|
107
107
|
// when leaving a scope (list, blank node, formula)
|
|
108
108
|
|
|
109
109
|
|
|
110
|
-
_restoreContext() {
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
_restoreContext(type, token) {
|
|
111
|
+
// Obtain the previous context
|
|
112
|
+
const context = this._contextStack.pop();
|
|
113
|
+
|
|
114
|
+
if (!context || context.type !== type) return this._error(`Unexpected ${token.type}`, token); // Restore the quad of the previous context
|
|
113
115
|
|
|
114
116
|
this._subject = context.subject;
|
|
115
117
|
this._predicate = context.predicate;
|
|
116
118
|
this._object = context.object;
|
|
117
|
-
this._graph = context.graph; //
|
|
119
|
+
this._graph = context.graph; // Restore N3 context settings
|
|
118
120
|
|
|
119
|
-
if (
|
|
121
|
+
if (this._n3Mode) {
|
|
120
122
|
this._inversePredicate = context.inverse;
|
|
121
123
|
this._prefixes._ = context.blankPrefix;
|
|
122
124
|
this._quantified = context.quantified;
|
|
@@ -406,7 +408,7 @@ class N3Parser {
|
|
|
406
408
|
|
|
407
409
|
const empty = this._predicate === null;
|
|
408
410
|
|
|
409
|
-
this._restoreContext(); // If the blank node was the object, restore previous context and read punctuation
|
|
411
|
+
this._restoreContext('blank', token); // If the blank node was the object, restore previous context and read punctuation
|
|
410
412
|
|
|
411
413
|
|
|
412
414
|
if (this._object !== null) return this._getContextEndReader(); // If the blank node was the predicate, continue reading the object
|
|
@@ -460,7 +462,7 @@ class N3Parser {
|
|
|
460
462
|
|
|
461
463
|
case ')':
|
|
462
464
|
// Closing the list; restore the parent context
|
|
463
|
-
this._restoreContext(); // If this list is contained within a parent list, return the membership quad here.
|
|
465
|
+
this._restoreContext('list', token); // If this list is contained within a parent list, return the membership quad here.
|
|
464
466
|
// This will be `<parent list element> rdf:first <this list>.`.
|
|
465
467
|
|
|
466
468
|
|
|
@@ -606,7 +608,7 @@ class N3Parser {
|
|
|
606
608
|
|
|
607
609
|
if (this._subject !== null) this._emit(this._subject, this._predicate, this._object, this._graph); // Restore the parent context containing this formula
|
|
608
610
|
|
|
609
|
-
this._restoreContext(); // If the formula was the subject, continue reading the predicate.
|
|
611
|
+
this._restoreContext('formula', token); // If the formula was the subject, continue reading the predicate.
|
|
610
612
|
// If the formula was the object, read punctuation.
|
|
611
613
|
|
|
612
614
|
|
|
@@ -830,7 +832,7 @@ class N3Parser {
|
|
|
830
832
|
// The list item is the remaining subejct after reading the path
|
|
831
833
|
const item = this._subject; // Switch back to the context of the list
|
|
832
834
|
|
|
833
|
-
this._restoreContext(); // Output the list item
|
|
835
|
+
this._restoreContext('item', token); // Output the list item
|
|
834
836
|
|
|
835
837
|
|
|
836
838
|
this._emit(this._subject, this.RDF_FIRST, item, this._graph);
|
|
@@ -890,7 +892,7 @@ class N3Parser {
|
|
|
890
892
|
|
|
891
893
|
const quad = this._quad(this._subject, this._predicate, this._object, this._graph || this.DEFAULTGRAPH);
|
|
892
894
|
|
|
893
|
-
this._restoreContext(); // If the triple was the subject, continue by reading the predicate.
|
|
895
|
+
this._restoreContext('<<', token); // If the triple was the subject, continue by reading the predicate.
|
|
894
896
|
|
|
895
897
|
|
|
896
898
|
if (this._subject === null) {
|
package/lib/N3Store.js
CHANGED
|
@@ -92,17 +92,15 @@ class N3Store {
|
|
|
92
92
|
// `name0`, `name1`, and `name2` are the names of the keys at each level,
|
|
93
93
|
// used when reconstructing the resulting quad
|
|
94
94
|
// (for instance: _subject_, _predicate_, and _object_).
|
|
95
|
-
// Finally, `
|
|
96
|
-
// If `callback` is given, each result is passed through it
|
|
97
|
-
// and iteration halts when it returns truthy for any quad.
|
|
98
|
-
// If instead `array` is given, each result is added to the array.
|
|
95
|
+
// Finally, `graphId` will be the graph of the created quads.
|
|
99
96
|
|
|
100
97
|
|
|
101
|
-
_findInIndex(index0, key0, key1, key2, name0, name1, name2,
|
|
98
|
+
*_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
|
|
102
99
|
let tmp, index1, index2; // Depending on the number of variables, keys or reverse index are faster
|
|
103
100
|
|
|
104
101
|
const varCount = !key0 + !key1 + !key2,
|
|
105
|
-
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
|
|
102
|
+
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
|
|
103
|
+
const graph = (0, _N3DataFactory.termFromId)(graphId, this._factory); // If a key is specified, use only that part of index 0.
|
|
106
104
|
|
|
107
105
|
if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
|
|
108
106
|
|
|
@@ -129,17 +127,12 @@ class N3Store {
|
|
|
129
127
|
parts[name0] = (0, _N3DataFactory.termFromId)(entity0, this._factory);
|
|
130
128
|
parts[name1] = (0, _N3DataFactory.termFromId)(entity1, this._factory);
|
|
131
129
|
parts[name2] = (0, _N3DataFactory.termFromId)(entityKeys[values[l]], this._factory);
|
|
132
|
-
|
|
133
|
-
const quad = this._factory.quad(parts.subject, parts.predicate, parts.object, (0, _N3DataFactory.termFromId)(graph, this._factory));
|
|
134
|
-
|
|
135
|
-
if (array) array.push(quad);else if (callback(quad)) return true;
|
|
130
|
+
yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
}
|
|
139
134
|
}
|
|
140
135
|
}
|
|
141
|
-
|
|
142
|
-
return array;
|
|
143
136
|
} // ### `_loop` executes the callback on all keys of index 0
|
|
144
137
|
|
|
145
138
|
|
|
@@ -288,13 +281,17 @@ class N3Store {
|
|
|
288
281
|
delete(quad) {
|
|
289
282
|
this.removeQuad(quad);
|
|
290
283
|
return this;
|
|
291
|
-
} // ### `has` determines whether a dataset includes a certain quad.
|
|
292
|
-
// Returns true or false as appropriate.
|
|
284
|
+
} // ### `has` determines whether a dataset includes a certain quad or quad pattern.
|
|
293
285
|
|
|
294
286
|
|
|
295
|
-
has(
|
|
296
|
-
|
|
297
|
-
|
|
287
|
+
has(subjectOrQuad, predicate, object, graph) {
|
|
288
|
+
if (subjectOrQuad && subjectOrQuad.subject) ({
|
|
289
|
+
subject: subjectOrQuad,
|
|
290
|
+
predicate,
|
|
291
|
+
object,
|
|
292
|
+
graph
|
|
293
|
+
} = subjectOrQuad);
|
|
294
|
+
return !this.readQuads(subjectOrQuad, predicate, object, graph).next().done;
|
|
298
295
|
} // ### `import` adds a stream of quads to the store
|
|
299
296
|
|
|
300
297
|
|
|
@@ -356,7 +353,7 @@ class N3Store {
|
|
|
356
353
|
});
|
|
357
354
|
|
|
358
355
|
stream._read = () => {
|
|
359
|
-
for (const quad of this.
|
|
356
|
+
for (const quad of this.readQuads(subject, predicate, object, graph)) stream.push(quad);
|
|
360
357
|
|
|
361
358
|
stream.push(null);
|
|
362
359
|
};
|
|
@@ -372,19 +369,24 @@ class N3Store {
|
|
|
372
369
|
|
|
373
370
|
|
|
374
371
|
getQuads(subject, predicate, object, graph) {
|
|
372
|
+
return [...this.readQuads(subject, predicate, object, graph)];
|
|
373
|
+
} // ### `readQuads` returns an generator of quads matching a pattern.
|
|
374
|
+
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
*readQuads(subject, predicate, object, graph) {
|
|
375
378
|
// Convert terms to internal string representation
|
|
376
379
|
subject = subject && (0, _N3DataFactory.termToId)(subject);
|
|
377
380
|
predicate = predicate && (0, _N3DataFactory.termToId)(predicate);
|
|
378
381
|
object = object && (0, _N3DataFactory.termToId)(object);
|
|
379
382
|
graph = graph && (0, _N3DataFactory.termToId)(graph);
|
|
380
383
|
|
|
381
|
-
const
|
|
382
|
-
graphs = this._getGraphs(graph),
|
|
384
|
+
const graphs = this._getGraphs(graph),
|
|
383
385
|
ids = this._ids;
|
|
384
386
|
|
|
385
387
|
let content, subjectId, predicateId, objectId; // Translate IRIs to internal index keys.
|
|
386
388
|
|
|
387
|
-
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return
|
|
389
|
+
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return;
|
|
388
390
|
|
|
389
391
|
for (const graphId in graphs) {
|
|
390
392
|
// Only if the specified graph contains triples, there can be results
|
|
@@ -392,16 +394,14 @@ class N3Store {
|
|
|
392
394
|
// Choose the optimal index, based on what fields are present
|
|
393
395
|
if (subjectId) {
|
|
394
396
|
if (objectId) // If subject and object are given, the object index will be the fastest
|
|
395
|
-
this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, null,
|
|
396
|
-
this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, null,
|
|
397
|
+
yield* this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, null, true);else // If only subject and possibly predicate are given, the subject index will be the fastest
|
|
398
|
+
yield* this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, null, true);
|
|
397
399
|
} else if (predicateId) // If only predicate and possibly object are given, the predicate index will be the fastest
|
|
398
|
-
this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, null,
|
|
399
|
-
this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, null,
|
|
400
|
-
this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, null,
|
|
400
|
+
yield* this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, null, true);else if (objectId) // If only object is given, the object index will be the fastest
|
|
401
|
+
yield* this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, null, true);else // If nothing is given, iterate subjects and predicates first
|
|
402
|
+
yield* this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, null, true);
|
|
401
403
|
}
|
|
402
404
|
}
|
|
403
|
-
|
|
404
|
-
return quads;
|
|
405
405
|
} // ### `match` returns a new dataset that is comprised of all quads in the current instance matching the given arguments.
|
|
406
406
|
// The logic described in Quad Matching is applied for each quad in this dataset to check if it should be included in the output dataset.
|
|
407
407
|
// Note: This method always returns a new DatasetCore, even if that dataset contains no quads.
|
|
@@ -480,45 +480,7 @@ class N3Store {
|
|
|
480
480
|
|
|
481
481
|
|
|
482
482
|
some(callback, subject, predicate, object, graph) {
|
|
483
|
-
|
|
484
|
-
subject = subject && (0, _N3DataFactory.termToId)(subject);
|
|
485
|
-
predicate = predicate && (0, _N3DataFactory.termToId)(predicate);
|
|
486
|
-
object = object && (0, _N3DataFactory.termToId)(object);
|
|
487
|
-
graph = graph && (0, _N3DataFactory.termToId)(graph);
|
|
488
|
-
|
|
489
|
-
const graphs = this._getGraphs(graph),
|
|
490
|
-
ids = this._ids;
|
|
491
|
-
|
|
492
|
-
let content, subjectId, predicateId, objectId; // Translate IRIs to internal index keys.
|
|
493
|
-
|
|
494
|
-
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return false;
|
|
495
|
-
|
|
496
|
-
for (const graphId in graphs) {
|
|
497
|
-
// Only if the specified graph contains triples, there can be results
|
|
498
|
-
if (content = graphs[graphId]) {
|
|
499
|
-
// Choose the optimal index, based on what fields are present
|
|
500
|
-
if (subjectId) {
|
|
501
|
-
if (objectId) {
|
|
502
|
-
// If subject and object are given, the object index will be the fastest
|
|
503
|
-
if (this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, callback, null)) return true;
|
|
504
|
-
} else // If only subject and possibly predicate are given, the subject index will be the fastest
|
|
505
|
-
if (this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, callback, null)) return true;
|
|
506
|
-
} else if (predicateId) {
|
|
507
|
-
// If only predicate and possibly object are given, the predicate index will be the fastest
|
|
508
|
-
if (this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, callback, null)) {
|
|
509
|
-
return true;
|
|
510
|
-
}
|
|
511
|
-
} else if (objectId) {
|
|
512
|
-
// If only object is given, the object index will be the fastest
|
|
513
|
-
if (this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, callback, null)) {
|
|
514
|
-
return true;
|
|
515
|
-
}
|
|
516
|
-
} else // If nothing is given, iterate subjects and predicates first
|
|
517
|
-
if (this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, callback, null)) {
|
|
518
|
-
return true;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}
|
|
483
|
+
for (const quad of this.readQuads(subject, predicate, object, graph)) if (callback(quad)) return true;
|
|
522
484
|
|
|
523
485
|
return false;
|
|
524
486
|
} // ### `getSubjects` returns all subjects that match the pattern.
|
|
@@ -772,7 +734,7 @@ class N3Store {
|
|
|
772
734
|
|
|
773
735
|
|
|
774
736
|
*[Symbol.iterator]() {
|
|
775
|
-
yield* this.
|
|
737
|
+
yield* this.readQuads();
|
|
776
738
|
}
|
|
777
739
|
|
|
778
740
|
} // Determines whether the argument is a string
|
|
@@ -825,7 +787,7 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
825
787
|
}
|
|
826
788
|
|
|
827
789
|
_read() {
|
|
828
|
-
for (const quad of this
|
|
790
|
+
for (const quad of this) this.push(quad);
|
|
829
791
|
|
|
830
792
|
this.push(null);
|
|
831
793
|
}
|
|
@@ -847,7 +809,7 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
847
809
|
}
|
|
848
810
|
|
|
849
811
|
*[Symbol.iterator]() {
|
|
850
|
-
yield* this.
|
|
812
|
+
yield* this._filtered || this.n3Store.readQuads(this.subject, this.predicate, this.object, this.graph);
|
|
851
813
|
}
|
|
852
814
|
|
|
853
815
|
}
|
package/lib/N3Util.js
CHANGED
package/package.json
CHANGED
package/src/N3Lexer.js
CHANGED
|
@@ -78,16 +78,17 @@ export default class N3Lexer {
|
|
|
78
78
|
_tokenizeToEnd(callback, inputFinished) {
|
|
79
79
|
// Continue parsing as far as possible; the loop will return eventually
|
|
80
80
|
let input = this._input;
|
|
81
|
-
|
|
81
|
+
let currentLineLength = input.length;
|
|
82
82
|
while (true) {
|
|
83
83
|
// Count and skip whitespace lines
|
|
84
84
|
let whiteSpaceMatch, comment;
|
|
85
85
|
while (whiteSpaceMatch = this._newline.exec(input)) {
|
|
86
86
|
// Try to find a comment
|
|
87
|
-
if (
|
|
88
|
-
|
|
87
|
+
if (this._comments && (comment = this._comment.exec(whiteSpaceMatch[0])))
|
|
88
|
+
emitToken('comment', comment[1], '', this._line, whiteSpaceMatch[0].length);
|
|
89
89
|
// Advance the input
|
|
90
90
|
input = input.substr(whiteSpaceMatch[0].length, input.length);
|
|
91
|
+
currentLineLength = input.length;
|
|
91
92
|
this._line++;
|
|
92
93
|
}
|
|
93
94
|
// Skip whitespace on current line
|
|
@@ -99,9 +100,10 @@ export default class N3Lexer {
|
|
|
99
100
|
// If the input is finished, emit EOF
|
|
100
101
|
if (inputFinished) {
|
|
101
102
|
// Try to find a final comment
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
if (this._comments && (comment = this._comment.exec(input)))
|
|
104
|
+
emitToken('comment', comment[1], '', this._line, input.length);
|
|
105
|
+
input = null;
|
|
106
|
+
emitToken('eof', '', '', this._line, 0);
|
|
105
107
|
}
|
|
106
108
|
return this._input = input;
|
|
107
109
|
}
|
|
@@ -345,14 +347,23 @@ export default class N3Lexer {
|
|
|
345
347
|
}
|
|
346
348
|
|
|
347
349
|
// Emit the parsed token
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
+
const length = matchLength || match[0].length;
|
|
351
|
+
const token = emitToken(type, value, prefix, line, length);
|
|
350
352
|
this.previousToken = token;
|
|
351
353
|
this._previousMarker = type;
|
|
354
|
+
|
|
352
355
|
// Advance to next part to tokenize
|
|
353
|
-
input = input.substr(
|
|
356
|
+
input = input.substr(length, input.length);
|
|
354
357
|
}
|
|
355
358
|
|
|
359
|
+
// Emits the token through the callback
|
|
360
|
+
function emitToken(type, value, prefix, line, length) {
|
|
361
|
+
const start = input ? currentLineLength - input.length : currentLineLength;
|
|
362
|
+
const end = start + length;
|
|
363
|
+
const token = { type, value, prefix, line, start, end };
|
|
364
|
+
callback(null, token);
|
|
365
|
+
return token;
|
|
366
|
+
}
|
|
356
367
|
// Signals the syntax error through the callback
|
|
357
368
|
function reportSyntaxError(self) { callback(self._syntaxError(/^\S*/.exec(input)[0])); }
|
|
358
369
|
}
|
package/src/N3Parser.js
CHANGED
|
@@ -74,8 +74,8 @@ export default class N3Parser {
|
|
|
74
74
|
_saveContext(type, graph, subject, predicate, object) {
|
|
75
75
|
const n3Mode = this._n3Mode;
|
|
76
76
|
this._contextStack.push({
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
type,
|
|
78
|
+
subject, predicate, object, graph,
|
|
79
79
|
inverse: n3Mode ? this._inversePredicate : false,
|
|
80
80
|
blankPrefix: n3Mode ? this._prefixes._ : '',
|
|
81
81
|
quantified: n3Mode ? this._quantified : null,
|
|
@@ -94,14 +94,20 @@ export default class N3Parser {
|
|
|
94
94
|
|
|
95
95
|
// ### `_restoreContext` restores the parent context
|
|
96
96
|
// when leaving a scope (list, blank node, formula)
|
|
97
|
-
_restoreContext() {
|
|
98
|
-
|
|
97
|
+
_restoreContext(type, token) {
|
|
98
|
+
// Obtain the previous context
|
|
99
|
+
const context = this._contextStack.pop();
|
|
100
|
+
if (!context || context.type !== type)
|
|
101
|
+
return this._error(`Unexpected ${token.type}`, token);
|
|
102
|
+
|
|
103
|
+
// Restore the quad of the previous context
|
|
99
104
|
this._subject = context.subject;
|
|
100
105
|
this._predicate = context.predicate;
|
|
101
106
|
this._object = context.object;
|
|
102
107
|
this._graph = context.graph;
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
|
|
109
|
+
// Restore N3 context settings
|
|
110
|
+
if (this._n3Mode) {
|
|
105
111
|
this._inversePredicate = context.inverse;
|
|
106
112
|
this._prefixes._ = context.blankPrefix;
|
|
107
113
|
this._quantified = context.quantified;
|
|
@@ -374,7 +380,7 @@ export default class N3Parser {
|
|
|
374
380
|
|
|
375
381
|
// Restore the parent context containing this blank node
|
|
376
382
|
const empty = this._predicate === null;
|
|
377
|
-
this._restoreContext();
|
|
383
|
+
this._restoreContext('blank', token);
|
|
378
384
|
// If the blank node was the object, restore previous context and read punctuation
|
|
379
385
|
if (this._object !== null)
|
|
380
386
|
return this._getContextEndReader();
|
|
@@ -425,7 +431,7 @@ export default class N3Parser {
|
|
|
425
431
|
break;
|
|
426
432
|
case ')':
|
|
427
433
|
// Closing the list; restore the parent context
|
|
428
|
-
this._restoreContext();
|
|
434
|
+
this._restoreContext('list', token);
|
|
429
435
|
// If this list is contained within a parent list, return the membership quad here.
|
|
430
436
|
// This will be `<parent list element> rdf:first <this list>.`.
|
|
431
437
|
if (stack.length !== 0 && stack[stack.length - 1].type === 'list')
|
|
@@ -576,7 +582,7 @@ export default class N3Parser {
|
|
|
576
582
|
this._emit(this._subject, this._predicate, this._object, this._graph);
|
|
577
583
|
|
|
578
584
|
// Restore the parent context containing this formula
|
|
579
|
-
this._restoreContext();
|
|
585
|
+
this._restoreContext('formula', token);
|
|
580
586
|
// If the formula was the subject, continue reading the predicate.
|
|
581
587
|
// If the formula was the object, read punctuation.
|
|
582
588
|
return this._object === null ? this._readPredicate : this._getContextEndReader();
|
|
@@ -785,7 +791,7 @@ export default class N3Parser {
|
|
|
785
791
|
// The list item is the remaining subejct after reading the path
|
|
786
792
|
const item = this._subject;
|
|
787
793
|
// Switch back to the context of the list
|
|
788
|
-
this._restoreContext();
|
|
794
|
+
this._restoreContext('item', token);
|
|
789
795
|
// Output the list item
|
|
790
796
|
this._emit(this._subject, this.RDF_FIRST, item, this._graph);
|
|
791
797
|
}
|
|
@@ -847,7 +853,7 @@ export default class N3Parser {
|
|
|
847
853
|
// Read the quad and restore the previous context
|
|
848
854
|
const quad = this._quad(this._subject, this._predicate, this._object,
|
|
849
855
|
this._graph || this.DEFAULTGRAPH);
|
|
850
|
-
this._restoreContext();
|
|
856
|
+
this._restoreContext('<<', token);
|
|
851
857
|
// If the triple was the subject, continue by reading the predicate.
|
|
852
858
|
if (this._subject === null) {
|
|
853
859
|
this._subject = quad;
|