n3 2.7.9 → 2.7.11
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 +5 -5
- package/browser/n3.min.js +5 -5
- package/lib/N3Lexer.js +51 -27
- package/package.json +1 -1
- package/src/N3Lexer.js +57 -32
package/lib/N3Lexer.js
CHANGED
|
@@ -12,6 +12,11 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
12
12
|
const {
|
|
13
13
|
xsd
|
|
14
14
|
} = _IRIs.default;
|
|
15
|
+
const SPACE = 0x20,
|
|
16
|
+
TAB = 0x09,
|
|
17
|
+
LF = 0x0A,
|
|
18
|
+
CR = 0x0D,
|
|
19
|
+
HASH = 0x23;
|
|
15
20
|
|
|
16
21
|
// Regular expression and replacement strings to unescape N3 strings
|
|
17
22
|
const escapeSequence = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{8})|\\([^])/g;
|
|
@@ -61,10 +66,8 @@ const lineModeRegExps = {
|
|
|
61
66
|
_simpleQuotedString: true,
|
|
62
67
|
_langcode: true,
|
|
63
68
|
_blank: true,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
_whitespace: true,
|
|
67
|
-
_endOfFile: true
|
|
69
|
+
_commentLine: true,
|
|
70
|
+
_whitespace: true
|
|
68
71
|
};
|
|
69
72
|
const invalidRegExp = /$0^/;
|
|
70
73
|
|
|
@@ -89,10 +92,8 @@ class N3Lexer {
|
|
|
89
92
|
this._n3Verb = /^(?:has|is|of)(?=[\s#()\[\]\{\}"'<>?_+\-0-9])/;
|
|
90
93
|
this._n3Id = /^id(?=[\s#<])/;
|
|
91
94
|
this._shortPredicates = /^a(?=[\s#()\[\]\{\}"'<>])/;
|
|
92
|
-
this.
|
|
93
|
-
this._comment = /#([^\n\r]*)/;
|
|
95
|
+
this._commentLine = /^[ \t]*#([^\n\r]*)(?:\r\n|\n|\r)[ \t]*/;
|
|
94
96
|
this._whitespace = /^[ \t]+/;
|
|
95
|
-
this._endOfFile = /^(?:#[^\n\r]*)?$/;
|
|
96
97
|
options = options || {};
|
|
97
98
|
|
|
98
99
|
// Whether the log:isImpliedBy predicate is supported
|
|
@@ -124,25 +125,48 @@ class N3Lexer {
|
|
|
124
125
|
let input = this._input;
|
|
125
126
|
let currentLineLength = input.length;
|
|
126
127
|
while (true) {
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
// Consume one separator line at a time, including its following indentation.
|
|
129
|
+
while (true) {
|
|
130
|
+
let charCode = input.charCodeAt(0),
|
|
131
|
+
separatorLength = 0;
|
|
132
|
+
if (charCode === SPACE || charCode === TAB) {
|
|
133
|
+
const next = input.charCodeAt(1);
|
|
134
|
+
separatorLength = next === SPACE || next === TAB ? this._whitespace.exec(input)[0].length : 1;
|
|
135
|
+
charCode = input.charCodeAt(separatorLength);
|
|
136
|
+
}
|
|
137
|
+
if (charCode === HASH) {
|
|
138
|
+
const comment = this._commentLine.exec(input);
|
|
139
|
+
if (comment) {
|
|
140
|
+
if (this.comments) emitToken('comment', comment[1], '', this._line, comment[0].length);
|
|
141
|
+
input = input.slice(comment[0].length);
|
|
142
|
+
currentLineLength = input.length;
|
|
143
|
+
this._line++;
|
|
144
|
+
} else {
|
|
145
|
+
// A comment without a line ending stays buffered until EOF.
|
|
146
|
+
input = input.slice(separatorLength);
|
|
147
|
+
if (!inputFinished) return this._input = input;
|
|
148
|
+
if (this.comments) emitToken('comment', input.slice(1), '', this._line, input.length);
|
|
149
|
+
input = '';
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
} else if (charCode === LF || charCode === CR) {
|
|
153
|
+
separatorLength += charCode === CR && input.charCodeAt(separatorLength + 1) === LF ? 2 : 1;
|
|
154
|
+
// Indentation is part of the same separator match as the newline.
|
|
155
|
+
const next = input.charCodeAt(separatorLength);
|
|
156
|
+
if (next === SPACE || next === TAB) {
|
|
157
|
+
const following = input.charCodeAt(separatorLength + 1);
|
|
158
|
+
separatorLength += following === SPACE || following === TAB ? this._whitespace.exec(input.slice(separatorLength))[0].length : 1;
|
|
159
|
+
}
|
|
160
|
+
input = input.slice(separatorLength);
|
|
161
|
+
currentLineLength = input.length;
|
|
162
|
+
this._line++;
|
|
163
|
+
} else {
|
|
164
|
+
if (separatorLength !== 0) input = input.slice(separatorLength);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
136
167
|
}
|
|
137
|
-
|
|
138
|
-
if (!whiteSpaceMatch && (whiteSpaceMatch = this._whitespace.exec(input))) input = input.slice(whiteSpaceMatch[0].length);
|
|
139
|
-
|
|
140
|
-
// Stop for now if we're at the end
|
|
141
|
-
if (this._endOfFile.test(input)) {
|
|
142
|
-
// If the input is finished, emit EOF
|
|
168
|
+
if (input.length === 0) {
|
|
143
169
|
if (inputFinished) {
|
|
144
|
-
// Try to find a final comment
|
|
145
|
-
if (this.comments && (comment = this._comment.exec(input))) emitToken('comment', comment[1], '', this._line, input.length);
|
|
146
170
|
input = null;
|
|
147
171
|
emitToken('eof', '', '', this._line, 0);
|
|
148
172
|
}
|
|
@@ -313,11 +337,11 @@ class N3Lexer {
|
|
|
313
337
|
case 'f':
|
|
314
338
|
case 't':
|
|
315
339
|
// Try to match a boolean
|
|
316
|
-
if (
|
|
340
|
+
if (this._boolean.test(input)) type = 'literal', value = firstChar === 't' ? 'true' : 'false', prefix = xsd.boolean, matchLength = value.length;else inconclusive = true;
|
|
317
341
|
break;
|
|
318
342
|
case 'a':
|
|
319
343
|
// Try to find an abbreviated predicate
|
|
320
|
-
if (
|
|
344
|
+
if (this._shortPredicates.test(input)) type = 'abbreviation', value = 'a', matchLength = 1;else inconclusive = true;
|
|
321
345
|
break;
|
|
322
346
|
case 'h':
|
|
323
347
|
case 'o':
|
|
@@ -326,7 +350,7 @@ class N3Lexer {
|
|
|
326
350
|
break;
|
|
327
351
|
case 'i':
|
|
328
352
|
// Try to find an IRI property list identifier or N3 verb keyword
|
|
329
|
-
if (this._n3Mode &&
|
|
353
|
+
if (this._n3Mode && this._n3Id.test(input)) type = 'id', matchLength = 2;else if (this._n3Mode && (match = this._matchN3Verb(input, inputFinished))) type = match[0];else inconclusive = true;
|
|
330
354
|
break;
|
|
331
355
|
case '=':
|
|
332
356
|
// Try to find an implication arrow or equals sign
|
package/package.json
CHANGED
package/src/N3Lexer.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Buffer } from 'buffer';
|
|
|
3
3
|
import namespaces from './IRIs';
|
|
4
4
|
|
|
5
5
|
const { xsd } = namespaces;
|
|
6
|
+
const SPACE = 0x20, TAB = 0x09, LF = 0x0A, CR = 0x0D, HASH = 0x23;
|
|
6
7
|
|
|
7
8
|
// Regular expression and replacement strings to unescape N3 strings
|
|
8
9
|
const escapeSequence = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{8})|\\([^])/g;
|
|
@@ -30,10 +31,8 @@ const lineModeRegExps = {
|
|
|
30
31
|
_simpleQuotedString: true,
|
|
31
32
|
_langcode: true,
|
|
32
33
|
_blank: true,
|
|
33
|
-
|
|
34
|
-
_comment: true,
|
|
34
|
+
_commentLine: true,
|
|
35
35
|
_whitespace: true,
|
|
36
|
-
_endOfFile: true,
|
|
37
36
|
};
|
|
38
37
|
const invalidRegExp = /$0^/;
|
|
39
38
|
|
|
@@ -58,10 +57,8 @@ export default class N3Lexer {
|
|
|
58
57
|
this._n3Verb = /^(?:has|is|of)(?=[\s#()\[\]\{\}"'<>?_+\-0-9])/;
|
|
59
58
|
this._n3Id = /^id(?=[\s#<])/;
|
|
60
59
|
this._shortPredicates = /^a(?=[\s#()\[\]\{\}"'<>])/;
|
|
61
|
-
this.
|
|
62
|
-
this._comment = /#([^\n\r]*)/;
|
|
60
|
+
this._commentLine = /^[ \t]*#([^\n\r]*)(?:\r\n|\n|\r)[ \t]*/;
|
|
63
61
|
this._whitespace = /^[ \t]+/;
|
|
64
|
-
this._endOfFile = /^(?:#[^\n\r]*)?$/;
|
|
65
62
|
options = options || {};
|
|
66
63
|
|
|
67
64
|
// Whether the log:isImpliedBy predicate is supported
|
|
@@ -94,28 +91,56 @@ export default class N3Lexer {
|
|
|
94
91
|
let input = this._input;
|
|
95
92
|
let currentLineLength = input.length;
|
|
96
93
|
while (true) {
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
// Consume one separator line at a time, including its following indentation.
|
|
95
|
+
while (true) {
|
|
96
|
+
let charCode = input.charCodeAt(0), separatorLength = 0;
|
|
97
|
+
if (charCode === SPACE || charCode === TAB) {
|
|
98
|
+
const next = input.charCodeAt(1);
|
|
99
|
+
separatorLength = next === SPACE || next === TAB ?
|
|
100
|
+
this._whitespace.exec(input)[0].length : 1;
|
|
101
|
+
charCode = input.charCodeAt(separatorLength);
|
|
102
|
+
}
|
|
103
|
+
if (charCode === HASH) {
|
|
104
|
+
const comment = this._commentLine.exec(input);
|
|
105
|
+
if (comment) {
|
|
106
|
+
if (this.comments)
|
|
107
|
+
emitToken('comment', comment[1], '', this._line, comment[0].length);
|
|
108
|
+
input = input.slice(comment[0].length);
|
|
109
|
+
currentLineLength = input.length;
|
|
110
|
+
this._line++;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// A comment without a line ending stays buffered until EOF.
|
|
114
|
+
input = input.slice(separatorLength);
|
|
115
|
+
if (!inputFinished)
|
|
116
|
+
return this._input = input;
|
|
117
|
+
if (this.comments)
|
|
118
|
+
emitToken('comment', input.slice(1), '', this._line, input.length);
|
|
119
|
+
input = '';
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if (charCode === LF || charCode === CR) {
|
|
124
|
+
separatorLength += charCode === CR && input.charCodeAt(separatorLength + 1) === LF ? 2 : 1;
|
|
125
|
+
// Indentation is part of the same separator match as the newline.
|
|
126
|
+
const next = input.charCodeAt(separatorLength);
|
|
127
|
+
if (next === SPACE || next === TAB) {
|
|
128
|
+
const following = input.charCodeAt(separatorLength + 1);
|
|
129
|
+
separatorLength += following === SPACE || following === TAB ?
|
|
130
|
+
this._whitespace.exec(input.slice(separatorLength))[0].length : 1;
|
|
131
|
+
}
|
|
132
|
+
input = input.slice(separatorLength);
|
|
133
|
+
currentLineLength = input.length;
|
|
134
|
+
this._line++;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
if (separatorLength !== 0)
|
|
138
|
+
input = input.slice(separatorLength);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
107
141
|
}
|
|
108
|
-
|
|
109
|
-
if (!whiteSpaceMatch && (whiteSpaceMatch = this._whitespace.exec(input)))
|
|
110
|
-
input = input.slice(whiteSpaceMatch[0].length);
|
|
111
|
-
|
|
112
|
-
// Stop for now if we're at the end
|
|
113
|
-
if (this._endOfFile.test(input)) {
|
|
114
|
-
// If the input is finished, emit EOF
|
|
142
|
+
if (input.length === 0) {
|
|
115
143
|
if (inputFinished) {
|
|
116
|
-
// Try to find a final comment
|
|
117
|
-
if (this.comments && (comment = this._comment.exec(input)))
|
|
118
|
-
emitToken('comment', comment[1], '', this._line, input.length);
|
|
119
144
|
input = null;
|
|
120
145
|
emitToken('eof', '', '', this._line, 0);
|
|
121
146
|
}
|
|
@@ -311,16 +336,16 @@ export default class N3Lexer {
|
|
|
311
336
|
case 'f':
|
|
312
337
|
case 't':
|
|
313
338
|
// Try to match a boolean
|
|
314
|
-
if (
|
|
315
|
-
type = 'literal', value =
|
|
339
|
+
if (this._boolean.test(input))
|
|
340
|
+
type = 'literal', value = firstChar === 't' ? 'true' : 'false', prefix = xsd.boolean, matchLength = value.length;
|
|
316
341
|
else
|
|
317
342
|
inconclusive = true;
|
|
318
343
|
break;
|
|
319
344
|
|
|
320
345
|
case 'a':
|
|
321
346
|
// Try to find an abbreviated predicate
|
|
322
|
-
if (
|
|
323
|
-
type = 'abbreviation', value = 'a';
|
|
347
|
+
if (this._shortPredicates.test(input))
|
|
348
|
+
type = 'abbreviation', value = 'a', matchLength = 1;
|
|
324
349
|
else
|
|
325
350
|
inconclusive = true;
|
|
326
351
|
break;
|
|
@@ -336,8 +361,8 @@ export default class N3Lexer {
|
|
|
336
361
|
|
|
337
362
|
case 'i':
|
|
338
363
|
// Try to find an IRI property list identifier or N3 verb keyword
|
|
339
|
-
if (this._n3Mode &&
|
|
340
|
-
type = 'id';
|
|
364
|
+
if (this._n3Mode && this._n3Id.test(input))
|
|
365
|
+
type = 'id', matchLength = 2;
|
|
341
366
|
else if (this._n3Mode && (match = this._matchN3Verb(input, inputFinished)))
|
|
342
367
|
type = match[0];
|
|
343
368
|
else
|