Skip to content

Commit ca776f1

Browse files
author
Tim Berners-Lee
committed
Working on patch parser, passes firs simple tests in the node-lpd-httpd
1 parent a4cfa9b commit ca776f1

File tree

4 files changed

+109
-35
lines changed

4 files changed

+109
-35
lines changed

n3parser.js

+27-16
Original file line numberDiff line numberDiff line change
@@ -1117,28 +1117,39 @@ __SinkParser.prototype.skipSpace = function(str, i) {
11171117
/*
11181118
Skip white space, newlines and comments.
11191119
return -1 if EOF, else position of first non-ws character*/
1120-
var tmp = str;
1120+
11211121
var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
11221122
for (var j = (i ? i : 0); j < str.length; j++) {
1123-
if (whitespace.indexOf(str.charAt(j)) === -1) {
1123+
var ch = str.charAt(j);
1124+
// console.log(" skipspace j= "+j + " i= " + i + " n= " + str.length);
1125+
// console.log(" skipspace ch <" + ch + ">");
1126+
if (whitespace.indexOf(ch) < 0 ) { //not ws
1127+
// console.log(" skipspace 2 ch <" + ch + ">");
11241128
if( str.charAt(j)==='#' ) {
1125-
str = str.slice(i).replace(/^[^\n]*\n/,"");
1126-
i=0;
1127-
j=-1;
1128-
} else {
1129-
break;
1129+
for (;; j++) {
1130+
// console.log(" skipspace2 j= "+j + " i= " + i + " n= " + str.length);
1131+
if (j === str.length) {
1132+
return -1; // EOF
1133+
}
1134+
if (str.charAt(j) === '\n') {
1135+
this.lines = this.lines + 1;
1136+
break;
1137+
}
1138+
};
1139+
} else { // Not hash - something interesting
1140+
// console.log(" skipspace 3 ch <" + ch + ">");
1141+
return j
1142+
}
1143+
} else { // Whitespace
1144+
// console.log(" skipspace 5 ch <" + ch + ">");
1145+
if (str.charAt(j) === '\n') {
1146+
this.lines = this.lines + 1;
11301147
}
11311148
}
1132-
if (str.charAt(j) == '\n') {
1133-
this.lines = this.lines + 1;
1134-
}
1135-
}
1136-
var val = (tmp.length - str.length) + j;
1137-
if( val === tmp.length ) {
1138-
return -1;
1139-
}
1140-
return val;
1149+
} // next j
1150+
return -1; // EOF
11411151
};
1152+
11421153
__SinkParser.prototype.variable = function(str, i, res) {
11431154
/*
11441155
?abc -> variable(:abc)

patchParser.js

+42-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
// Parse a simple SPARL-Update subset syntax for patches.
32
//
43
// This parses
@@ -12,13 +11,20 @@ $rdf.sparqlUpdateParser = function(str, kb, base) {
1211
var keywords = [ 'INSERT', 'DELETE', 'WHERE' ]
1312
var SQNS = $rdf.Namespace('http://www.w3.org/ns/pim/patch#');
1413
var p = $rdf.N3Parser(kb, kb, base, base, null, null, "", null);
15-
// p.loadBuf("<#s> <#p> (1 2 2).");
16-
res = [];
1714
var clauses = {};
1815

19-
function badSyntax(uri, lines, str, i, why) {
20-
return ( ( ( ( ( ( ( ( "Line " + ( lines + 1 ) ) + " of <" ) + uri ) + ">: Bad syntax:\n " ) + why ) + "\nat: \"" ) + str.slice(i, (i + 30))) + "\"" ) ;
21-
};
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+
2228

2329
i = 0;
2430
var query = kb.sym(base+ '#query'); // Invent a URI for the query
@@ -29,40 +35,58 @@ $rdf.sparqlUpdateParser = function(str, kb, base) {
2935
var j = p.skipSpace(str, i);
3036
if (j < 0) {
3137
return clauses
32-
// throw badSyntax(p._thisDoc, p.lines, str, j, "needed INSERT, DELETE etc, found end.");
3338
}
34-
// console.log("B Now at j= " + j)
35-
39+
// console.log("B After space at j= " + j)
40+
var found = false;
3641
for (k=0; k< keywords.length; k++) {
3742
key = keywords[k];
3843
if (str.slice(j, j + key.length) === key) {
3944
// console.log("C got one " + key);
4045
i = p.skipSpace(str, j+ key.length);
46+
// console.log("D after space at i= " + i);
4147
if (i < 0) {
42-
throw badSyntax(p._thisDoc, p.lines, str, i, "needed {...} after "+key);
48+
throw badSyntax(p._thisDoc, p.lines, str, j+ key.length, "found EOF, needed {...} after "+key);
4349
};
4450
if (key === 'INSERT' && str.slice(i, i+4) === 'DATA') { // Some wanted 'DATA'. Whatever
45-
i = p.skipSpace(str, i+4);
46-
if (i < 0) {
47-
throw badSyntax(p._thisDoc, p.lines, str, i, "needed {...} after INSERT DATA "+key);
51+
j = p.skipSpace(str, i+4);
52+
if (j < 0) {
53+
throw badSyntax(p._thisDoc, p.lines, str, i+4, "needed {...} after INSERT DATA "+key);
4854
};
55+
i = j;
4956
}
5057
var res2 = [];
51-
var m = p.node(str, i, res2);
52-
// console.log("M Now at m= " + m)
53-
// console.log("M Now at i= " + i)
58+
var j = p.node(str, i, res2);
59+
// console.log("M Now at j= " + j + " i= " + i)
5460

55-
if (m < 0) {
61+
if (j < 0) {
5662
throw badSyntax(p._thisDoc, p.lines, str, i,
5763
"bad syntax or EOF in {...} after " + key);
5864
}
5965
clauses[key.toLowerCase()] = res2[0];
6066
// print("res2[0] for "+key+ " is " + res2[0]); // @@ debug @@@@@@
6167
kb.add(query, SQNS(key.lower), res2[0]);
6268
// key is the keyword and res2 has the contents
63-
i = m
69+
found = true;
70+
i = j;
6471
}
6572
};
73+
if (!found && str.slice(j, j+7) === '@prefix') {
74+
var i = p.directive(str, j);
75+
if (i < 0) {
76+
throw badSyntax(p._thisDoc, p.lines, str, i,
77+
"bad syntax or EOF after @prefix ");
78+
}
79+
// console.log("P before dot i= " + i)
80+
i = p.checkDot(str, i);
81+
// console.log("Q after dot i= " + i)
82+
found = true;
83+
}
84+
if (!found) {
85+
// console.log("Bad syntax " + j)
86+
throw badSyntax(p._thisDoc, p.lines, str, j,
87+
"Unknown syntax at start of statememt: '" + str.slice(j).slice(0,20) +"'")
88+
}
89+
6690
} // while
6791
//return clauses
6892

serialize.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,12 @@ __Serializer.prototype.statementsToN3 = function(sts) {
379379
if (typeof sts == 'undefined') {
380380
throw('Cant find statements for '+subject);
381381
}
382-
sts.sort();
382+
383+
var SPO = function(x, y) {
384+
return $rdf.Util.heavyCompareSPO(x, y, this.store)
385+
}
386+
sts.sort(); // 2014-09-30
387+
// sts.sort(SPO); // 2014-09-30
383388
var objects = [];
384389
for (var i=0; i<sts.length; i++) {
385390
var st = sts[i];

util.js

+34
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,41 @@ $rdf.Util.variablesIn = function(g) {
296296
return vars;
297297
};
298298

299+
// Heavy comparison is for repeatable canonical ordering
300+
$rdf.Util.heavyCompare = function(x, y, g) {
301+
var nonBlank = function(x) {
302+
return (x.termType === 'bnode') ? null : x;
303+
}
304+
var signature = function(b) {
305+
var lis = g.statementsMatching(x).map(function(st){
306+
return ('' + nonBlank(st.subject) + ' ' + nonBlank(st.predicate)
307+
+ ' ' + nonBlank(st.object));
308+
}).concat(g.statementsMatching(undefined, undefined, x).map(function(st){
309+
return ('' + nonBlank(st.subject) + ' ' + nonBlank(st.predicate)
310+
+ ' ' + nonBlank(st.object));
311+
}))
312+
lis.sort();
313+
return lis.join('\n');
314+
}
315+
if ((x.termType === 'bnode') || (y.termType === 'bnode')) {
316+
if (x.compareTerm(y) === 0) return 0; // Same
317+
if (signature(x) > signature(y)) return +1;
318+
if (signature(x) < signature(y)) return -1;
319+
return x.compareTerm(y); // Too bad -- this order not canonical.
320+
//throw "different bnodes indistinquishable for sorting"
321+
} else {
322+
return x.compareTerm(y);
323+
}
324+
};
299325

326+
$rdf.Util.heavyCompareSPO = function(x, y, g) {
327+
var comp = $rdf.Util.heavyCompare;
328+
var d = comp(x.subject, y.subject, g);
329+
if (d) return d;
330+
d = comp(x.predicate, y.predicate, g);
331+
if (d) return d;
332+
return comp(x.object, y.object, g);
333+
};
300334

301335

302336
///////////////////// Parse XML

0 commit comments

Comments
 (0)