n3 2.2.2 → 2.2.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/lib/N3Parser.js CHANGED
@@ -711,7 +711,7 @@ class N3Parser {
711
711
  if (!this._validAnnotation) return this._error('Annotation block can not be empty', token);
712
712
  this._subject = null;
713
713
  this._annotation = false;
714
- next = this._readPunctuation;
714
+ next = this._getContextEndReader();
715
715
  break;
716
716
  default:
717
717
  // An entity means this is a quad (only allowed if not already inside a graph)
@@ -745,9 +745,20 @@ class N3Parser {
745
745
  case ',':
746
746
  next = this._readObject;
747
747
  break;
748
+ // Annotation syntax applies to the quad just read, exactly as it does
749
+ // outside of a blank node property list. `|}` arrives here too, because
750
+ // the objects inside the annotation block are themselves read within the
751
+ // enclosing blank node context.
752
+ case '~':
753
+ case '{|':
754
+ case '|}':
755
+ return this._readPunctuation(token);
748
756
  default:
749
757
  return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
750
758
  }
759
+ // An annotation block consumes the subject it annotates, so there is
760
+ // nothing left to share with a following predicate-object pair
761
+ if (this._subject === null) return this._error('Expected ] to follow annotation', token);
751
762
  // A quad has been completed now, so return it
752
763
  this._emit(this._subject, this._predicate, this._object, this._graph);
753
764
  return next;
@@ -1011,12 +1022,40 @@ class N3Parser {
1011
1022
  // If next token is a reifier, read it as such.
1012
1023
  if (token.type === 'IRI' || token.type === 'typeIRI' || token.type === 'type' || token.type === 'prefixed' || token.type === 'blank' || token.type === 'var') {
1013
1024
  this._reifier = this._readEntity(token);
1014
- return this._readPunctuation;
1025
+ return this._readAnnotationBlockOrPunctuation;
1015
1026
  }
1016
1027
  // Otherwise, emit and assert triple term.
1017
1028
  this._readTripleTerm();
1018
1029
  this._subject = null;
1019
- return this._readPunctuation(token);
1030
+ return this._getContextEndReader().call(this, token);
1031
+ }
1032
+
1033
+ // ### `_readAnnotationBlockOrPunctuation` reads what follows an explicit reifier:
1034
+ // either an annotation block, which reuses the reifier as its subject,
1035
+ // or punctuation, in which case the reifier stands alone and its triple
1036
+ // term still needs to be asserted here.
1037
+ _readAnnotationBlockOrPunctuation(token) {
1038
+ if (token.type === '{|') return this._readPunctuation(token);
1039
+ this._readTripleTerm();
1040
+ this._annotation = false;
1041
+ // A shared subject or predicate goes on to reify a *different* triple,
1042
+ // so the term just asserted must not be reused for the next one.
1043
+ this._tripleTerm = null;
1044
+ // The annotated triple was already emitted when the tilde was read,
1045
+ // so continue without letting `_readPunctuation` emit it a second time.
1046
+ switch (token.type) {
1047
+ // The subject stays shared with the next predicate-object pair
1048
+ case ';':
1049
+ return this._readPredicate;
1050
+ // The subject and predicate stay shared with the next object
1051
+ case ',':
1052
+ return this._readObject;
1053
+ default:
1054
+ this._subject = null;
1055
+ // Resume in the enclosing context, which is top-level punctuation
1056
+ // unless the reified triple sits inside a blank node property list
1057
+ return this._getContextEndReader().call(this, token);
1058
+ }
1020
1059
  }
1021
1060
  _readTripleTerm() {
1022
1061
  const stack = this._contextStack,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "2.2.2",
3
+ "version": "2.2.4",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
package/src/N3Parser.js CHANGED
@@ -772,7 +772,7 @@ export default class N3Parser {
772
772
  return this._error('Annotation block can not be empty', token);
773
773
  this._subject = null;
774
774
  this._annotation = false;
775
- next = this._readPunctuation;
775
+ next = this._getContextEndReader();
776
776
  break;
777
777
  default:
778
778
  // An entity means this is a quad (only allowed if not already inside a graph)
@@ -808,9 +808,21 @@ export default class N3Parser {
808
808
  case ',':
809
809
  next = this._readObject;
810
810
  break;
811
+ // Annotation syntax applies to the quad just read, exactly as it does
812
+ // outside of a blank node property list. `|}` arrives here too, because
813
+ // the objects inside the annotation block are themselves read within the
814
+ // enclosing blank node context.
815
+ case '~':
816
+ case '{|':
817
+ case '|}':
818
+ return this._readPunctuation(token);
811
819
  default:
812
820
  return this._error(`Expected punctuation to follow "${this._object.id}"`, token);
813
821
  }
822
+ // An annotation block consumes the subject it annotates, so there is
823
+ // nothing left to share with a following predicate-object pair
824
+ if (this._subject === null)
825
+ return this._error('Expected ] to follow annotation', token);
814
826
  // A quad has been completed now, so return it
815
827
  this._emit(this._subject, this._predicate, this._object, this._graph);
816
828
  return next;
@@ -1096,12 +1108,42 @@ export default class N3Parser {
1096
1108
  // If next token is a reifier, read it as such.
1097
1109
  if (token.type === 'IRI' || token.type === 'typeIRI' || token.type === 'type' || token.type === 'prefixed' || token.type === 'blank' || token.type === 'var') {
1098
1110
  this._reifier = this._readEntity(token);
1099
- return this._readPunctuation;
1111
+ return this._readAnnotationBlockOrPunctuation;
1100
1112
  }
1101
1113
  // Otherwise, emit and assert triple term.
1102
1114
  this._readTripleTerm();
1103
1115
  this._subject = null;
1104
- return this._readPunctuation(token);
1116
+ return this._getContextEndReader().call(this, token);
1117
+ }
1118
+
1119
+ // ### `_readAnnotationBlockOrPunctuation` reads what follows an explicit reifier:
1120
+ // either an annotation block, which reuses the reifier as its subject,
1121
+ // or punctuation, in which case the reifier stands alone and its triple
1122
+ // term still needs to be asserted here.
1123
+ _readAnnotationBlockOrPunctuation(token) {
1124
+ if (token.type === '{|')
1125
+ return this._readPunctuation(token);
1126
+
1127
+ this._readTripleTerm();
1128
+ this._annotation = false;
1129
+ // A shared subject or predicate goes on to reify a *different* triple,
1130
+ // so the term just asserted must not be reused for the next one.
1131
+ this._tripleTerm = null;
1132
+ // The annotated triple was already emitted when the tilde was read,
1133
+ // so continue without letting `_readPunctuation` emit it a second time.
1134
+ switch (token.type) {
1135
+ // The subject stays shared with the next predicate-object pair
1136
+ case ';':
1137
+ return this._readPredicate;
1138
+ // The subject and predicate stay shared with the next object
1139
+ case ',':
1140
+ return this._readObject;
1141
+ default:
1142
+ this._subject = null;
1143
+ // Resume in the enclosing context, which is top-level punctuation
1144
+ // unless the reified triple sits inside a blank node property list
1145
+ return this._getContextEndReader().call(this, token);
1146
+ }
1105
1147
  }
1106
1148
 
1107
1149
  _readTripleTerm() {