n3 2.10.3 → 2.10.4
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/browser/n3.esm.min.js +4 -4
- package/browser/n3.min.js +4 -4
- package/lib/N3Parser.js +95 -64
- package/package.json +1 -1
- package/src/N3Parser.js +97 -70
package/lib/N3Parser.js
CHANGED
|
@@ -368,10 +368,14 @@ class N3Parser {
|
|
|
368
368
|
case 'inversePredicate':
|
|
369
369
|
this._inversePredicate = true;
|
|
370
370
|
return this._readPredicateAfterVerb;
|
|
371
|
+
case '|}':
|
|
372
|
+
// Expected predicate didn't come, must have been trailing semicolon
|
|
373
|
+
// or an empty annotation block
|
|
374
|
+
this._subject = null;
|
|
375
|
+
return this._readAnnotationBlockPunctuation(token);
|
|
371
376
|
case '.':
|
|
372
377
|
case ']':
|
|
373
378
|
case '}':
|
|
374
|
-
case '|}':
|
|
375
379
|
// Expected predicate didn't come, must have been trailing semicolon.
|
|
376
380
|
// In N3 mode, a subject (such as a path) can be a statement by itself.
|
|
377
381
|
if (this._predicate === null && !this._n3Mode) return this._error(`Unexpected ${type}`, token);
|
|
@@ -876,8 +880,7 @@ class N3Parser {
|
|
|
876
880
|
// ### `_readPunctuation` reads punctuation between quads or quad parts
|
|
877
881
|
_readPunctuation(token) {
|
|
878
882
|
let next,
|
|
879
|
-
graph = this._graph
|
|
880
|
-
startingAnnotation = false;
|
|
883
|
+
graph = this._graph;
|
|
881
884
|
const subject = this._subject,
|
|
882
885
|
inversePredicate = this._inversePredicate;
|
|
883
886
|
switch (token.type) {
|
|
@@ -902,34 +905,13 @@ class N3Parser {
|
|
|
902
905
|
case ',':
|
|
903
906
|
next = this._readObject;
|
|
904
907
|
break;
|
|
905
|
-
//
|
|
908
|
+
// A reifier or annotation block annotates the triple just read
|
|
906
909
|
case '~':
|
|
907
|
-
// Only invalidate the cache for a genuinely new triple - chained annotation blocks on the
|
|
908
|
-
// same triple (subject already null from a preceding annotation) must keep reusing it.
|
|
909
|
-
if (subject !== null) this._tripleTerm = null;
|
|
910
|
-
next = this._readReifierInAnnotation;
|
|
911
|
-
startingAnnotation = true;
|
|
912
|
-
break;
|
|
913
|
-
// {| means that the current triple is annotated with predicate-object pairs.
|
|
914
910
|
case '{|':
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (subject !== null) this._tripleTerm = null;
|
|
918
|
-
this._subject = this._readTripleTerm();
|
|
919
|
-
this._inversePredicate = false;
|
|
920
|
-
this._validAnnotation = false;
|
|
921
|
-
startingAnnotation = true;
|
|
922
|
-
next = this._readPredicate;
|
|
923
|
-
break;
|
|
924
|
-
// |} means that the current reified triple in annotation syntax is finalized.
|
|
911
|
+
return this._readAnnotationStart(token);
|
|
912
|
+
// An annotation block can only be closed from within one
|
|
925
913
|
case '|}':
|
|
926
|
-
|
|
927
|
-
if (!this._validAnnotation) return this._error('Annotation block can not be empty', token);
|
|
928
|
-
this._subject = null;
|
|
929
|
-
this._annotation = false;
|
|
930
|
-
this._inversePredicate = false;
|
|
931
|
-
next = this._getContextEndReader();
|
|
932
|
-
break;
|
|
914
|
+
return this._error('Unexpected annotation syntax closing', token);
|
|
933
915
|
default:
|
|
934
916
|
// An entity means this is a quad (only allowed if not already inside a graph)
|
|
935
917
|
if (this._supportsQuads && this._graph === null && (graph = this._readEntity(token)) !== undefined) {
|
|
@@ -939,14 +921,11 @@ class N3Parser {
|
|
|
939
921
|
return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
|
|
940
922
|
}
|
|
941
923
|
// A quad has been completed now, so return it
|
|
942
|
-
if (subject !== null
|
|
924
|
+
if (subject !== null) {
|
|
943
925
|
const predicate = this._predicate,
|
|
944
926
|
object = this._object;
|
|
945
927
|
this._emit(subject, predicate, object, graph, inversePredicate);
|
|
946
928
|
}
|
|
947
|
-
if (startingAnnotation) {
|
|
948
|
-
this._annotation = true;
|
|
949
|
-
}
|
|
950
929
|
return next;
|
|
951
930
|
}
|
|
952
931
|
|
|
@@ -965,19 +944,15 @@ class N3Parser {
|
|
|
965
944
|
next = this._readObject;
|
|
966
945
|
break;
|
|
967
946
|
// Annotation syntax applies to the quad just read, exactly as it does
|
|
968
|
-
// outside of a blank node property list
|
|
969
|
-
// the objects inside the annotation block are themselves read within the
|
|
970
|
-
// enclosing blank node context.
|
|
947
|
+
// outside of a blank node property list
|
|
971
948
|
case '~':
|
|
972
949
|
case '{|':
|
|
950
|
+
return this._readAnnotationStart(token);
|
|
973
951
|
case '|}':
|
|
974
|
-
return this.
|
|
952
|
+
return this._error('Unexpected annotation syntax closing', token);
|
|
975
953
|
default:
|
|
976
954
|
return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
|
|
977
955
|
}
|
|
978
|
-
// An annotation block consumes the subject it annotates, so there is
|
|
979
|
-
// nothing left to share with a following predicate-object pair
|
|
980
|
-
if (this._subject === null) return this._error('Expected ] to follow annotation', token);
|
|
981
956
|
// A quad has been completed now, so return it
|
|
982
957
|
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
983
958
|
if (resetInversePredicate) this._inversePredicate = false;
|
|
@@ -1247,32 +1222,27 @@ class N3Parser {
|
|
|
1247
1222
|
return this._readReifiedTripleTail;
|
|
1248
1223
|
}
|
|
1249
1224
|
|
|
1250
|
-
// ### `
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
// Otherwise, emit and assert triple term.
|
|
1258
|
-
this._readTripleTerm();
|
|
1259
|
-
this._subject = null;
|
|
1260
|
-
return this._getContextEndReader().call(this, token);
|
|
1225
|
+
// ### `_readAnnotationStart` reads the first reifier or annotation block after an object,
|
|
1226
|
+
// which completes the annotated quad
|
|
1227
|
+
_readAnnotationStart(token) {
|
|
1228
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
1229
|
+
// A new triple is annotated, so its triple term cannot be reused
|
|
1230
|
+
this._tripleTerm = null;
|
|
1231
|
+
return this._readAnnotation(token);
|
|
1261
1232
|
}
|
|
1262
1233
|
|
|
1263
|
-
// ### `
|
|
1264
|
-
//
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
//
|
|
1234
|
+
// ### `_readAnnotation` reads what follows an annotated quad:
|
|
1235
|
+
// further reifiers or annotation blocks for that same quad, or punctuation
|
|
1236
|
+
_readAnnotation(token) {
|
|
1237
|
+
switch (token.type) {
|
|
1238
|
+
case '~':
|
|
1239
|
+
return this._readReifierInAnnotation;
|
|
1240
|
+
case '{|':
|
|
1241
|
+
return this._readAnnotationBlockHead(token);
|
|
1242
|
+
}
|
|
1243
|
+
// The annotated quad was already emitted when its annotation started,
|
|
1244
|
+
// so continue without emitting it a second time
|
|
1273
1245
|
this._tripleTerm = null;
|
|
1274
|
-
// The annotated triple was already emitted when the tilde was read,
|
|
1275
|
-
// so continue without letting `_readPunctuation` emit it a second time.
|
|
1276
1246
|
switch (token.type) {
|
|
1277
1247
|
// The subject stays shared with the next predicate-object pair
|
|
1278
1248
|
case ';':
|
|
@@ -1283,11 +1253,70 @@ class N3Parser {
|
|
|
1283
1253
|
return this._readObject;
|
|
1284
1254
|
default:
|
|
1285
1255
|
this._subject = null;
|
|
1286
|
-
// Resume in the enclosing context
|
|
1287
|
-
// unless the reified triple sits inside a blank node property list
|
|
1256
|
+
// Resume in the enclosing context
|
|
1288
1257
|
return this._getContextEndReader().call(this, token);
|
|
1289
1258
|
}
|
|
1290
1259
|
}
|
|
1260
|
+
|
|
1261
|
+
// ### `_readReifierInAnnotation` reads the optional reifier after a tilde in annotation syntax
|
|
1262
|
+
_readReifierInAnnotation(token) {
|
|
1263
|
+
switch (token.type) {
|
|
1264
|
+
case 'IRI':
|
|
1265
|
+
case 'typeIRI':
|
|
1266
|
+
case 'type':
|
|
1267
|
+
case 'prefixed':
|
|
1268
|
+
case 'blank':
|
|
1269
|
+
case 'var':
|
|
1270
|
+
this._reifier = this._readEntity(token);
|
|
1271
|
+
return this._readAnnotationBlockOrReifier;
|
|
1272
|
+
}
|
|
1273
|
+
// Without an identifier, the reifier is a fresh blank node
|
|
1274
|
+
this._reifier = this._factory.blankNode();
|
|
1275
|
+
return this._readAnnotationBlockOrReifier(token);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// ### `_readAnnotationBlockOrReifier` reads what follows a reifier:
|
|
1279
|
+
// either an annotation block, which uses the reifier as its subject,
|
|
1280
|
+
// or anything else, in which case the reifier stands alone
|
|
1281
|
+
_readAnnotationBlockOrReifier(token) {
|
|
1282
|
+
if (token.type === '{|') return this._readAnnotationBlockHead(token);
|
|
1283
|
+
this._readTripleTerm();
|
|
1284
|
+
return this._readAnnotation(token);
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// ### `_readAnnotationBlockHead` opens an annotation block,
|
|
1288
|
+
// whose predicate-object pairs describe the reifier of the annotated quad
|
|
1289
|
+
_readAnnotationBlockHead(token) {
|
|
1290
|
+
const reifier = this._readTripleTerm();
|
|
1291
|
+
this._saveContext('annotation', this._graph, this._subject, this._predicate, this._object);
|
|
1292
|
+
// Restored when the block closes, so further annotations reuse the same triple term
|
|
1293
|
+
this._contextStack[this._contextStack.length - 1].tripleTerm = this._tripleTerm;
|
|
1294
|
+
this._subject = reifier;
|
|
1295
|
+
this._predicate = this._object = this._tripleTerm = null;
|
|
1296
|
+
this._inversePredicate = false;
|
|
1297
|
+
this._validAnnotation = false;
|
|
1298
|
+
return this._readPredicate;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// ### `_readAnnotationBlockPunctuation` reads punctuation inside an annotation block
|
|
1302
|
+
_readAnnotationBlockPunctuation(token) {
|
|
1303
|
+
const stack = this._contextStack;
|
|
1304
|
+
if (token.type === '|}') {
|
|
1305
|
+
if (!stack.length || stack[stack.length - 1].type !== 'annotation') return this._error('Unexpected annotation syntax closing', token);
|
|
1306
|
+
if (!this._validAnnotation) return this._error('Annotation block can not be empty', token);
|
|
1307
|
+
// Emit the last quad of the block, unless a trailing semicolon already did
|
|
1308
|
+
if (this._subject !== null) this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
1309
|
+
// Return to the annotated quad, which can be followed by more annotations
|
|
1310
|
+
const {
|
|
1311
|
+
tripleTerm
|
|
1312
|
+
} = stack[stack.length - 1];
|
|
1313
|
+
this._restoreContext('annotation', token);
|
|
1314
|
+
this._tripleTerm = tripleTerm;
|
|
1315
|
+
return this._readAnnotation;
|
|
1316
|
+
}
|
|
1317
|
+
// Otherwise, punctuation inside a block works like inside a blank node property list
|
|
1318
|
+
return this._readBlankNodePunctuation(token);
|
|
1319
|
+
}
|
|
1291
1320
|
_readTripleTerm() {
|
|
1292
1321
|
const stack = this._contextStack,
|
|
1293
1322
|
parent = stack.length && stack[stack.length - 1];
|
|
@@ -1314,6 +1343,8 @@ class N3Parser {
|
|
|
1314
1343
|
return this._readTripleTermTail;
|
|
1315
1344
|
case '<<':
|
|
1316
1345
|
return this._readReifiedTripleTailOrReifier;
|
|
1346
|
+
case 'annotation':
|
|
1347
|
+
return this._readAnnotationBlockPunctuation;
|
|
1317
1348
|
}
|
|
1318
1349
|
}
|
|
1319
1350
|
|
package/package.json
CHANGED
package/src/N3Parser.js
CHANGED
|
@@ -371,10 +371,14 @@ export default class N3Parser {
|
|
|
371
371
|
case 'inversePredicate':
|
|
372
372
|
this._inversePredicate = true;
|
|
373
373
|
return this._readPredicateAfterVerb;
|
|
374
|
+
case '|}':
|
|
375
|
+
// Expected predicate didn't come, must have been trailing semicolon
|
|
376
|
+
// or an empty annotation block
|
|
377
|
+
this._subject = null;
|
|
378
|
+
return this._readAnnotationBlockPunctuation(token);
|
|
374
379
|
case '.':
|
|
375
380
|
case ']':
|
|
376
381
|
case '}':
|
|
377
|
-
case '|}':
|
|
378
382
|
// Expected predicate didn't come, must have been trailing semicolon.
|
|
379
383
|
// In N3 mode, a subject (such as a path) can be a statement by itself.
|
|
380
384
|
if (this._predicate === null && !this._n3Mode)
|
|
@@ -952,7 +956,7 @@ export default class N3Parser {
|
|
|
952
956
|
|
|
953
957
|
// ### `_readPunctuation` reads punctuation between quads or quad parts
|
|
954
958
|
_readPunctuation(token) {
|
|
955
|
-
let next, graph = this._graph
|
|
959
|
+
let next, graph = this._graph;
|
|
956
960
|
const subject = this._subject, inversePredicate = this._inversePredicate;
|
|
957
961
|
switch (token.type) {
|
|
958
962
|
// A closing brace ends a graph
|
|
@@ -978,38 +982,13 @@ export default class N3Parser {
|
|
|
978
982
|
case ',':
|
|
979
983
|
next = this._readObject;
|
|
980
984
|
break;
|
|
981
|
-
//
|
|
985
|
+
// A reifier or annotation block annotates the triple just read
|
|
982
986
|
case '~':
|
|
983
|
-
// Only invalidate the cache for a genuinely new triple - chained annotation blocks on the
|
|
984
|
-
// same triple (subject already null from a preceding annotation) must keep reusing it.
|
|
985
|
-
if (subject !== null)
|
|
986
|
-
this._tripleTerm = null;
|
|
987
|
-
next = this._readReifierInAnnotation;
|
|
988
|
-
startingAnnotation = true;
|
|
989
|
-
break;
|
|
990
|
-
// {| means that the current triple is annotated with predicate-object pairs.
|
|
991
987
|
case '{|':
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
if (subject !== null)
|
|
995
|
-
this._tripleTerm = null;
|
|
996
|
-
this._subject = this._readTripleTerm();
|
|
997
|
-
this._inversePredicate = false;
|
|
998
|
-
this._validAnnotation = false;
|
|
999
|
-
startingAnnotation = true;
|
|
1000
|
-
next = this._readPredicate;
|
|
1001
|
-
break;
|
|
1002
|
-
// |} means that the current reified triple in annotation syntax is finalized.
|
|
988
|
+
return this._readAnnotationStart(token);
|
|
989
|
+
// An annotation block can only be closed from within one
|
|
1003
990
|
case '|}':
|
|
1004
|
-
|
|
1005
|
-
return this._error('Unexpected annotation syntax closing', token);
|
|
1006
|
-
if (!this._validAnnotation)
|
|
1007
|
-
return this._error('Annotation block can not be empty', token);
|
|
1008
|
-
this._subject = null;
|
|
1009
|
-
this._annotation = false;
|
|
1010
|
-
this._inversePredicate = false;
|
|
1011
|
-
next = this._getContextEndReader();
|
|
1012
|
-
break;
|
|
991
|
+
return this._error('Unexpected annotation syntax closing', token);
|
|
1013
992
|
default:
|
|
1014
993
|
// An entity means this is a quad (only allowed if not already inside a graph)
|
|
1015
994
|
if (this._supportsQuads && this._graph === null && (graph = this._readEntity(token)) !== undefined) {
|
|
@@ -1019,13 +998,10 @@ export default class N3Parser {
|
|
|
1019
998
|
return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
|
|
1020
999
|
}
|
|
1021
1000
|
// A quad has been completed now, so return it
|
|
1022
|
-
if (subject !== null
|
|
1001
|
+
if (subject !== null) {
|
|
1023
1002
|
const predicate = this._predicate, object = this._object;
|
|
1024
1003
|
this._emit(subject, predicate, object, graph, inversePredicate);
|
|
1025
1004
|
}
|
|
1026
|
-
if (startingAnnotation) {
|
|
1027
|
-
this._annotation = true;
|
|
1028
|
-
}
|
|
1029
1005
|
return next;
|
|
1030
1006
|
}
|
|
1031
1007
|
|
|
@@ -1043,20 +1019,15 @@ export default class N3Parser {
|
|
|
1043
1019
|
next = this._readObject;
|
|
1044
1020
|
break;
|
|
1045
1021
|
// Annotation syntax applies to the quad just read, exactly as it does
|
|
1046
|
-
// outside of a blank node property list
|
|
1047
|
-
// the objects inside the annotation block are themselves read within the
|
|
1048
|
-
// enclosing blank node context.
|
|
1022
|
+
// outside of a blank node property list
|
|
1049
1023
|
case '~':
|
|
1050
1024
|
case '{|':
|
|
1025
|
+
return this._readAnnotationStart(token);
|
|
1051
1026
|
case '|}':
|
|
1052
|
-
return this.
|
|
1027
|
+
return this._error('Unexpected annotation syntax closing', token);
|
|
1053
1028
|
default:
|
|
1054
1029
|
return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
|
|
1055
1030
|
}
|
|
1056
|
-
// An annotation block consumes the subject it annotates, so there is
|
|
1057
|
-
// nothing left to share with a following predicate-object pair
|
|
1058
|
-
if (this._subject === null)
|
|
1059
|
-
return this._error('Expected ] to follow annotation', token);
|
|
1060
1031
|
// A quad has been completed now, so return it
|
|
1061
1032
|
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
1062
1033
|
if (resetInversePredicate)
|
|
@@ -1356,34 +1327,27 @@ export default class N3Parser {
|
|
|
1356
1327
|
return this._readReifiedTripleTail;
|
|
1357
1328
|
}
|
|
1358
1329
|
|
|
1359
|
-
// ### `
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
// Otherwise, emit and assert triple term.
|
|
1367
|
-
this._readTripleTerm();
|
|
1368
|
-
this._subject = null;
|
|
1369
|
-
return this._getContextEndReader().call(this, token);
|
|
1330
|
+
// ### `_readAnnotationStart` reads the first reifier or annotation block after an object,
|
|
1331
|
+
// which completes the annotated quad
|
|
1332
|
+
_readAnnotationStart(token) {
|
|
1333
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
1334
|
+
// A new triple is annotated, so its triple term cannot be reused
|
|
1335
|
+
this._tripleTerm = null;
|
|
1336
|
+
return this._readAnnotation(token);
|
|
1370
1337
|
}
|
|
1371
1338
|
|
|
1372
|
-
// ### `
|
|
1373
|
-
//
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
//
|
|
1383
|
-
// so the term just asserted must not be reused for the next one.
|
|
1339
|
+
// ### `_readAnnotation` reads what follows an annotated quad:
|
|
1340
|
+
// further reifiers or annotation blocks for that same quad, or punctuation
|
|
1341
|
+
_readAnnotation(token) {
|
|
1342
|
+
switch (token.type) {
|
|
1343
|
+
case '~':
|
|
1344
|
+
return this._readReifierInAnnotation;
|
|
1345
|
+
case '{|':
|
|
1346
|
+
return this._readAnnotationBlockHead(token);
|
|
1347
|
+
}
|
|
1348
|
+
// The annotated quad was already emitted when its annotation started,
|
|
1349
|
+
// so continue without emitting it a second time
|
|
1384
1350
|
this._tripleTerm = null;
|
|
1385
|
-
// The annotated triple was already emitted when the tilde was read,
|
|
1386
|
-
// so continue without letting `_readPunctuation` emit it a second time.
|
|
1387
1351
|
switch (token.type) {
|
|
1388
1352
|
// The subject stays shared with the next predicate-object pair
|
|
1389
1353
|
case ';':
|
|
@@ -1394,12 +1358,73 @@ export default class N3Parser {
|
|
|
1394
1358
|
return this._readObject;
|
|
1395
1359
|
default:
|
|
1396
1360
|
this._subject = null;
|
|
1397
|
-
// Resume in the enclosing context
|
|
1398
|
-
// unless the reified triple sits inside a blank node property list
|
|
1361
|
+
// Resume in the enclosing context
|
|
1399
1362
|
return this._getContextEndReader().call(this, token);
|
|
1400
1363
|
}
|
|
1401
1364
|
}
|
|
1402
1365
|
|
|
1366
|
+
// ### `_readReifierInAnnotation` reads the optional reifier after a tilde in annotation syntax
|
|
1367
|
+
_readReifierInAnnotation(token) {
|
|
1368
|
+
switch (token.type) {
|
|
1369
|
+
case 'IRI':
|
|
1370
|
+
case 'typeIRI':
|
|
1371
|
+
case 'type':
|
|
1372
|
+
case 'prefixed':
|
|
1373
|
+
case 'blank':
|
|
1374
|
+
case 'var':
|
|
1375
|
+
this._reifier = this._readEntity(token);
|
|
1376
|
+
return this._readAnnotationBlockOrReifier;
|
|
1377
|
+
}
|
|
1378
|
+
// Without an identifier, the reifier is a fresh blank node
|
|
1379
|
+
this._reifier = this._factory.blankNode();
|
|
1380
|
+
return this._readAnnotationBlockOrReifier(token);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// ### `_readAnnotationBlockOrReifier` reads what follows a reifier:
|
|
1384
|
+
// either an annotation block, which uses the reifier as its subject,
|
|
1385
|
+
// or anything else, in which case the reifier stands alone
|
|
1386
|
+
_readAnnotationBlockOrReifier(token) {
|
|
1387
|
+
if (token.type === '{|')
|
|
1388
|
+
return this._readAnnotationBlockHead(token);
|
|
1389
|
+
this._readTripleTerm();
|
|
1390
|
+
return this._readAnnotation(token);
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
// ### `_readAnnotationBlockHead` opens an annotation block,
|
|
1394
|
+
// whose predicate-object pairs describe the reifier of the annotated quad
|
|
1395
|
+
_readAnnotationBlockHead(token) {
|
|
1396
|
+
const reifier = this._readTripleTerm();
|
|
1397
|
+
this._saveContext('annotation', this._graph, this._subject, this._predicate, this._object);
|
|
1398
|
+
// Restored when the block closes, so further annotations reuse the same triple term
|
|
1399
|
+
this._contextStack[this._contextStack.length - 1].tripleTerm = this._tripleTerm;
|
|
1400
|
+
this._subject = reifier;
|
|
1401
|
+
this._predicate = this._object = this._tripleTerm = null;
|
|
1402
|
+
this._inversePredicate = false;
|
|
1403
|
+
this._validAnnotation = false;
|
|
1404
|
+
return this._readPredicate;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// ### `_readAnnotationBlockPunctuation` reads punctuation inside an annotation block
|
|
1408
|
+
_readAnnotationBlockPunctuation(token) {
|
|
1409
|
+
const stack = this._contextStack;
|
|
1410
|
+
if (token.type === '|}') {
|
|
1411
|
+
if (!stack.length || stack[stack.length - 1].type !== 'annotation')
|
|
1412
|
+
return this._error('Unexpected annotation syntax closing', token);
|
|
1413
|
+
if (!this._validAnnotation)
|
|
1414
|
+
return this._error('Annotation block can not be empty', token);
|
|
1415
|
+
// Emit the last quad of the block, unless a trailing semicolon already did
|
|
1416
|
+
if (this._subject !== null)
|
|
1417
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
1418
|
+
// Return to the annotated quad, which can be followed by more annotations
|
|
1419
|
+
const { tripleTerm } = stack[stack.length - 1];
|
|
1420
|
+
this._restoreContext('annotation', token);
|
|
1421
|
+
this._tripleTerm = tripleTerm;
|
|
1422
|
+
return this._readAnnotation;
|
|
1423
|
+
}
|
|
1424
|
+
// Otherwise, punctuation inside a block works like inside a blank node property list
|
|
1425
|
+
return this._readBlankNodePunctuation(token);
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1403
1428
|
_readTripleTerm() {
|
|
1404
1429
|
const stack = this._contextStack, parent = stack.length && stack[stack.length - 1];
|
|
1405
1430
|
const parentGraph = parent ? parent.graph : undefined;
|
|
@@ -1429,6 +1454,8 @@ export default class N3Parser {
|
|
|
1429
1454
|
return this._readTripleTermTail;
|
|
1430
1455
|
case '<<':
|
|
1431
1456
|
return this._readReifiedTripleTailOrReifier;
|
|
1457
|
+
case 'annotation':
|
|
1458
|
+
return this._readAnnotationBlockPunctuation;
|
|
1432
1459
|
}
|
|
1433
1460
|
}
|
|
1434
1461
|
|