Skip to content

Commit a4cfa9b

Browse files
author
Tim Berners-Lee
committed
Refine patchParser for LDP node server; add code untested for repeatable ordering of bnodes in serializer with rdf.Util.heavyCompare. This designed to efficiciently store patched turtle files in version control systems
1 parent 947d192 commit a4cfa9b

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed

ldpatchParser.js

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
2+
// Parse LDPATCH subset syntax for patches.
3+
//
4+
// http://www.w3.org/TR/ldpatch
5+
//
6+
//
7+
8+
$rdf.LDPatchParser = function(str, kb, base) {
9+
var i,j,k;
10+
11+
var SQNS = $rdf.Namespace('http://www.w3.org/ns/pim/patch#');
12+
var p = $rdf.N3Parser(kb, kb, base, base, null, null, "", null);
13+
var res = [];
14+
var clauses = [];
15+
16+
var badSyntax = function (uri, lines, str, i, why) {
17+
return ("Line " + ( lines + 1 ) + " of <" + uri + ">: Bad syntax:\n " +
18+
why + "\n at: \"" + str.slice(i, (i + 30)) + "\"" ) ;
19+
};
20+
21+
var check = function(next, last, message) {
22+
if (next < 0) {
23+
throw badSyntax(p._thisDoc, p.lines, str, j, last, message);
24+
};
25+
return next;
26+
};
27+
28+
var positiveInteger2 = function(str, i, res) {
29+
var j = p.skipSpace(str, i);
30+
if (j < 0) return -1;
31+
var k = j;
32+
while (( j < str.length) && ('0123456789'.indexOf(str[j]) >=0)) {
33+
j++;
34+
}
35+
if (k === j) return -1;
36+
res.push(parseInt(str.slice(k,j)))
37+
return j
38+
}
39+
40+
var expect = function(str, i, word) {
41+
var j = p.skipSpace(str, i);
42+
if (j >=0 && str.slice(j, j+word.length) == word) return j+word.length;
43+
return -1;
44+
}
45+
46+
var ldppath = function (str, pointer, res) {
47+
var i, j, k, inverse, step;
48+
j = p.skipSpace(str, pointer);
49+
check(j, pointer, "Expected / or ! or [ as path");
50+
i = j +1; // i is pointer
51+
var path = [];
52+
switch (str[j]) {
53+
case '/': // Path step
54+
var j = p.skipSpace(str, i);
55+
check(j, i, "Found end, expected ^ or URI or 0-9 after /");
56+
57+
if ('0123456789.'.indexOf(str[j]) >= 0) { // "Index"
58+
res = []
59+
step = { 'type': 'index', from: 0, to: 0}
60+
j = positiveInteger2(str, i, res);
61+
if (j >= 0) {
62+
step.from = res.pop()
63+
i = j;
64+
}
65+
66+
j = expect(str, i, '..');
67+
i = check(j, i, "Expected .. in index in path");
68+
69+
j = positiveInteger2(str, i, res);
70+
if (j >= 0) {
71+
step.to = res.pop()
72+
i = j;
73+
}
74+
path.push(step);
75+
// i is pointer
76+
break;
77+
78+
} else {
79+
step = { 'type': 'arc', 'inverse': (str[j] === '^') };
80+
if (step.inverse) {
81+
i = p.skipSpace(str, j+1);
82+
j = check(i, j+1, "EOF found after /^");
83+
}
84+
i = p.node(str, j, res);
85+
if (i <0) throw badSyntax(p._thisDoc, p.lines, str, j,
86+
"bad URI in step ");
87+
step.predicate = res[0];
88+
};
89+
path.push(step);
90+
break;
91+
92+
case '!':
93+
path.push({'type': 'unique'});
94+
break;
95+
96+
case '[': // Constraint ::= '[' Path ( '=' Value )? ']' | '!'
97+
step = { 'type': 'branch'};
98+
var nested = []
99+
j = j + 1 // skip bracket
100+
i = ldppath(str, j+1, nested)
101+
if (i>0) {
102+
step.path = nested.pop();
103+
j = i
104+
}
105+
i = p.skipSpace(str, j)
106+
check(i, j, "found end of file when expected ] or =");
107+
if (str[i] == '"') {
108+
j = p.skipSpace(str, i++);
109+
check(j, i+1, "expected node after = in path constraint, found end of file");
110+
i = p.node(str, j, nested)
111+
check(i, j, "expected node after = in path constraint");
112+
step.final = nested.pop();
113+
j = p.skipSpace(str, i)
114+
check(j, i, "found end of file when expected ]");
115+
}
116+
if (str[i] !==']') {
117+
check(-1, i, "expected ] or = at end of path constraint")
118+
}
119+
path.push(step);
120+
break;
121+
122+
default:
123+
check(-1, j, "Expected / or ! or [ in path");
124+
break;
125+
}
126+
};
127+
128+
129+
i = 0;
130+
var query = kb.sym(base+ '#query'); // Invent a URI for the query
131+
132+
while (true) {
133+
res = []
134+
j = p.bareWord(str, i, res);
135+
if (j<0) return clauses; // End of file
136+
137+
switch (res[0]) {
138+
139+
case '@prefix':
140+
var i = p.directive(str, j);
141+
check(i, j, "bad syntax or EOF after @prefix ");
142+
i = p.checkDot(str, i);
143+
break;
144+
145+
case 'D':
146+
case 'Delete':
147+
case 'A':
148+
case 'Add':
149+
for (k-0; k<3; k++) {
150+
var i = p.node(str, j, res);
151+
j = check(i, j, "Bad triple after " + res[0]);
152+
}
153+
i = p.checkDot(str, j);
154+
res[0] = res[0][0]; // For uniformity, just initial
155+
clauses.push(res); // [ command, s, p, o ]
156+
j = i;
157+
break;
158+
159+
case 'B':
160+
case 'Bind':
161+
i = p.variable(str, j, res)
162+
check(i, j, "Expected variable after " + res[0]);
163+
// @@@@@@@@ TBC
164+
break;
165+
166+
case 'UL':
167+
case 'UpdateList':
168+
// @@@ TBC
169+
break;
170+
default:
171+
check(-1, i, "Unknown syntax start of statement: "+res[0]);
172+
} // switch
173+
174+
//return clauses
175+
}
176+
}; // End of LDPatchParser
177+

0 commit comments

Comments
 (0)