eyeling 1.24.2 → 1.24.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/HANDBOOK.md +43 -7
- package/dist/browser/eyeling.browser.js +401 -72
- package/eyeling.js +401 -72
- package/index.js +2 -0
- package/lib/cli.js +27 -10
- package/lib/engine.js +17 -7
- package/lib/lexer.js +242 -52
- package/lib/multisource.js +9 -2
- package/lib/printing.js +106 -1
- package/package.json +1 -1
- package/see/README.md +2 -1
- package/see/examples/doc/rdf_dataset.md +26 -0
- package/see/examples/input/rdf_dataset.trig +34 -0
- package/see/examples/n3/rdf_dataset.n3 +34 -0
- package/see/examples/output/rdf_dataset.md +54 -0
- package/see/examples/rdf_dataset.js +1512 -0
- package/see/see.js +26 -2
- package/test/api.test.js +68 -2
- package/test/see.test.js +0 -0
- package/tools/bundle.js +0 -0
- package/tools/n3gen.js +0 -0
|
@@ -4547,6 +4547,7 @@ function main() {
|
|
|
4547
4547
|
` -e, --enforce-https Rewrite http:// IRIs to https:// for log dereferencing builtins.\n` +
|
|
4548
4548
|
` -h, --help Show this help and exit.\n` +
|
|
4549
4549
|
` -p, --proof-comments Enable proof explanations.\n` +
|
|
4550
|
+
` -r, --rdf Enable RDF/TriG input/output compatibility.\n` +
|
|
4550
4551
|
` -s, --super-restricted Disable all builtins except => and <=.\n` +
|
|
4551
4552
|
` -t, --stream Stream derived triples as soon as they are derived.\n` +
|
|
4552
4553
|
` -v, --version Print version and exit.\n`;
|
|
@@ -4588,6 +4589,7 @@ function main() {
|
|
|
4588
4589
|
|
|
4589
4590
|
const showAst = argv.includes('--ast') || argv.includes('-a');
|
|
4590
4591
|
const streamMode = argv.includes('--stream') || argv.includes('-t');
|
|
4592
|
+
const rdfMode = argv.includes('--rdf') || argv.includes('-r');
|
|
4591
4593
|
|
|
4592
4594
|
// --enforce-https: rewrite http:// -> https:// for log dereferencing builtins
|
|
4593
4595
|
if (argv.includes('--enforce-https') || argv.includes('-e')) {
|
|
@@ -4650,6 +4652,7 @@ function main() {
|
|
|
4650
4652
|
label: sourceLabel,
|
|
4651
4653
|
collectUsedPrefixes: true,
|
|
4652
4654
|
keepSourceArtifacts: false,
|
|
4655
|
+
rdf: rdfMode,
|
|
4653
4656
|
}),
|
|
4654
4657
|
);
|
|
4655
4658
|
} catch (e) {
|
|
@@ -4762,10 +4765,10 @@ function main() {
|
|
|
4762
4765
|
(df) => {
|
|
4763
4766
|
if (engine.getProofCommentsEnabled()) {
|
|
4764
4767
|
engine.printExplanation(df, outPrefixes);
|
|
4765
|
-
console.log(engine.tripleToN3(df.fact, outPrefixes));
|
|
4768
|
+
console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, outPrefixes) : engine.tripleToN3(df.fact, outPrefixes));
|
|
4766
4769
|
console.log();
|
|
4767
4770
|
} else {
|
|
4768
|
-
console.log(engine.tripleToN3(df.fact, outPrefixes));
|
|
4771
|
+
console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, outPrefixes) : engine.tripleToN3(df.fact, outPrefixes));
|
|
4769
4772
|
}
|
|
4770
4773
|
},
|
|
4771
4774
|
{ captureExplanations: engine.getProofCommentsEnabled(), prefixes: outPrefixes },
|
|
@@ -4801,7 +4804,24 @@ function main() {
|
|
|
4801
4804
|
return;
|
|
4802
4805
|
}
|
|
4803
4806
|
|
|
4804
|
-
|
|
4807
|
+
let bodyText = '';
|
|
4808
|
+
if (rdfMode && !engine.getProofCommentsEnabled()) {
|
|
4809
|
+
bodyText = outTriples.map((tr) => engine.tripleToRdfCompatible(tr, prefixes)).join('\n');
|
|
4810
|
+
} else if (hasQueries && !engine.getProofCommentsEnabled()) {
|
|
4811
|
+
// In log:query mode, when proof comments are disabled, pretty-print blank-node
|
|
4812
|
+
// shaped outputs as Turtle property lists ("[ ... ] .") for readability.
|
|
4813
|
+
bodyText = engine.prettyPrintQueryTriples(outTriples, prefixes);
|
|
4814
|
+
}
|
|
4815
|
+
|
|
4816
|
+
let usedPrefixes = prefixes.prefixesUsedForOutput(outTriples);
|
|
4817
|
+
if (rdfMode && bodyText) {
|
|
4818
|
+
usedPrefixes = usedPrefixes.filter(([pfx]) => pfx === '' || bodyText.includes(pfx + ':'));
|
|
4819
|
+
}
|
|
4820
|
+
|
|
4821
|
+
if (rdfMode && bodyText.includes('<<(')) {
|
|
4822
|
+
console.log('VERSION "1.2"');
|
|
4823
|
+
console.log();
|
|
4824
|
+
}
|
|
4805
4825
|
|
|
4806
4826
|
for (const [pfx, base] of usedPrefixes) {
|
|
4807
4827
|
if (pfx === '') console.log(`@prefix : <${base}> .`);
|
|
@@ -4809,21 +4829,18 @@ function main() {
|
|
|
4809
4829
|
}
|
|
4810
4830
|
if (outTriples.length && usedPrefixes.length) console.log();
|
|
4811
4831
|
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
if (hasQueries && !engine.getProofCommentsEnabled()) {
|
|
4815
|
-
const s = engine.prettyPrintQueryTriples(outTriples, prefixes);
|
|
4816
|
-
if (s) process.stdout.write(String(s).replace(/\s*$/g, '') + '\n');
|
|
4832
|
+
if (bodyText) {
|
|
4833
|
+
process.stdout.write(String(bodyText).replace(/\s*$/g, '') + '\n');
|
|
4817
4834
|
return;
|
|
4818
4835
|
}
|
|
4819
4836
|
|
|
4820
4837
|
for (const df of outDerived) {
|
|
4821
4838
|
if (engine.getProofCommentsEnabled()) {
|
|
4822
4839
|
engine.printExplanation(df, prefixes);
|
|
4823
|
-
console.log(engine.tripleToN3(df.fact, prefixes));
|
|
4840
|
+
console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, prefixes) : engine.tripleToN3(df.fact, prefixes));
|
|
4824
4841
|
console.log();
|
|
4825
4842
|
} else {
|
|
4826
|
-
console.log(engine.tripleToN3(df.fact, prefixes));
|
|
4843
|
+
console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, prefixes) : engine.tripleToN3(df.fact, prefixes));
|
|
4827
4844
|
}
|
|
4828
4845
|
}
|
|
4829
4846
|
}
|
|
@@ -5356,7 +5373,12 @@ const {
|
|
|
5356
5373
|
|
|
5357
5374
|
const { makeExplain } = require('./explain');
|
|
5358
5375
|
|
|
5359
|
-
const {
|
|
5376
|
+
const {
|
|
5377
|
+
termToN3,
|
|
5378
|
+
tripleToN3,
|
|
5379
|
+
prettyPrintQueryTriples,
|
|
5380
|
+
tripleToRdfCompatible,
|
|
5381
|
+
} = require('./printing');
|
|
5360
5382
|
const {
|
|
5361
5383
|
getDataFactory,
|
|
5362
5384
|
internalTripleToRdfJsQuad,
|
|
@@ -8669,9 +8691,12 @@ function reasonStream(input, opts = {}) {
|
|
|
8669
8691
|
dataFactory = null,
|
|
8670
8692
|
skipUnsupportedRdfJs = false,
|
|
8671
8693
|
builtinModules = null,
|
|
8694
|
+
rdf = false,
|
|
8672
8695
|
} = opts;
|
|
8673
8696
|
|
|
8674
|
-
const
|
|
8697
|
+
const useRdfCompatibility = !!rdf;
|
|
8698
|
+
|
|
8699
|
+
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: useRdfCompatibility });
|
|
8675
8700
|
const parsedInput = parsedSourceList || normalizeParsedReasonerInputSync(input);
|
|
8676
8701
|
const rdfFactory = rdfjs ? getDataFactory(dataFactory) : null;
|
|
8677
8702
|
|
|
@@ -8707,7 +8732,7 @@ function reasonStream(input, opts = {}) {
|
|
|
8707
8732
|
if (baseIri) prefixes.setBase(baseIri);
|
|
8708
8733
|
} else {
|
|
8709
8734
|
const n3Text = normalizeReasonerInputSync(input);
|
|
8710
|
-
const toks = lex(n3Text);
|
|
8735
|
+
const toks = lex(n3Text, { rdf: useRdfCompatibility });
|
|
8711
8736
|
const parser = new Parser(toks);
|
|
8712
8737
|
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
8713
8738
|
|
|
@@ -8741,7 +8766,7 @@ function reasonStream(input, opts = {}) {
|
|
|
8741
8766
|
// query-selected triples (not all derived facts).
|
|
8742
8767
|
if (typeof onDerived === 'function') {
|
|
8743
8768
|
for (const qdf of queryDerived) {
|
|
8744
|
-
const payload = { triple: tripleToN3(qdf.fact, prefixes), df: qdf };
|
|
8769
|
+
const payload = { triple: useRdfCompatibility ? tripleToRdfCompatible(qdf.fact, prefixes) : tripleToN3(qdf.fact, prefixes), df: qdf };
|
|
8745
8770
|
if (rdfFactory) {
|
|
8746
8771
|
const quad = maybeTripleToRdfJsQuad(qdf.fact, rdfFactory, skipUnsupportedRdfJs);
|
|
8747
8772
|
if (quad) payload.quad = quad;
|
|
@@ -8758,7 +8783,7 @@ function reasonStream(input, opts = {}) {
|
|
|
8758
8783
|
(df) => {
|
|
8759
8784
|
if (typeof onDerived === 'function') {
|
|
8760
8785
|
const payload = {
|
|
8761
|
-
triple: tripleToN3(df.fact, prefixes),
|
|
8786
|
+
triple: useRdfCompatibility ? tripleToRdfCompatible(df.fact, prefixes) : tripleToN3(df.fact, prefixes),
|
|
8762
8787
|
df,
|
|
8763
8788
|
};
|
|
8764
8789
|
if (rdfFactory) {
|
|
@@ -8779,8 +8804,9 @@ function reasonStream(input, opts = {}) {
|
|
|
8779
8804
|
? facts
|
|
8780
8805
|
: derived.map((d) => d.fact);
|
|
8781
8806
|
|
|
8782
|
-
const closureN3 =
|
|
8783
|
-
|
|
8807
|
+
const closureN3 = useRdfCompatibility
|
|
8808
|
+
? closureTriples.map((t) => tripleToRdfCompatible(t, prefixes)).join('\n')
|
|
8809
|
+
: Array.isArray(logQueryRules) && logQueryRules.length && !proof
|
|
8784
8810
|
? prettyPrintQueryTriples(closureTriples, prefixes)
|
|
8785
8811
|
: closureTriples.map((t) => tripleToN3(t, prefixes)).join('\n');
|
|
8786
8812
|
|
|
@@ -8921,6 +8947,7 @@ module.exports = {
|
|
|
8921
8947
|
printExplanation,
|
|
8922
8948
|
// used by demo worker to stringify derived triples with prefixes
|
|
8923
8949
|
tripleToN3,
|
|
8950
|
+
tripleToRdfCompatible,
|
|
8924
8951
|
// pretty log:query output (when proof comments are disabled)
|
|
8925
8952
|
prettyPrintQueryTriples,
|
|
8926
8953
|
getEnforceHttpsEnabled,
|
|
@@ -9556,45 +9583,62 @@ function stripQuotes(lex) {
|
|
|
9556
9583
|
}
|
|
9557
9584
|
|
|
9558
9585
|
|
|
9559
|
-
// RDF
|
|
9560
|
-
//
|
|
9561
|
-
//
|
|
9562
|
-
// graph
|
|
9563
|
-
//
|
|
9564
|
-
|
|
9565
|
-
|
|
9566
|
-
|
|
9586
|
+
// RDF/TriG compatibility is an opt-in syntax-normalization layer, not a new
|
|
9587
|
+
// reasoning model. Eyeling remains strict N3 by default and N3 internally:
|
|
9588
|
+
// - RDF 1.2 triple terms <<( s p o )>> become singleton graph terms { s p o }.
|
|
9589
|
+
// - TriG named graph blocks g { ... } become g log:nameOf { ... } .
|
|
9590
|
+
// - A top-level default graph block { ... } is unwrapped into ordinary triples.
|
|
9591
|
+
// This mirrors tools/n3gen.js and keeps all downstream parsing/reasoning N3-only.
|
|
9592
|
+
const LOG_NAME_OF_IRI = '<http://www.w3.org/2000/10/swap/log#nameOf>';
|
|
9593
|
+
|
|
9594
|
+
function normalizeRdfCompatibility(inputText) {
|
|
9595
|
+
let text = String(inputText ?? '');
|
|
9596
|
+
|
|
9597
|
+
// Fast path: most Eyeling inputs are ordinary N3 and do not need RDF/TriG
|
|
9598
|
+
// surface-syntax normalization. Avoid scanning large files character-by-character
|
|
9599
|
+
// unless they actually contain RDF 1.2 triple terms, VERSION directives, or a
|
|
9600
|
+
// plausible top-level TriG named graph block.
|
|
9601
|
+
const hasTripleTerms = text.includes('<<(');
|
|
9602
|
+
const hasVersionDirective = /^\s*(?:@version|VERSION)\s+(["'])1\.2\1\s*\.?\s*(?:#.*)?$/im.test(text);
|
|
9603
|
+
const hasNamedGraphCandidate = /(?:^|[.\r\n])\s*(?:GRAPH\s+)?(?:<[^>\r\n]*>|_:[A-Za-z][A-Za-z0-9_-]*|[A-Za-z][A-Za-z0-9_-]*:[^\s{};,.()[\]]*)\s*\{/m.test(text);
|
|
9567
9604
|
|
|
9568
|
-
|
|
9569
|
-
|
|
9605
|
+
if (!hasTripleTerms && !hasVersionDirective && !hasNamedGraphCandidate) return text;
|
|
9606
|
+
|
|
9607
|
+
function isWordChar(ch) {
|
|
9608
|
+
return ch != null && /[A-Za-z0-9_:-]/.test(ch);
|
|
9570
9609
|
}
|
|
9571
9610
|
|
|
9572
|
-
function
|
|
9573
|
-
|
|
9611
|
+
function startsWordAt(s, word, at) {
|
|
9612
|
+
return s.startsWith(word, at) && !isWordChar(s[at - 1]) && !isWordChar(s[at + word.length]);
|
|
9613
|
+
}
|
|
9614
|
+
|
|
9615
|
+
function readStringAt(s, at) {
|
|
9616
|
+
const quote = s[at];
|
|
9617
|
+
let i = at;
|
|
9574
9618
|
let out = quote;
|
|
9575
|
-
const long =
|
|
9619
|
+
const long = s.startsWith(quote.repeat(3), i);
|
|
9576
9620
|
if (long) {
|
|
9577
9621
|
out = quote.repeat(3);
|
|
9578
9622
|
i += 3;
|
|
9579
|
-
while (i <
|
|
9580
|
-
if (
|
|
9623
|
+
while (i < s.length) {
|
|
9624
|
+
if (s.startsWith(quote.repeat(3), i)) {
|
|
9581
9625
|
out += quote.repeat(3);
|
|
9582
9626
|
i += 3;
|
|
9583
|
-
return out;
|
|
9627
|
+
return { text: out, end: i };
|
|
9584
9628
|
}
|
|
9585
|
-
if (
|
|
9586
|
-
out +=
|
|
9629
|
+
if (s[i] === '\\' && i + 1 < s.length) {
|
|
9630
|
+
out += s.slice(i, i + 2);
|
|
9587
9631
|
i += 2;
|
|
9588
9632
|
} else {
|
|
9589
|
-
out +=
|
|
9633
|
+
out += s[i++];
|
|
9590
9634
|
}
|
|
9591
9635
|
}
|
|
9592
|
-
return out;
|
|
9636
|
+
return { text: out, end: i };
|
|
9593
9637
|
}
|
|
9594
9638
|
i += 1;
|
|
9595
9639
|
let escaped = false;
|
|
9596
|
-
while (i <
|
|
9597
|
-
const ch =
|
|
9640
|
+
while (i < s.length) {
|
|
9641
|
+
const ch = s[i++];
|
|
9598
9642
|
out += ch;
|
|
9599
9643
|
if (escaped) {
|
|
9600
9644
|
escaped = false;
|
|
@@ -9604,61 +9648,234 @@ function normalizeRdf12TripleTerms(inputText) {
|
|
|
9604
9648
|
break;
|
|
9605
9649
|
}
|
|
9606
9650
|
}
|
|
9607
|
-
return out;
|
|
9651
|
+
return { text: out, end: i };
|
|
9608
9652
|
}
|
|
9609
9653
|
|
|
9610
|
-
function
|
|
9611
|
-
let
|
|
9612
|
-
|
|
9613
|
-
|
|
9654
|
+
function readIriAt(s, at) {
|
|
9655
|
+
let i = at + 1;
|
|
9656
|
+
let out = '<';
|
|
9657
|
+
while (i < s.length) {
|
|
9658
|
+
const ch = s[i++];
|
|
9614
9659
|
out += ch;
|
|
9615
9660
|
if (ch === '>') break;
|
|
9616
9661
|
}
|
|
9617
|
-
return out;
|
|
9662
|
+
return { text: out, end: i };
|
|
9618
9663
|
}
|
|
9619
9664
|
|
|
9620
|
-
function
|
|
9621
|
-
let
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9665
|
+
function convertTripleTerms(s) {
|
|
9666
|
+
let i = 0;
|
|
9667
|
+
|
|
9668
|
+
function startsAt(needle, at = i) {
|
|
9669
|
+
return s.startsWith(needle, at);
|
|
9670
|
+
}
|
|
9671
|
+
|
|
9672
|
+
function convertUntil(stopToken) {
|
|
9673
|
+
let out = '';
|
|
9674
|
+
while (i < s.length) {
|
|
9675
|
+
if (stopToken && startsAt(stopToken)) {
|
|
9676
|
+
i += stopToken.length;
|
|
9677
|
+
return out;
|
|
9678
|
+
}
|
|
9679
|
+
if (startsAt('<<(')) {
|
|
9680
|
+
i += 3;
|
|
9681
|
+
out += '{ ' + convertUntil(')>>').trim() + ' }';
|
|
9682
|
+
continue;
|
|
9683
|
+
}
|
|
9684
|
+
const ch = s[i];
|
|
9685
|
+
if (ch === '"' || ch === "'") {
|
|
9686
|
+
const str = readStringAt(s, i);
|
|
9687
|
+
out += str.text;
|
|
9688
|
+
i = str.end;
|
|
9689
|
+
continue;
|
|
9690
|
+
}
|
|
9691
|
+
if (ch === '<') {
|
|
9692
|
+
const iri = readIriAt(s, i);
|
|
9693
|
+
out += iri.text;
|
|
9694
|
+
i = iri.end;
|
|
9695
|
+
continue;
|
|
9696
|
+
}
|
|
9697
|
+
if (ch === '#') {
|
|
9698
|
+
while (i < s.length) {
|
|
9699
|
+
const c = s[i++];
|
|
9700
|
+
out += c;
|
|
9701
|
+
if (c === '\n' || c === '\r') break;
|
|
9702
|
+
}
|
|
9703
|
+
continue;
|
|
9704
|
+
}
|
|
9705
|
+
out += ch;
|
|
9706
|
+
i += 1;
|
|
9626
9707
|
}
|
|
9627
|
-
if (
|
|
9628
|
-
|
|
9629
|
-
|
|
9708
|
+
if (stopToken) throw new N3SyntaxError(`Unterminated RDF 1.2 triple term, expected ${stopToken}`);
|
|
9709
|
+
return out;
|
|
9710
|
+
}
|
|
9711
|
+
|
|
9712
|
+
return convertUntil(null);
|
|
9713
|
+
}
|
|
9714
|
+
|
|
9715
|
+
function stripVersionDirectives(s) {
|
|
9716
|
+
return s.replace(/^\s*(?:@version|VERSION)\s+(["'])1\.2\1\s*\.?\s*(?:#.*)?$/gim, '');
|
|
9717
|
+
}
|
|
9718
|
+
|
|
9719
|
+
function skipWsAndComments(s, at) {
|
|
9720
|
+
let i = at;
|
|
9721
|
+
while (i < s.length) {
|
|
9722
|
+
if (/\s/.test(s[i])) {
|
|
9723
|
+
i += 1;
|
|
9724
|
+
continue;
|
|
9725
|
+
}
|
|
9726
|
+
if (s[i] === '#') {
|
|
9727
|
+
while (i < s.length && s[i] !== '\n' && s[i] !== '\r') i += 1;
|
|
9630
9728
|
continue;
|
|
9631
9729
|
}
|
|
9632
|
-
|
|
9730
|
+
break;
|
|
9731
|
+
}
|
|
9732
|
+
return i;
|
|
9733
|
+
}
|
|
9734
|
+
|
|
9735
|
+
function readTermAt(s, at) {
|
|
9736
|
+
if (s[at] === '<') return readIriAt(s, at);
|
|
9737
|
+
let i = at;
|
|
9738
|
+
while (i < s.length && !/\s/.test(s[i]) && !'{}[](),;.'.includes(s[i])) i += 1;
|
|
9739
|
+
if (i === at) return null;
|
|
9740
|
+
const value = s.slice(at, i);
|
|
9741
|
+
if (!value || value.startsWith('@')) return null;
|
|
9742
|
+
return { text: value, end: i };
|
|
9743
|
+
}
|
|
9744
|
+
|
|
9745
|
+
function readBalancedBlock(s, at) {
|
|
9746
|
+
if (s[at] !== '{') return null;
|
|
9747
|
+
let i = at;
|
|
9748
|
+
let depth = 0;
|
|
9749
|
+
while (i < s.length) {
|
|
9750
|
+
const ch = s[i];
|
|
9633
9751
|
if (ch === '"' || ch === "'") {
|
|
9634
|
-
|
|
9752
|
+
i = readStringAt(s, i).end;
|
|
9635
9753
|
continue;
|
|
9636
9754
|
}
|
|
9637
9755
|
if (ch === '<') {
|
|
9638
|
-
|
|
9756
|
+
i = readIriAt(s, i).end;
|
|
9639
9757
|
continue;
|
|
9640
9758
|
}
|
|
9641
9759
|
if (ch === '#') {
|
|
9642
|
-
while (i <
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9760
|
+
while (i < s.length && s[i] !== '\n' && s[i] !== '\r') i += 1;
|
|
9761
|
+
continue;
|
|
9762
|
+
}
|
|
9763
|
+
if (ch === '{') depth += 1;
|
|
9764
|
+
if (ch === '}') {
|
|
9765
|
+
depth -= 1;
|
|
9766
|
+
i += 1;
|
|
9767
|
+
if (depth === 0) return { text: s.slice(at, i), inner: s.slice(at + 1, i - 1), end: i };
|
|
9647
9768
|
continue;
|
|
9648
9769
|
}
|
|
9649
|
-
out += ch;
|
|
9650
9770
|
i += 1;
|
|
9651
9771
|
}
|
|
9652
|
-
|
|
9772
|
+
throw new N3SyntaxError('Unterminated RDF/TriG graph block, expected }');
|
|
9773
|
+
}
|
|
9774
|
+
|
|
9775
|
+
function normalizeNamedGraphs(s) {
|
|
9776
|
+
let out = '';
|
|
9777
|
+
let i = 0;
|
|
9778
|
+
let statementStart = true;
|
|
9779
|
+
let braceDepth = 0;
|
|
9780
|
+
|
|
9781
|
+
while (i < s.length) {
|
|
9782
|
+
if (statementStart && braceDepth === 0) {
|
|
9783
|
+
const termStart = skipWsAndComments(s, i);
|
|
9784
|
+
out += s.slice(i, termStart);
|
|
9785
|
+
i = termStart;
|
|
9786
|
+
|
|
9787
|
+
// Top-level TriG default graph block: { ... } .
|
|
9788
|
+
if (s[i] === '{') {
|
|
9789
|
+
const block = readBalancedBlock(s, i);
|
|
9790
|
+
const after = skipWsAndComments(s, block.end);
|
|
9791
|
+
if (after >= s.length || s[after] === '.') {
|
|
9792
|
+
out += block.inner.trim();
|
|
9793
|
+
if (block.inner.trim() && !/\n$/.test(block.inner)) out += '\n';
|
|
9794
|
+
i = after < s.length && s[after] === '.' ? after + 1 : after;
|
|
9795
|
+
statementStart = true;
|
|
9796
|
+
continue;
|
|
9797
|
+
}
|
|
9798
|
+
// It is an ordinary N3 formula subject, not a TriG default graph.
|
|
9799
|
+
out += block.text;
|
|
9800
|
+
i = block.end;
|
|
9801
|
+
statementStart = false;
|
|
9802
|
+
continue;
|
|
9803
|
+
}
|
|
9804
|
+
|
|
9805
|
+
let graphKeyword = false;
|
|
9806
|
+
if (startsWordAt(s, 'GRAPH', i)) {
|
|
9807
|
+
graphKeyword = true;
|
|
9808
|
+
i += 'GRAPH'.length;
|
|
9809
|
+
i = skipWsAndComments(s, i);
|
|
9810
|
+
}
|
|
9811
|
+
|
|
9812
|
+
const term = readTermAt(s, i);
|
|
9813
|
+
if (term && !['@prefix', '@base', 'PREFIX', 'BASE', 'VERSION'].includes(term.text)) {
|
|
9814
|
+
const afterTerm = skipWsAndComments(s, term.end);
|
|
9815
|
+
if (s[afterTerm] === '{') {
|
|
9816
|
+
const block = readBalancedBlock(s, afterTerm);
|
|
9817
|
+
const afterBlock = skipWsAndComments(s, block.end);
|
|
9818
|
+
out += `${term.text} ${LOG_NAME_OF_IRI} ${block.text} .`;
|
|
9819
|
+
i = afterBlock < s.length && s[afterBlock] === '.' ? afterBlock + 1 : block.end;
|
|
9820
|
+
statementStart = true;
|
|
9821
|
+
continue;
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9824
|
+
|
|
9825
|
+
// Not TriG named-graph syntax after all; copy the first character and
|
|
9826
|
+
// continue as ordinary N3.
|
|
9827
|
+
if (graphKeyword) {
|
|
9828
|
+
out += 'GRAPH ';
|
|
9829
|
+
statementStart = false;
|
|
9830
|
+
} else if (i < s.length) {
|
|
9831
|
+
const copied = s[i++];
|
|
9832
|
+
out += copied;
|
|
9833
|
+
if (!/\s/.test(copied)) statementStart = false;
|
|
9834
|
+
}
|
|
9835
|
+
} else {
|
|
9836
|
+
const ch = s[i];
|
|
9837
|
+
out += ch;
|
|
9838
|
+
if (ch === '"' || ch === "'") {
|
|
9839
|
+
const str = readStringAt(s, i);
|
|
9840
|
+
out = out.slice(0, -1) + str.text;
|
|
9841
|
+
i = str.end;
|
|
9842
|
+
continue;
|
|
9843
|
+
}
|
|
9844
|
+
if (ch === '<') {
|
|
9845
|
+
const iri = readIriAt(s, i);
|
|
9846
|
+
out = out.slice(0, -1) + iri.text;
|
|
9847
|
+
i = iri.end;
|
|
9848
|
+
continue;
|
|
9849
|
+
}
|
|
9850
|
+
if (ch === '#') {
|
|
9851
|
+
i += 1;
|
|
9852
|
+
while (i < s.length) {
|
|
9853
|
+
const c = s[i++];
|
|
9854
|
+
out += c;
|
|
9855
|
+
if (c === '\n' || c === '\r') break;
|
|
9856
|
+
}
|
|
9857
|
+
continue;
|
|
9858
|
+
}
|
|
9859
|
+
if (ch === '{') braceDepth += 1;
|
|
9860
|
+
else if (ch === '}' && braceDepth > 0) braceDepth -= 1;
|
|
9861
|
+
else if (ch === '.' && braceDepth === 0) statementStart = true;
|
|
9862
|
+
else if (!/\s/.test(ch)) statementStart = false;
|
|
9863
|
+
i += 1;
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9866
|
+
|
|
9653
9867
|
return out;
|
|
9654
9868
|
}
|
|
9655
9869
|
|
|
9656
|
-
|
|
9657
|
-
|
|
9870
|
+
if (hasTripleTerms) text = convertTripleTerms(text);
|
|
9871
|
+
if (hasVersionDirective) text = stripVersionDirectives(text);
|
|
9872
|
+
if (hasVersionDirective || hasNamedGraphCandidate) text = normalizeNamedGraphs(text);
|
|
9873
|
+
return text;
|
|
9658
9874
|
}
|
|
9659
9875
|
|
|
9660
|
-
function lex(inputText) {
|
|
9661
|
-
|
|
9876
|
+
function lex(inputText, opts = {}) {
|
|
9877
|
+
const rdf = !!(opts && opts.rdf);
|
|
9878
|
+
if (rdf) inputText = normalizeRdfCompatibility(inputText);
|
|
9662
9879
|
const chars = Array.from(inputText);
|
|
9663
9880
|
const n = chars.length;
|
|
9664
9881
|
let i = 0;
|
|
@@ -10119,7 +10336,7 @@ function lex(inputText) {
|
|
|
10119
10336
|
return tokens;
|
|
10120
10337
|
}
|
|
10121
10338
|
|
|
10122
|
-
module.exports = { Token, N3SyntaxError, lex, decodeN3StringEscapes };
|
|
10339
|
+
module.exports = { Token, N3SyntaxError, lex, normalizeRdfCompatibility, decodeN3StringEscapes };
|
|
10123
10340
|
|
|
10124
10341
|
};
|
|
10125
10342
|
__modules["lib/multisource.js"] = function(require, module, exports){
|
|
@@ -10228,8 +10445,14 @@ function prefixesUsedInTokens(tokens, prefEnv) {
|
|
|
10228
10445
|
}
|
|
10229
10446
|
|
|
10230
10447
|
function parseN3Text(text, opts = {}) {
|
|
10231
|
-
const {
|
|
10232
|
-
|
|
10448
|
+
const {
|
|
10449
|
+
baseIri = '',
|
|
10450
|
+
label = '<input>',
|
|
10451
|
+
keepSourceArtifacts = true,
|
|
10452
|
+
collectUsedPrefixes = false,
|
|
10453
|
+
rdf = false,
|
|
10454
|
+
} = opts || {};
|
|
10455
|
+
const tokens = lex(text, { rdf });
|
|
10233
10456
|
const parser = new Parser(tokens);
|
|
10234
10457
|
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
10235
10458
|
const [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
|
|
@@ -10423,6 +10646,7 @@ function parseN3SourceList(input, opts = {}) {
|
|
|
10423
10646
|
baseIri: source.baseIri || (sources.length === 1 ? defaultBaseIri : ''),
|
|
10424
10647
|
collectUsedPrefixes: true,
|
|
10425
10648
|
keepSourceArtifacts: !!opts.keepSourceArtifacts,
|
|
10649
|
+
rdf: !!opts.rdf,
|
|
10426
10650
|
}),
|
|
10427
10651
|
);
|
|
10428
10652
|
return mergeParsedDocuments(parsed, {
|
|
@@ -11813,6 +12037,7 @@ const {
|
|
|
11813
12037
|
isOwlSameAsPred,
|
|
11814
12038
|
isLogImplies,
|
|
11815
12039
|
isLogImpliedBy,
|
|
12040
|
+
LOG_NS,
|
|
11816
12041
|
} = require('./prelude');
|
|
11817
12042
|
|
|
11818
12043
|
function stripQuotes(lex) {
|
|
@@ -12142,7 +12367,111 @@ function prettyPrintQueryTriples(triples, prefixes) {
|
|
|
12142
12367
|
return blocks.join('\n');
|
|
12143
12368
|
}
|
|
12144
12369
|
|
|
12145
|
-
|
|
12370
|
+
|
|
12371
|
+
// ---------------------------------------------------------------------------
|
|
12372
|
+
// RDF compatibility output
|
|
12373
|
+
// ---------------------------------------------------------------------------
|
|
12374
|
+
|
|
12375
|
+
function isRdfTripleTermSubject(t) {
|
|
12376
|
+
return t instanceof Iri || t instanceof Blank;
|
|
12377
|
+
}
|
|
12378
|
+
|
|
12379
|
+
function isRdfTripleTermPredicate(t) {
|
|
12380
|
+
return t instanceof Iri;
|
|
12381
|
+
}
|
|
12382
|
+
|
|
12383
|
+
function isRdfTripleTermObject(t) {
|
|
12384
|
+
return t instanceof Iri || t instanceof Blank || t instanceof Literal;
|
|
12385
|
+
}
|
|
12386
|
+
|
|
12387
|
+
function isRdfTripleTermGraph(t) {
|
|
12388
|
+
if (!(t instanceof GraphTerm)) return false;
|
|
12389
|
+
if (!Array.isArray(t.triples) || t.triples.length !== 1) return false;
|
|
12390
|
+
const tr = t.triples[0];
|
|
12391
|
+
return isRdfTripleTermSubject(tr.s) && isRdfTripleTermPredicate(tr.p) && isRdfTripleTermObject(tr.o);
|
|
12392
|
+
}
|
|
12393
|
+
|
|
12394
|
+
|
|
12395
|
+
function isLogNameOfPred(p) {
|
|
12396
|
+
return p instanceof Iri && p.value === LOG_NS + 'nameOf';
|
|
12397
|
+
}
|
|
12398
|
+
|
|
12399
|
+
function isRdfNamedGraphLabel(t) {
|
|
12400
|
+
return t instanceof Iri || t instanceof Blank;
|
|
12401
|
+
}
|
|
12402
|
+
|
|
12403
|
+
function rdfCompatibleGraphBlock(graph, prefixes) {
|
|
12404
|
+
const indent = ' ';
|
|
12405
|
+
const indentBlock = (str) =>
|
|
12406
|
+
str
|
|
12407
|
+
.split(/\r?\n/)
|
|
12408
|
+
.map((ln) => (ln.length ? indent + ln : ln))
|
|
12409
|
+
.join('\n');
|
|
12410
|
+
|
|
12411
|
+
let s = '{\n';
|
|
12412
|
+
for (const inner of graph.triples || []) {
|
|
12413
|
+
const block = tripleToRdfCompatible(inner, prefixes).trimEnd();
|
|
12414
|
+
if (block) s += indentBlock(block) + '\n';
|
|
12415
|
+
}
|
|
12416
|
+
s += '}';
|
|
12417
|
+
return s;
|
|
12418
|
+
}
|
|
12419
|
+
|
|
12420
|
+
function rdfPredicateToText(p, prefixes) {
|
|
12421
|
+
return isRdfTypePred(p) ? 'a' : termToN3(p, prefixes);
|
|
12422
|
+
}
|
|
12423
|
+
|
|
12424
|
+
function termToRdfCompatible(t, pref) {
|
|
12425
|
+
if (isRdfTripleTermGraph(t)) {
|
|
12426
|
+
const tr = t.triples[0];
|
|
12427
|
+
const s = termToN3(tr.s, pref);
|
|
12428
|
+
const p = rdfPredicateToText(tr.p, pref);
|
|
12429
|
+
const o = termToN3(tr.o, pref);
|
|
12430
|
+
return `<<( ${s} ${p} ${o} )>>`;
|
|
12431
|
+
}
|
|
12432
|
+
return termToN3(t, pref);
|
|
12433
|
+
}
|
|
12434
|
+
|
|
12435
|
+
function tripleToRdfCompatible(tr, prefixes) {
|
|
12436
|
+
if (isLogNameOfPred(tr.p) && isRdfNamedGraphLabel(tr.s) && tr.o instanceof GraphTerm) {
|
|
12437
|
+
return `${termToN3(tr.s, prefixes)} ${rdfCompatibleGraphBlock(tr.o, prefixes)}`;
|
|
12438
|
+
}
|
|
12439
|
+
|
|
12440
|
+
if (isLogImplies(tr.p)) {
|
|
12441
|
+
const s = termToRdfCompatible(tr.s, prefixes);
|
|
12442
|
+
const o = termToRdfCompatible(tr.o, prefixes);
|
|
12443
|
+
return `${s} => ${o} .`;
|
|
12444
|
+
}
|
|
12445
|
+
|
|
12446
|
+
if (isLogImpliedBy(tr.p)) {
|
|
12447
|
+
const s = termToRdfCompatible(tr.s, prefixes);
|
|
12448
|
+
const o = termToRdfCompatible(tr.o, prefixes);
|
|
12449
|
+
return `${s} <= ${o} .`;
|
|
12450
|
+
}
|
|
12451
|
+
|
|
12452
|
+
const s = termToRdfCompatible(tr.s, prefixes);
|
|
12453
|
+
const p = isRdfTypePred(tr.p) ? 'a' : isOwlSameAsPred(tr.p) ? '=' : termToN3(tr.p, prefixes);
|
|
12454
|
+
const o = termToRdfCompatible(tr.o, prefixes);
|
|
12455
|
+
return `${s} ${p} ${o} .`;
|
|
12456
|
+
}
|
|
12457
|
+
|
|
12458
|
+
function prettyPrintQueryTriplesRdfCompatible(triples, prefixes) {
|
|
12459
|
+
return triples.map((tr) => tripleToRdfCompatible(tr, prefixes)).join('\n');
|
|
12460
|
+
}
|
|
12461
|
+
|
|
12462
|
+
function needsRdf12Version(text) {
|
|
12463
|
+
return typeof text === 'string' && text.includes('<<(');
|
|
12464
|
+
}
|
|
12465
|
+
|
|
12466
|
+
module.exports = {
|
|
12467
|
+
termToN3,
|
|
12468
|
+
tripleToN3,
|
|
12469
|
+
prettyPrintQueryTriples,
|
|
12470
|
+
termToRdfCompatible,
|
|
12471
|
+
tripleToRdfCompatible,
|
|
12472
|
+
prettyPrintQueryTriplesRdfCompatible,
|
|
12473
|
+
needsRdf12Version,
|
|
12474
|
+
};
|
|
12146
12475
|
|
|
12147
12476
|
};
|
|
12148
12477
|
__modules["lib/rdfjs.js"] = function(require, module, exports){
|