n3 2.13.1 → 2.13.3
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 +1 -0
- package/browser/n3.esm.min.js +10 -10
- package/browser/n3.min.js +9 -9
- package/lib/N3Lexer.js +23 -10
- package/lib/N3Parser.js +22 -3
- package/package.json +1 -1
- package/src/N3Lexer.js +23 -10
- package/src/N3Parser.js +26 -3
package/lib/N3Lexer.js
CHANGED
|
@@ -136,7 +136,7 @@ class N3Lexer {
|
|
|
136
136
|
if (!(key in lineModeRegExps) && this[key] instanceof RegExp) this[key] = invalidRegExp;
|
|
137
137
|
}
|
|
138
138
|
// The only keyword in N-Triples and N-Quads is VERSION, which is case-sensitive
|
|
139
|
-
this._keyword = /VERSION(?=[\s#<])/y;
|
|
139
|
+
this._keyword = /VERSION(?=[\s#<"])/y;
|
|
140
140
|
}
|
|
141
141
|
// When not in line mode, enable N3 functionality by default
|
|
142
142
|
else {
|
|
@@ -737,6 +737,27 @@ class N3Lexer {
|
|
|
737
737
|
return err;
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
+
// ### `_startTokenization` resets the lexer state for a new input
|
|
741
|
+
_startTokenization() {
|
|
742
|
+
this._line = 1;
|
|
743
|
+
this._linePosition = 0;
|
|
744
|
+
this._previousMarker = undefined;
|
|
745
|
+
this.previousToken = undefined;
|
|
746
|
+
this._literalClosingPos = 0;
|
|
747
|
+
this._input = undefined;
|
|
748
|
+
// Deferred tokenization and stream events can outlive their invocation.
|
|
749
|
+
// Ignore them once a later call takes ownership of the lexer state.
|
|
750
|
+
return this._tokenization = {};
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// ### `_tokenizeString` synchronously emits the tokens of a complete string through the callback,
|
|
754
|
+
// so that the caller can consume each token without the lexer collecting them all first
|
|
755
|
+
_tokenizeString(input, callback) {
|
|
756
|
+
this._startTokenization();
|
|
757
|
+
this._input = this._readStartingBom(input);
|
|
758
|
+
this._tryTokenizeToEnd(callback, true);
|
|
759
|
+
}
|
|
760
|
+
|
|
740
761
|
// ### Strips off any starting UTF BOM mark.
|
|
741
762
|
_readStartingBom(input) {
|
|
742
763
|
if (input.startsWith('\ufeff')) {
|
|
@@ -754,15 +775,7 @@ class N3Lexer {
|
|
|
754
775
|
// Separator whitespace counts towards the next token's start, outside either range.
|
|
755
776
|
// Multiline tokens also have endLine; their end column is relative to that line.
|
|
756
777
|
tokenize(input, callback) {
|
|
757
|
-
|
|
758
|
-
// Ignore them once a later call takes ownership of the lexer state.
|
|
759
|
-
const tokenization = this._tokenization = {};
|
|
760
|
-
this._line = 1;
|
|
761
|
-
this._linePosition = 0;
|
|
762
|
-
this._previousMarker = undefined;
|
|
763
|
-
this.previousToken = undefined;
|
|
764
|
-
this._literalClosingPos = 0;
|
|
765
|
-
this._input = undefined;
|
|
778
|
+
const tokenization = this._startTokenization();
|
|
766
779
|
|
|
767
780
|
// If the input is a string, continuously emit tokens through the callback until the end
|
|
768
781
|
if (typeof input === 'string') {
|
package/lib/N3Parser.js
CHANGED
|
@@ -1554,6 +1554,10 @@ class N3Parser {
|
|
|
1554
1554
|
// The read callback is the next function to be executed when a token arrives.
|
|
1555
1555
|
// We start reading in the top context.
|
|
1556
1556
|
this._readCallback = this._readBeforeTopContext;
|
|
1557
|
+
// A parse that failed part-way can have left scopes and a statement open
|
|
1558
|
+
this._contextStack = [];
|
|
1559
|
+
this._graph = this._subject = this._predicate = this._object = null;
|
|
1560
|
+
this._tripleTerm = this._reifier = null;
|
|
1557
1561
|
this._sparqlStyle = false;
|
|
1558
1562
|
this._prefixes = Object.create(null);
|
|
1559
1563
|
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2) : `b${blankNodePrefix++}_`;
|
|
@@ -1570,14 +1574,14 @@ class N3Parser {
|
|
|
1570
1574
|
this._quantifiedChanges = null;
|
|
1571
1575
|
this._emptyFormula = false;
|
|
1572
1576
|
this._tripleTermDepth = 0;
|
|
1573
|
-
|
|
1577
|
+
const readGrammarToken = token => {
|
|
1574
1578
|
return this._readCallback = this._readCallback(token);
|
|
1575
1579
|
};
|
|
1580
|
+
let readToken = readGrammarToken;
|
|
1576
1581
|
|
|
1577
1582
|
// Comments bypass the grammar, but participate in the token lifecycle.
|
|
1578
1583
|
if (onComment || this._lexer.comments) {
|
|
1579
1584
|
this._lexer.comments = true;
|
|
1580
|
-
const readGrammarToken = readToken;
|
|
1581
1585
|
readToken = token => {
|
|
1582
1586
|
if (token.type !== 'comment') return readGrammarToken(token);
|
|
1583
1587
|
if (onComment) onComment(token.value);
|
|
@@ -1611,7 +1615,22 @@ class N3Parser {
|
|
|
1611
1615
|
this._callback = (e, t) => {
|
|
1612
1616
|
e ? error = e : t && quads.push(t);
|
|
1613
1617
|
};
|
|
1614
|
-
this._lexer
|
|
1618
|
+
const lexer = this._lexer;
|
|
1619
|
+
// Without callbacks, nothing observes the parse before the whole document
|
|
1620
|
+
// has lexed, so tokens can be parsed as they are lexed instead of being
|
|
1621
|
+
// collected into an array first. A lexer that replaces the built-in
|
|
1622
|
+
// tokenize keeps going through its own implementation.
|
|
1623
|
+
if (!onPrefix && !onVersion && !onDirective && !onComment && !onToken && !onTokenEnd && lexer.tokenize === _N3Lexer.default.prototype.tokenize && typeof lexer._tokenizeString === 'function') {
|
|
1624
|
+
// A lexical error used to stop the parse before any token was read,
|
|
1625
|
+
// so undo base declarations that were read before it
|
|
1626
|
+
const base = [this._base, this._basePath, this._baseRoot, this._baseScheme];
|
|
1627
|
+
lexer._tokenizeString(input, (e, token) => {
|
|
1628
|
+
if (e) {
|
|
1629
|
+
[this._base, this._basePath, this._baseRoot, this._baseScheme] = base;
|
|
1630
|
+
this._callback(e), this._callback = noop;
|
|
1631
|
+
} else if (this._readCallback) readToken(token);
|
|
1632
|
+
});
|
|
1633
|
+
} else lexer.tokenize(input).every(readToken);
|
|
1615
1634
|
if (error) throw error;
|
|
1616
1635
|
return quads;
|
|
1617
1636
|
}
|
package/package.json
CHANGED
package/src/N3Lexer.js
CHANGED
|
@@ -102,7 +102,7 @@ export default class N3Lexer {
|
|
|
102
102
|
this[key] = invalidRegExp;
|
|
103
103
|
}
|
|
104
104
|
// The only keyword in N-Triples and N-Quads is VERSION, which is case-sensitive
|
|
105
|
-
this._keyword = /VERSION(?=[\s#<])/y;
|
|
105
|
+
this._keyword = /VERSION(?=[\s#<"])/y;
|
|
106
106
|
}
|
|
107
107
|
// When not in line mode, enable N3 functionality by default
|
|
108
108
|
else {
|
|
@@ -758,6 +758,27 @@ export default class N3Lexer {
|
|
|
758
758
|
return err;
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
+
// ### `_startTokenization` resets the lexer state for a new input
|
|
762
|
+
_startTokenization() {
|
|
763
|
+
this._line = 1;
|
|
764
|
+
this._linePosition = 0;
|
|
765
|
+
this._previousMarker = undefined;
|
|
766
|
+
this.previousToken = undefined;
|
|
767
|
+
this._literalClosingPos = 0;
|
|
768
|
+
this._input = undefined;
|
|
769
|
+
// Deferred tokenization and stream events can outlive their invocation.
|
|
770
|
+
// Ignore them once a later call takes ownership of the lexer state.
|
|
771
|
+
return this._tokenization = {};
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// ### `_tokenizeString` synchronously emits the tokens of a complete string through the callback,
|
|
775
|
+
// so that the caller can consume each token without the lexer collecting them all first
|
|
776
|
+
_tokenizeString(input, callback) {
|
|
777
|
+
this._startTokenization();
|
|
778
|
+
this._input = this._readStartingBom(input);
|
|
779
|
+
this._tryTokenizeToEnd(callback, true);
|
|
780
|
+
}
|
|
781
|
+
|
|
761
782
|
// ### Strips off any starting UTF BOM mark.
|
|
762
783
|
_readStartingBom(input) {
|
|
763
784
|
if (input.startsWith('\ufeff')) {
|
|
@@ -775,15 +796,7 @@ export default class N3Lexer {
|
|
|
775
796
|
// Separator whitespace counts towards the next token's start, outside either range.
|
|
776
797
|
// Multiline tokens also have endLine; their end column is relative to that line.
|
|
777
798
|
tokenize(input, callback) {
|
|
778
|
-
|
|
779
|
-
// Ignore them once a later call takes ownership of the lexer state.
|
|
780
|
-
const tokenization = this._tokenization = {};
|
|
781
|
-
this._line = 1;
|
|
782
|
-
this._linePosition = 0;
|
|
783
|
-
this._previousMarker = undefined;
|
|
784
|
-
this.previousToken = undefined;
|
|
785
|
-
this._literalClosingPos = 0;
|
|
786
|
-
this._input = undefined;
|
|
799
|
+
const tokenization = this._startTokenization();
|
|
787
800
|
|
|
788
801
|
// If the input is a string, continuously emit tokens through the callback until the end
|
|
789
802
|
if (typeof input === 'string') {
|
package/src/N3Parser.js
CHANGED
|
@@ -1682,6 +1682,10 @@ export default class N3Parser {
|
|
|
1682
1682
|
// The read callback is the next function to be executed when a token arrives.
|
|
1683
1683
|
// We start reading in the top context.
|
|
1684
1684
|
this._readCallback = this._readBeforeTopContext;
|
|
1685
|
+
// A parse that failed part-way can have left scopes and a statement open
|
|
1686
|
+
this._contextStack = [];
|
|
1687
|
+
this._graph = this._subject = this._predicate = this._object = null;
|
|
1688
|
+
this._tripleTerm = this._reifier = null;
|
|
1685
1689
|
this._sparqlStyle = false;
|
|
1686
1690
|
this._prefixes = Object.create(null);
|
|
1687
1691
|
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2)
|
|
@@ -1701,14 +1705,14 @@ export default class N3Parser {
|
|
|
1701
1705
|
this._emptyFormula = false;
|
|
1702
1706
|
this._tripleTermDepth = 0;
|
|
1703
1707
|
|
|
1704
|
-
|
|
1708
|
+
const readGrammarToken = token => {
|
|
1705
1709
|
return this._readCallback = this._readCallback(token);
|
|
1706
1710
|
};
|
|
1711
|
+
let readToken = readGrammarToken;
|
|
1707
1712
|
|
|
1708
1713
|
// Comments bypass the grammar, but participate in the token lifecycle.
|
|
1709
1714
|
if (onComment || this._lexer.comments) {
|
|
1710
1715
|
this._lexer.comments = true;
|
|
1711
|
-
const readGrammarToken = readToken;
|
|
1712
1716
|
readToken = token => {
|
|
1713
1717
|
if (token.type !== 'comment')
|
|
1714
1718
|
return readGrammarToken(token);
|
|
@@ -1743,7 +1747,26 @@ export default class N3Parser {
|
|
|
1743
1747
|
const quads = [];
|
|
1744
1748
|
let error;
|
|
1745
1749
|
this._callback = (e, t) => { e ? (error = e) : t && quads.push(t); };
|
|
1746
|
-
this._lexer
|
|
1750
|
+
const lexer = this._lexer;
|
|
1751
|
+
// Without callbacks, nothing observes the parse before the whole document
|
|
1752
|
+
// has lexed, so tokens can be parsed as they are lexed instead of being
|
|
1753
|
+
// collected into an array first. A lexer that replaces the built-in
|
|
1754
|
+
// tokenize keeps going through its own implementation.
|
|
1755
|
+
if (!onPrefix && !onVersion && !onDirective && !onComment && !onToken && !onTokenEnd &&
|
|
1756
|
+
lexer.tokenize === N3Lexer.prototype.tokenize && typeof lexer._tokenizeString === 'function') {
|
|
1757
|
+
// A lexical error used to stop the parse before any token was read,
|
|
1758
|
+
// so undo base declarations that were read before it
|
|
1759
|
+
const base = [this._base, this._basePath, this._baseRoot, this._baseScheme];
|
|
1760
|
+
lexer._tokenizeString(input, (e, token) => {
|
|
1761
|
+
if (e) {
|
|
1762
|
+
[this._base, this._basePath, this._baseRoot, this._baseScheme] = base;
|
|
1763
|
+
this._callback(e), this._callback = noop;
|
|
1764
|
+
}
|
|
1765
|
+
else if (this._readCallback) readToken(token);
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
else
|
|
1769
|
+
lexer.tokenize(input).every(readToken);
|
|
1747
1770
|
if (error) throw error;
|
|
1748
1771
|
return quads;
|
|
1749
1772
|
}
|