summaryrefslogtreecommitdiff
path: root/src/runtime/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/javascript')
-rw-r--r--src/runtime/javascript/gflib.js802
1 files changed, 401 insertions, 401 deletions
diff --git a/src/runtime/javascript/gflib.js b/src/runtime/javascript/gflib.js
index 97e98aab2..45bb32d3d 100644
--- a/src/runtime/javascript/gflib.js
+++ b/src/runtime/javascript/gflib.js
@@ -1,38 +1,38 @@
function GFGrammar(abstract, concretes) {
- this.abstract = abstract;
- this.concretes = concretes;
+ this.abstract = abstract;
+ this.concretes = concretes;
}
-/* Translates a string from any concrete syntax to all concrete syntaxes.
+/* Translates a string from any concrete syntax to all concrete syntaxes.
Uses the start category of the grammar.
*/
GFGrammar.prototype.translate = function (input, fromLang, toLang) {
- var outputs = new Object();
- var fromConcs = this.concretes;
- if (fromLang) {
- fromConcs = new Object();
- fromConcs[fromLang] = this.concretes[fromLang];
- }
- var toConcs = this.concretes;
- if (toLang) {
- toConcs = new Object();
- toConcs[toLang] = this.concretes[toLang];
- }
- for (var c1 in fromConcs) {
- var concrete = this.concretes[c1];
- var trees = concrete.parseString(input, this.abstract.startcat);
- if (trees.length > 0) {
- outputs[c1] = new Array();
- for (var i in trees) {
- outputs[c1][i] = new Object();
- for (var c2 in toConcs) {
- outputs[c1][i][c2] = this.concretes[c2].linearize(trees[i]);
- }
- }
- }
- }
- return outputs;
+ var outputs = new Object();
+ var fromConcs = this.concretes;
+ if (fromLang) {
+ fromConcs = new Object();
+ fromConcs[fromLang] = this.concretes[fromLang];
+ }
+ var toConcs = this.concretes;
+ if (toLang) {
+ toConcs = new Object();
+ toConcs[toLang] = this.concretes[toLang];
+ }
+ for (var c1 in fromConcs) {
+ var concrete = this.concretes[c1];
+ var trees = concrete.parseString(input, this.abstract.startcat);
+ if (trees.length > 0) {
+ outputs[c1] = new Array();
+ for (var i in trees) {
+ outputs[c1][i] = new Object();
+ for (var c2 in toConcs) {
+ outputs[c1][i][c2] = this.concretes[c2].linearize(trees[i]);
+ }
+ }
+ }
+ }
+ return outputs;
}
@@ -47,56 +47,56 @@ String.prototype.setTag = function (tag) { this.tag = tag; };
/* Abstract syntax trees */
function Fun(name) {
- this.name = name;
- this.args = new Array();
- for (var i = 1; i < arguments.length; i++) {
- this.args[i-1] = arguments[i];
- }
+ this.name = name;
+ this.args = new Array();
+ for (var i = 1; i < arguments.length; i++) {
+ this.args[i-1] = arguments[i];
+ }
}
Fun.prototype.print = function () { return this.show(0); } ;
Fun.prototype.show = function (prec) {
- if (this.isMeta()) {
- if (isUndefined(this.type)) {
- return '?';
- } else {
- var s = '?:' + this.type;
- if (prec > 0) {
- s = "(" + s + ")" ;
- }
- return s;
- }
- } else {
- var s = this.name;
- var cs = this.args;
- for (var i in cs) {
- s += " " + (isUndefined(cs[i]) ? "undefined" : cs[i].show(1));
- }
- if (prec > 0 && cs.length > 0) {
- s = "(" + s + ")" ;
- }
- return s;
- }
+ if (this.isMeta()) {
+ if (isUndefined(this.type)) {
+ return '?';
+ } else {
+ var s = '?:' + this.type;
+ if (prec > 0) {
+ s = "(" + s + ")" ;
+ }
+ return s;
+ }
+ } else {
+ var s = this.name;
+ var cs = this.args;
+ for (var i in cs) {
+ s += " " + (isUndefined(cs[i]) ? "undefined" : cs[i].show(1));
+ }
+ if (prec > 0 && cs.length > 0) {
+ s = "(" + s + ")" ;
+ }
+ return s;
+ }
};
Fun.prototype.getArg = function (i) {
- return this.args[i];
+ return this.args[i];
};
Fun.prototype.setArg = function (i,c) {
- this.args[i] = c;
+ this.args[i] = c;
};
Fun.prototype.isMeta = function() {
- return this.name == '?';
+ return this.name == '?';
} ;
Fun.prototype.isComplete = function() {
- if (this.isMeta()) {
- return false;
- } else {
- for (var i in this.args) {
- if (!this.args[i].isComplete()) {
- return false;
- }
- }
- return true;
- }
+ if (this.isMeta()) {
+ return false;
+ } else {
+ for (var i in this.args) {
+ if (!this.args[i].isComplete()) {
+ return false;
+ }
+ }
+ return true;
+ }
} ;
Fun.prototype.isLiteral = function() {
return (/^[\"\-\d]/).test(this.name);
@@ -120,146 +120,146 @@ Fun.prototype.isEqual = function(obj) {
if (!this.args[i].isEqual(obj.args[i]))
return false;
}
-
+
return true;
}
/* Type annotation */
function GFAbstract(startcat, types) {
- this.startcat = startcat;
- this.types = types;
+ this.startcat = startcat;
+ this.types = types;
}
GFAbstract.prototype.addType = function(fun, args, cat) {
- this.types[fun] = new Type(args, cat);
+ this.types[fun] = new Type(args, cat);
} ;
GFAbstract.prototype.getArgs = function(fun) {
- return this.types[fun].args;
+ return this.types[fun].args;
}
GFAbstract.prototype.getCat = function(fun) {
- return this.types[fun].cat;
+ return this.types[fun].cat;
};
GFAbstract.prototype.annotate = function(tree, type) {
- if (tree.name == '?') {
- tree.type = type;
- } else {
- var typ = this.types[tree.name];
- for (var i in tree.args) {
- this.annotate(tree.args[i], typ.args[i]);
- }
- }
- return tree;
+ if (tree.name == '?') {
+ tree.type = type;
+ } else {
+ var typ = this.types[tree.name];
+ for (var i in tree.args) {
+ this.annotate(tree.args[i], typ.args[i]);
+ }
+ }
+ return tree;
} ;
GFAbstract.prototype.handleLiterals = function(tree, type) {
- if (tree.name != '?') {
- if (type == "String" || type == "Int" || type == "Float") {
- tree.name = type + "_Literal_" + tree.name;
- } else {
- var typ = this.types[tree.name];
- for (var i in tree.args) {
- this.handleLiterals(tree.args[i], typ.args[i]);
- }
- }
- }
- return tree;
+ if (tree.name != '?') {
+ if (type == "String" || type == "Int" || type == "Float") {
+ tree.name = type + "_Literal_" + tree.name;
+ } else {
+ var typ = this.types[tree.name];
+ for (var i in tree.args) {
+ this.handleLiterals(tree.args[i], typ.args[i]);
+ }
+ }
+ }
+ return tree;
} ;
/* Hack to get around the fact that our SISR doesn't build real Fun objects. */
GFAbstract.prototype.copyTree = function(x) {
- var t = new Fun(x.name);
- if (!isUndefined(x.type)) {
- t.type = x.type;
- }
- var cs = x.args;
- if (!isUndefined(cs)) {
- for (var i in cs) {
- t.setArg(i, this.copyTree(cs[i]));
- }
- }
- return t;
+ var t = new Fun(x.name);
+ if (!isUndefined(x.type)) {
+ t.type = x.type;
+ }
+ var cs = x.args;
+ if (!isUndefined(cs)) {
+ for (var i in cs) {
+ t.setArg(i, this.copyTree(cs[i]));
+ }
+ }
+ return t;
} ;
-GFAbstract.prototype.parseTree = function(str, type) {
- return this.annotate(this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g), 0), type);
+GFAbstract.prototype.parseTree = function(str, type) {
+ return this.annotate(this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g), 0), type);
} ;
GFAbstract.prototype.parseTree_ = function(tokens, prec) {
- if (tokens.length == 0 || tokens[0] == ")") { return null; }
- var t = tokens.shift();
- if (t == "(") {
- var tree = this.parseTree_(tokens, 0);
- tokens.shift();
- return tree;
- } else if (t == '?') {
- var tree = this.parseTree_(tokens, 0);
- return new Fun('?');
- } else {
- var tree = new Fun(t);
- if (prec == 0) {
- var c, i;
- for (i = 0; (c = this.parseTree_(tokens, 1)) !== null; i++) {
- tree.setArg(i,c);
- }
- }
- return tree;
- }
+ if (tokens.length == 0 || tokens[0] == ")") { return null; }
+ var t = tokens.shift();
+ if (t == "(") {
+ var tree = this.parseTree_(tokens, 0);
+ tokens.shift();
+ return tree;
+ } else if (t == '?') {
+ var tree = this.parseTree_(tokens, 0);
+ return new Fun('?');
+ } else {
+ var tree = new Fun(t);
+ if (prec == 0) {
+ var c, i;
+ for (i = 0; (c = this.parseTree_(tokens, 1)) !== null; i++) {
+ tree.setArg(i,c);
+ }
+ }
+ return tree;
+ }
} ;
function Type(args, cat) {
- this.args = args;
- this.cat = cat;
+ this.args = args;
+ this.cat = cat;
}
/* Linearization */
function GFConcrete(flags, productions, functions, sequences, startCats, totalFIds) {
- this.flags = flags;
- this.productions = productions;
- this.functions = functions;
- this.sequences = sequences;
- this.startCats = startCats;
- this.totalFIds = totalFIds;
+ this.flags = flags;
+ this.productions = productions;
+ this.functions = functions;
+ this.sequences = sequences;
+ this.startCats = startCats;
+ this.totalFIds = totalFIds;
- this.pproductions = productions;
- this.lproductions = new Object();
+ this.pproductions = productions;
+ this.lproductions = new Object();
for (var fid in productions) {
for (var i in productions[fid]) {
var rule = productions[fid][i];
-
+
if (rule.id == "Apply") {
var fun = this.functions[rule.fun];
var lproductions = this.lproductions;
-
+
rule.fun = fun;
var register = function (args, key, i) {
- if (i < args.length) {
- var c = 0;
- var arg = args[i].fid;
-
- for (var k in productions[arg]) {
+ if (i < args.length) {
+ var c = 0;
+ var arg = args[i].fid;
+
+ for (var k in productions[arg]) {
var rule = productions[arg][k];
if (rule.id == "Coerce") {
register(args,key + "_" + rule.arg,i+1);
c++;
}
}
-
+
if (c == 0)
register(args,key + "_" + arg,i+1);
- } else {
- var set = lproductions[key];
+ } else {
+ var set = lproductions[key];
if (set == null) {
set = new Array();
lproductions[key] = set;
}
- set.push({fun: fun, fid: fid});
- }
- }
+ set.push({fun: fun, fid: fid});
+ }
+ }
register(rule.args,rule.fun.name,0);
- }
+ }
}
}
-
+
for (var i in functions) {
var fun = functions[i];
for (var j in fun.lins) {
@@ -267,30 +267,30 @@ function GFConcrete(flags, productions, functions, sequences, startCats, totalFI
}
}
}
-GFConcrete.prototype.linearizeSyms = function (tree, tag) {
+GFConcrete.prototype.linearizeSyms = function (tree, tag) {
var res = new Array();
-
+
if (tree.isString()) {
- var sym = new SymKS(tree.name);
- sym.tag = tag;
- res.push({fid: -1, table: [[sym]]});
+ var sym = new SymKS(tree.name);
+ sym.tag = tag;
+ res.push({fid: -1, table: [[sym]]});
} else if (tree.isInt()) {
- var sym = new SymKS(tree.name);
- sym.tag = tag;
- res.push({fid: -2, table: [[sym]]});
+ var sym = new SymKS(tree.name);
+ sym.tag = tag;
+ res.push({fid: -2, table: [[sym]]});
} else if (tree.isFloat()) {
- var sym = new SymKS(tree.name);
- sym.tag = tag;
- res.push({fid: -3, table: [[sym]]});
+ var sym = new SymKS(tree.name);
+ sym.tag = tag;
+ res.push({fid: -3, table: [[sym]]});
} else if (tree.isMeta()) {
- // TODO: Use lindef here
+ // TODO: Use lindef here
var cat = this.startCats[tree.type];
-
+
var sym = new SymKS(tree.name);
- sym.tag = tag;
-
- for (var fid = cat.s; fid <= cat.e; fid++) {
- res.push({fid: fid, table: [[sym]]});
+ sym.tag = tag;
+
+ for (var fid = cat.s; fid <= cat.e; fid++) {
+ res.push({fid: fid, table: [[sym]]});
}
} else {
var cs = new Array();
@@ -310,7 +310,7 @@ GFConcrete.prototype.linearizeSyms = function (tree, tag) {
var lin = rule.fun.lins[j];
var toks = new Array();
row.table[j] = toks;
-
+
for (var k in lin) {
var sym = lin[k];
switch (sym.id) {
@@ -331,7 +331,7 @@ GFConcrete.prototype.linearizeSyms = function (tree, tag) {
res.push(row);
}
}
-
+
return res;
};
GFConcrete.prototype.syms2toks = function (syms) {
@@ -347,7 +347,7 @@ GFConcrete.prototype.syms2toks = function (syms) {
case "KP":
for (var j in sym.tokens) {
ts.push(this.tagIt(sym.tokens[j],sym.tag));
- }
+ }
break;
}
}
@@ -365,37 +365,37 @@ GFConcrete.prototype.linearize = function (tree) {
var res = this.linearizeSyms(tree,"0");
return this.unlex(this.syms2toks(res[0].table[0]));
}
-GFConcrete.prototype.tagAndLinearize = function (tree) {
+GFConcrete.prototype.tagAndLinearize = function (tree) {
var res = this.linearizeSyms(tree,"0");
return this.syms2toks(res[0].table[0]);
}
GFConcrete.prototype.unlex = function (ts) {
- if (ts.length == 0) {
- return "";
- }
-
- var noSpaceAfter = /^[\(\-\[]/;
- var noSpaceBefore = /^[\.\,\?\!\)\:\;\-\]]/;
-
- var s = "";
- for (var i = 0; i < ts.length; i++) {
- var t = ts[i];
- var after = i < ts.length-1 ? ts[i+1] : null;
- s += t;
- if (after != null && !t.match(noSpaceAfter)
- && !after.match(noSpaceBefore)) {
- s += " ";
- }
- }
- return s;
+ if (ts.length == 0) {
+ return "";
+ }
+
+ var noSpaceAfter = /^[\(\-\[]/;
+ var noSpaceBefore = /^[\.\,\?\!\)\:\;\-\]]/;
+
+ var s = "";
+ for (var i = 0; i < ts.length; i++) {
+ var t = ts[i];
+ var after = i < ts.length-1 ? ts[i+1] : null;
+ s += t;
+ if (after != null && !t.match(noSpaceAfter)
+ && !after.match(noSpaceBefore)) {
+ s += " ";
+ }
+ }
+ return s;
};
GFConcrete.prototype.tagIt = function (obj, tag) {
if (isString(obj)) {
- var o = new String(obj);
- o.setTag(tag);
- return o;
+ var o = new String(obj);
+ o.setTag(tag);
+ return o;
} else {
- var me = arguments.callee;
+ var me = arguments.callee;
if (arguments.length == 2) {
me.prototype = obj;
var o = new me();
@@ -416,28 +416,28 @@ function isNumber(a) { return typeof a == 'number' && isFinite(a); }
function isFunction(a) { return typeof a == 'function'; }
function dumpObject (obj) {
- if (isUndefined(obj)) {
- return "undefined";
- } else if (isString(obj)) {
- return '"' + obj.toString() + '"'; // FIXME: escape
- } else if (isBoolean(obj) || isNumber(obj)) {
- return obj.toString();
- } else if (isArray(obj)) {
- var x = "[";
- for (var i in obj) {
- x += dumpObject(obj[i]);
- if (i < obj.length-1) {
- x += ",";
- }
- }
- return x + "]";
- } else {
- var x = "{";
- for (var y in obj) {
- x += y + "=" + dumpObject(obj[y]) + ";" ;
- }
- return x + "}";
- }
+ if (isUndefined(obj)) {
+ return "undefined";
+ } else if (isString(obj)) {
+ return '"' + obj.toString() + '"'; // FIXME: escape
+ } else if (isBoolean(obj) || isNumber(obj)) {
+ return obj.toString();
+ } else if (isArray(obj)) {
+ var x = "[";
+ for (var i in obj) {
+ x += dumpObject(obj[i]);
+ if (i < obj.length-1) {
+ x += ",";
+ }
+ }
+ return x + "]";
+ } else {
+ var x = "{";
+ for (var y in obj) {
+ x += y + "=" + dumpObject(obj[y]) + ";" ;
+ }
+ return x + "}";
+ }
}
/* ------------------------------------------------------------------------- */
@@ -447,11 +447,11 @@ function dumpObject (obj) {
GFConcrete.prototype.showRules = function () {
var ruleStr = new Array();
- ruleStr.push("");
- for (var i = 0, j = this.rules.length; i < j; i++) {
- ruleStr.push(this.rules[i].show());
- }
- return ruleStr.join("");
+ ruleStr.push("");
+ for (var i = 0, j = this.rules.length; i < j; i++) {
+ ruleStr.push(this.rules[i].show());
+ }
+ return ruleStr.join("");
};
GFConcrete.prototype.tokenize = function (string) {
var inToken = false;
@@ -460,125 +460,125 @@ GFConcrete.prototype.tokenize = function (string) {
for (var i = 0; i < string.length; i++) {
if ( string.charAt(i) == ' ' // space
- || string.charAt(i) == '\f' // form feed
- || string.charAt(i) == '\n' // newline
- || string.charAt(i) == '\r' // return
- || string.charAt(i) == '\t' // horizontal tab
- || string.charAt(i) == '\v' // vertical tab
+ || string.charAt(i) == '\f' // form feed
+ || string.charAt(i) == '\n' // newline
+ || string.charAt(i) == '\r' // return
+ || string.charAt(i) == '\t' // horizontal tab
+ || string.charAt(i) == '\v' // vertical tab
|| string.charAt(i) == String.fromCharCode(160) // &nbsp;
) {
- if (inToken) {
+ if (inToken) {
end = i-1;
inToken = false;
-
+
tokens.push(string.substr(start,end-start+1));
}
- } else {
+ } else {
if (!inToken) {
start = i;
inToken = true;
}
}
}
-
+
if (inToken) {
end = i-1;
inToken = false;
-
+
tokens.push(string.substr(start,end-start+1));
}
return tokens;
};
GFConcrete.prototype.parseString = function (string, cat) {
- var tokens = this.tokenize(string);
-
- var ps = new ParseState(this, cat);
- for (var i in tokens) {
- if (!ps.next(tokens[i]))
+ var tokens = this.tokenize(string);
+
+ var ps = new ParseState(this, cat);
+ for (var i in tokens) {
+ if (!ps.next(tokens[i]))
return new Array();
- }
- return ps.extractTrees();
+ }
+ return ps.extractTrees();
};
/**
* Generate list of suggestions given an input string
*/
GFConcrete.prototype.complete = function (input, cat) {
- // Parameter defaults
- if (input == null) input = "";
- if (cat == null) cat = grammar.abstract.startcat;
-
- // Tokenise input string & remove empty tokens
- tokens = input.trim().split(' ');
- for (var i = tokens.length - 1; i >= 0; i--) {
- if (tokens[i] == "") { tokens.splice(i, 1); }
- }
-
- // Capture last token as it may be partial
- current = tokens.pop();
- if (current == null) current = "";
-
- // Init parse state objects.
- // ps2 is used for testing whether the final token is parsable or not.
- var ps = new ParseState(this, cat);
- var ps2 = new ParseState(this, cat);
-
- // Iterate over tokens, feed one by one to parser
- for (var i = 0; i < tokens.length ; i++) {
- if (!ps.next(tokens[i])) {
- return new Array(); // Incorrect parse, nothing to suggest
- }
- ps2.next(tokens[i]); // also consume token in ps2
- }
-
- // Attempt to also parse current, knowing it may be incomplete
- if (ps2.next(current)) {
- ps.next(current);
- tokens.push(current);
- current = "";
- }
- delete(ps2); // don't need this anymore
-
- // Parse is successful so far, now get suggestions
- var acc = ps.complete(current);
-
- // Format into just a list of strings & return
- // (I know the multiple nesting looks horrible)
- var suggs = new Array();
- if (acc.value) {
- // Iterate over all acc.value[]
- for (var v = 0; v < acc.value.length; v++) {
- // Iterate over all acc.value[].seq[]
- for (var s = 0; s < acc.value[v].seq.length; s++) {
- if (acc.value[v].seq[s].tokens == null) continue;
- // Iterate over all acc.value[].seq[].tokens
- for (var t = 0; t < acc.value[v].seq[s].tokens.length; t++) {
- suggs.push( acc.value[v].seq[s].tokens[t] );
- }
- }
- }
- }
-
- // Note: return used tokens too
- return { 'consumed' : tokens, 'suggestions' : suggs };
+ // Parameter defaults
+ if (input == null) input = "";
+ if (cat == null) cat = grammar.abstract.startcat;
+
+ // Tokenise input string & remove empty tokens
+ tokens = input.trim().split(' ');
+ for (var i = tokens.length - 1; i >= 0; i--) {
+ if (tokens[i] == "") { tokens.splice(i, 1); }
+ }
+
+ // Capture last token as it may be partial
+ current = tokens.pop();
+ if (current == null) current = "";
+
+ // Init parse state objects.
+ // ps2 is used for testing whether the final token is parsable or not.
+ var ps = new ParseState(this, cat);
+ var ps2 = new ParseState(this, cat);
+
+ // Iterate over tokens, feed one by one to parser
+ for (var i = 0; i < tokens.length ; i++) {
+ if (!ps.next(tokens[i])) {
+ return new Array(); // Incorrect parse, nothing to suggest
+ }
+ ps2.next(tokens[i]); // also consume token in ps2
+ }
+
+ // Attempt to also parse current, knowing it may be incomplete
+ if (ps2.next(current)) {
+ ps.next(current);
+ tokens.push(current);
+ current = "";
+ }
+ delete(ps2); // don't need this anymore
+
+ // Parse is successful so far, now get suggestions
+ var acc = ps.complete(current);
+
+ // Format into just a list of strings & return
+ // (I know the multiple nesting looks horrible)
+ var suggs = new Array();
+ if (acc.value) {
+ // Iterate over all acc.value[]
+ for (var v = 0; v < acc.value.length; v++) {
+ // Iterate over all acc.value[].seq[]
+ for (var s = 0; s < acc.value[v].seq.length; s++) {
+ if (acc.value[v].seq[s].tokens == null) continue;
+ // Iterate over all acc.value[].seq[].tokens
+ for (var t = 0; t < acc.value[v].seq[s].tokens.length; t++) {
+ suggs.push( acc.value[v].seq[s].tokens[t] );
+ }
+ }
+ }
+ }
+
+ // Note: return used tokens too
+ return { 'consumed' : tokens, 'suggestions' : suggs };
}
// Apply Object Definition
function Apply(fun, args) {
- this.id = "Apply";
- this.fun = fun;
- this.args = args;
+ this.id = "Apply";
+ this.fun = fun;
+ this.args = args;
}
Apply.prototype.show = function (cat) {
- var recStr = new Array();
- recStr.push(cat, " -> ", fun.name, " [", this.args, "]");
- return recStr.join("");
+ var recStr = new Array();
+ recStr.push(cat, " -> ", fun.name, " [", this.args, "]");
+ return recStr.join("");
};
Apply.prototype.isEqual = function (obj) {
- if (this.id != obj.id || this.fun != obj.fun || this.args.length != obj.args.length)
+ if (this.id != obj.id || this.fun != obj.fun || this.args.length != obj.args.length)
return false;
-
+
for (var i in this.args) {
if (this.args[i] != obj.args[i])
return false;
@@ -588,39 +588,39 @@ Apply.prototype.isEqual = function (obj) {
};
function PArg() {
- this.fid = arguments[arguments.length-1];
- if (arguments.length > 1)
- this.hypos = arguments.slice(0,arguments.length-1);
+ this.fid = arguments[arguments.length-1];
+ if (arguments.length > 1)
+ this.hypos = arguments.slice(0,arguments.length-1);
}
// Coerce Object Definition
function Coerce(arg) {
this.id = "Coerce";
- this.arg = arg;
+ this.arg = arg;
}
Coerce.prototype.show = function (cat) {
- var recStr = new Array();
- recStr.push(cat, " -> _ [", this.args, "]");
- return recStr.join("");
+ var recStr = new Array();
+ recStr.push(cat, " -> _ [", this.args, "]");
+ return recStr.join("");
};
// Const Object Definition
function Const(lit, toks) {
this.id = "Const";
- this.lit = lit;
- this.toks = toks;
+ this.lit = lit;
+ this.toks = toks;
}
Const.prototype.show = function (cat) {
- var recStr = new Array();
- recStr.push(cat, " -> ", lit.print());
- return recStr.join("");
+ var recStr = new Array();
+ recStr.push(cat, " -> ", lit.print());
+ return recStr.join("");
};
Const.prototype.isEqual = function (obj) {
- if (this.id != obj.id || this.lit.isEqual(obj.lit) || this.toks.length != obj.toks.length)
+ if (this.id != obj.id || this.lit.isEqual(obj.lit) || this.toks.length != obj.toks.length)
return false;
-
+
for (var i in this.toks) {
if (this.toks[i] != obj.toks[i])
return false;
@@ -638,41 +638,41 @@ function CncFun(name,lins) {
// Object to represent argument projections in grammar rules
function SymCat(i, label) {
- this.id = "Arg";
- this.i = i;
- this.label = label;
+ this.id = "Arg";
+ this.i = i;
+ this.label = label;
}
SymCat.prototype.getId = function () { return this.id; };
SymCat.prototype.getArgNum = function () { return this.i };
SymCat.prototype.show = function () {
- var argStr = new Array();
- argStr.push(this.i, this.label);
- return argStr.join(".");
+ var argStr = new Array();
+ argStr.push(this.i, this.label);
+ return argStr.join(".");
};
// Object to represent terminals in grammar rules
function SymKS() {
- this.id = "KS";
- this.tokens = arguments;
+ this.id = "KS";
+ this.tokens = arguments;
}
SymKS.prototype.getId = function () { return this.id; };
SymKS.prototype.show = function () {
- var terminalStr = new Array();
- terminalStr.push('"', this.tokens, '"');
- return terminalStr.join("");
+ var terminalStr = new Array();
+ terminalStr.push('"', this.tokens, '"');
+ return terminalStr.join("");
};
// Object to represent pre in grammar rules
function SymKP(tokens,alts) {
- this.id = "KP";
- this.tokens = tokens;
+ this.id = "KP";
+ this.tokens = tokens;
this.alts = alts;
}
SymKP.prototype.getId = function () { return this.id; };
SymKP.prototype.show = function () {
- var terminalStr = new Array();
- terminalStr.push('"', this.tokens, '"');
- return terminalStr.join("");
+ var terminalStr = new Array();
+ terminalStr.push('"', this.tokens, '"');
+ return terminalStr.join("");
};
function Alt(tokens, prefixes) {
@@ -682,15 +682,15 @@ function Alt(tokens, prefixes) {
// Object to represent pre in grammar rules
function SymLit(i,label) {
- this.id = "Lit";
- this.i = i;
- this.label = label;
+ this.id = "Lit";
+ this.i = i;
+ this.label = label;
}
SymLit.prototype.getId = function () { return this.id; };
SymLit.prototype.show = function () {
- var argStr = new Array();
- argStr.push(this.i, this.label);
- return argStr.join(".");
+ var argStr = new Array();
+ argStr.push(this.i, this.label);
+ return argStr.join(".");
};
// Parsing
@@ -732,11 +732,11 @@ Trie.prototype.lookup = function(key,obj) {
Trie.prototype.isEmpty = function() {
if (this.value != null)
return false;
-
+
for (var i in this.items) {
return false;
}
-
+
return true;
}
@@ -747,7 +747,7 @@ function ParseState(concrete, startCat) {
this.chart = new Chart(concrete);
var items = new Array();
-
+
var fids = concrete.startCats[startCat];
if (fids != null) {
var fid;
@@ -762,7 +762,7 @@ function ParseState(concrete, startCat) {
}
}
}
-
+
this.items.insertChain(new Array(), items);
}
ParseState.prototype.next = function (token) {
@@ -785,7 +785,7 @@ ParseState.prototype.next = function (token) {
else
return null;
}
-
+
return null;
}
, function (tokens, item) {
@@ -802,7 +802,7 @@ ParseState.prototype.next = function (token) {
this.items = acc;
this.chart.shift();
-
+
return !this.items.isEmpty();
}
/**
@@ -812,35 +812,35 @@ ParseState.prototype.next = function (token) {
*/
ParseState.prototype.complete = function (currentToken) {
- // Initialise accumulator for suggestions
- var acc = this.items.lookup(currentToken);
- if (acc == null)
- acc = new Trie();
-
- this.process(
- // Items
- this.items.value,
-
- // Deal with literal categories
- function (fid) {
- // Always return null, as suggested by Krasimir
- return null;
- },
-
- // Takes an array of tokens and populates the accumulator
- function (tokens, item) {
- if (currentToken == "" || tokens[0].indexOf(currentToken) == 0) { //if begins with...
- var tokens1 = new Array();
- for (var i = 1; i < tokens.length; i++) {
- tokens1[i-1] = tokens[i];
- }
- acc.insertChain1(tokens1, item);
- }
- }
- );
-
- // Return matches
- return acc;
+ // Initialise accumulator for suggestions
+ var acc = this.items.lookup(currentToken);
+ if (acc == null)
+ acc = new Trie();
+
+ this.process(
+ // Items
+ this.items.value,
+
+ // Deal with literal categories
+ function (fid) {
+ // Always return null, as suggested by Krasimir
+ return null;
+ },
+
+ // Takes an array of tokens and populates the accumulator
+ function (tokens, item) {
+ if (currentToken == "" || tokens[0].indexOf(currentToken) == 0) { //if begins with...
+ var tokens1 = new Array();
+ for (var i = 1; i < tokens.length; i++) {
+ tokens1[i-1] = tokens[i];
+ }
+ acc.insertChain1(tokens1, item);
+ }
+ }
+ );
+
+ // Return matches
+ return acc;
}
ParseState.prototype.extractTrees = function() {
this.process( this.items.value
@@ -850,11 +850,11 @@ ParseState.prototype.extractTrees = function() {
, function (tokens, item) {
}
);
-
-
+
+
var totalFIds = this.concrete.totalFIds;
var forest = this.chart.forest;
-
+
function go(fid) {
if (fid < totalFIds) {
return [new Fun("?")];
@@ -864,24 +864,24 @@ ParseState.prototype.extractTrees = function() {
var rules = forest[fid];
for (var j in rules) {
var rule = rules[j];
-
+
if (rule.id == "Const") {
trees.push(rule.lit);
- } else {
+ } else {
var arg_ix = new Array();
var arg_ts = new Array();
for (var k in rule.args) {
arg_ix[k] = 0;
arg_ts[k] = go(rule.args[k].fid);
}
-
+
while (true) {
var t = new Fun(rule.fun.name);
for (var k in arg_ts) {
t.setArg(k,arg_ts[k][arg_ix[k]]);
}
trees.push(t);
-
+
var i = 0;
while (i < arg_ts.length) {
arg_ix[i]++;
@@ -889,26 +889,26 @@ ParseState.prototype.extractTrees = function() {
break;
arg_ix[i] = 0;
- i++;
+ i++;
}
-
+
if (i >= arg_ts.length)
break;
}
}
}
-
+
return trees;
}
}
-
+
var trees = new Array();
var fids = this.concrete.startCats[this.startCat];
if (fids != null) {
var fid0;
for (fid0 = fids.s; fid0 <= fids.e; fid0++) {
-
+
var labels = new Object();
var rules = this.chart.expandForest(fid0);
for (var i in rules) {
@@ -916,7 +916,7 @@ ParseState.prototype.extractTrees = function() {
labels[lbl] = true;
}
}
-
+
for (var lbl in labels) {
var fid = this.chart.lookupPC(fid0,lbl,0);
var arg_ts = go(fid);
@@ -928,14 +928,14 @@ ParseState.prototype.extractTrees = function() {
break;
}
}
-
+
if (!isMember)
trees.push(arg_ts[i]);
}
}
}
- }
-
+ }
+
return trees;
}
ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
@@ -966,10 +966,10 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
break;
}
}
-
+
if (!isMember) {
items.push(item);
-
+
var fid2 = this.chart.lookupPC(fid,label,this.chart.offset);
if (fid2 != null) {
agenda.push(item.shiftOverArg(sym.i,fid2));
@@ -1004,7 +1004,7 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
var fid = this.chart.lookupPC(item.fid,item.lbl,item.offset);
if (fid == null) {
fid = this.chart.nextId++;
-
+
var items = this.chart.lookupACo(item.offset,item.fid,item.lbl);
if (items != null) {
for (var j in items) {
@@ -1013,7 +1013,7 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
agenda.push(pitem.shiftOverArg(i,fid));
}
}
-
+
this.chart.insertPC(item.fid,item.lbl,item.offset,fid);
this.chart.forest[fid] = [new Apply(item.fun,item.args)];
} else {
@@ -1023,16 +1023,16 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
agenda.push(new ActiveItem(this.chart.offset,0,item.fun,item.fun.lins[lbl],item.args,fid,lbl));
}
}
-
+
var rules = this.chart.forest[fid];
var rule = new Apply(item.fun,item.args);
-
+
var isMember = false;
for (var j in rules) {
if (rules[j].isEqual(rule))
isMember = true;
}
-
+
if (!isMember)
rules.push(rule);
}
@@ -1048,7 +1048,7 @@ function Chart(concrete) {
this.forest = new Object();
this.nextId = concrete.totalFIds;
this.offset = 0;
-
+
for (var fid in concrete.pproductions) {
this.forest[fid] = concrete.pproductions[fid];
}
@@ -1061,7 +1061,7 @@ Chart.prototype.lookupAC = function (fid,label) {
}
Chart.prototype.lookupACo = function (offset,fid,label) {
var tmp;
-
+
if (offset == this.offset)
tmp = this.active[fid];
else
@@ -1094,15 +1094,15 @@ Chart.prototype.insertPC = function (fid1,label,offset,fid2) {
Chart.prototype.shift = function () {
this.actives.push(this.active);
this.active = new Object();
-
+
this.passive = new Object();
-
+
this.offset++;
}
Chart.prototype.expandForest = function (fid) {
var rules = new Array();
var forest = this.forest;
-
+
var go = function (rules0) {
for (var i in rules0) {
var rule = rules0[i];