mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
almost functional version of the javascript runtime
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
<script type="text/javascript" src="gfjseditor.js"></script>
|
<script type="text/javascript" src="gfjseditor.js"></script>
|
||||||
<title>Web-based Syntax Editor</title>
|
<title>Web-based Syntax Editor</title>
|
||||||
</head>
|
</head>
|
||||||
<body onload="mkEditor('editor', Food)" onkeydown="return hotKeys(event)">
|
<body onload="mkEditor('editor', Foods)" onkeydown="return hotKeys(event)">
|
||||||
<div id="editor">
|
<div id="editor">
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -222,10 +222,10 @@ function getTree(tree, level) {
|
|||||||
htmlTree.push("<li>");
|
htmlTree.push("<li>");
|
||||||
if (tree.hasChildren()) {
|
if (tree.hasChildren()) {
|
||||||
htmlTree.push("<img class='tree-menu'");
|
htmlTree.push("<img class='tree-menu'");
|
||||||
if (tree.collapsed) {
|
if (tree.collapsed)
|
||||||
htmlTree.push(" src='plus.png'");
|
htmlTree.push(" src='plus.png'");
|
||||||
}
|
else
|
||||||
else { htmlTree.push(" src='minus.png'"); }
|
htmlTree.push(" src='minus.png'");
|
||||||
htmlTree.push(" onclick='signClick(\"", tree.name, "\", \"", tree.caption, "\")' />");
|
htmlTree.push(" onclick='signClick(\"", tree.name, "\", \"", tree.caption, "\")' />");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -359,7 +359,7 @@ function editFrameKeyDown(me,lang,event) {
|
|||||||
else
|
else
|
||||||
parseTrees = [new Fun(string)];
|
parseTrees = [new Fun(string)];
|
||||||
break;
|
break;
|
||||||
default: parseTrees = grammar.concretes[lang].parser.parseString(string, node.cat); break;
|
default: parseTrees = grammar.concretes[lang].parseString(string, node.cat); break;
|
||||||
}
|
}
|
||||||
if (parseTrees.length == 1) {
|
if (parseTrees.length == 1) {
|
||||||
pushUndoClearRedo();
|
pushUndoClearRedo();
|
||||||
@@ -607,13 +607,8 @@ function showActions(caption) {
|
|||||||
actions.push(createAction("Wrap", "action", "SingleWordCommand Wrap", "W"));
|
actions.push(createAction("Wrap", "action", "SingleWordCommand Wrap", "W"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i in grammar.concretes) {
|
actions.push(createAction("Parse", "action", "Command Parse IndefSgDet String_N", "P"));
|
||||||
if (grammar.concretes[i].parser) {
|
|
||||||
actions.push(createAction("Parse", "action", "Command Parse IndefSgDet String_N", "P"));
|
|
||||||
} else { actions.push(createAction("Parse", "unavailable", "Command Parse IndefSgDet String_N", "P")); }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node && !abstractNode.isComplete()) {
|
if (node && !abstractNode.isComplete()) {
|
||||||
actions.push(createAction("RandomNode", "action", "RandomlyCommand Refine DefSgDet Node", "N"));
|
actions.push(createAction("RandomNode", "action", "RandomlyCommand Refine DefSgDet Node", "N"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,20 +20,18 @@ GFGrammar.prototype.translate = function (input, fromLang, toLang) {
|
|||||||
toConcs[toLang] = this.concretes[toLang];
|
toConcs[toLang] = this.concretes[toLang];
|
||||||
}
|
}
|
||||||
for (var c1 in fromConcs) {
|
for (var c1 in fromConcs) {
|
||||||
var p = this.concretes[c1].parser;
|
var concrete = this.concretes[c1];
|
||||||
if (p) {
|
var trees = concrete.parseString(input, this.abstract.startcat);
|
||||||
var trees = p.parseString(input, this.abstract.startcat);
|
if (trees.length > 0) {
|
||||||
if (trees.length > 0) {
|
outputs[c1] = new Array();
|
||||||
outputs[c1] = new Array();
|
for (var i in trees) {
|
||||||
for (var i in trees) {
|
outputs[c1][i] = new Object();
|
||||||
outputs[c1][i] = new Object();
|
for (var c2 in toConcs) {
|
||||||
for (var c2 in toConcs) {
|
outputs[c1][i][c2] = this.concretes[c2].linearize(trees[i]);
|
||||||
outputs[c1][i][c2] = this.concretes[c2].linearize(trees[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +48,10 @@ String.prototype.setTag = function (tag) { this.tag = tag; };
|
|||||||
/* Abstract syntax trees */
|
/* Abstract syntax trees */
|
||||||
function Fun(name) {
|
function Fun(name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.args = copy_arguments(arguments, 1);
|
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.print = function () { return this.show(0); } ;
|
||||||
Fun.prototype.show = function (prec) {
|
Fun.prototype.show = function (prec) {
|
||||||
@@ -98,7 +99,18 @@ Fun.prototype.isComplete = function() {
|
|||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
Fun.prototype.isLiteral = function() {
|
Fun.prototype.isLiteral = function() {
|
||||||
return (/^[\"\d]/).test(this.name);
|
return (/^[\"\-\d]/).test(this.name);
|
||||||
|
} ;
|
||||||
|
Fun.prototype.isString = function() {
|
||||||
|
return (/^\".*\"$/).test(this.name);
|
||||||
|
} ;
|
||||||
|
Fun.prototype.isInt = function() {
|
||||||
|
return (/^\-?\d+$/).test(this.name);
|
||||||
|
} ;
|
||||||
|
Fun.prototype.isFloat = function() {
|
||||||
|
return (/^\-?\d*(\.\d*)?$/).test(this.name) &&
|
||||||
|
this.name != "." &&
|
||||||
|
this.name != "-.";
|
||||||
} ;
|
} ;
|
||||||
Fun.prototype.isEqual = function(obj) {
|
Fun.prototype.isEqual = function(obj) {
|
||||||
if (this.name != obj.name)
|
if (this.name != obj.name)
|
||||||
@@ -112,93 +124,6 @@ Fun.prototype.isEqual = function(obj) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Concrete syntax terms */
|
|
||||||
|
|
||||||
function Arr() { this.arr = copy_arguments(arguments, 0); }
|
|
||||||
Arr.prototype.tokens = function() { return this.arr[0].tokens(); };
|
|
||||||
Arr.prototype.sel = function(i) { return this.arr[i.toIndex()]; };
|
|
||||||
Arr.prototype.setTag = function(tag) {
|
|
||||||
for (var i = 0, j = this.arr.length; i < j; i++) {
|
|
||||||
this.arr[i].setTag(tag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function Seq() { this.seq = copy_arguments(arguments, 0); }
|
|
||||||
Seq.prototype.tokens = function() {
|
|
||||||
var xs = new Array();
|
|
||||||
for (var i in this.seq) {
|
|
||||||
var ys = this.seq[i].tokens();
|
|
||||||
for (var j in ys) {
|
|
||||||
xs.push(ys[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return xs;
|
|
||||||
};
|
|
||||||
Seq.prototype.setTag = function(tag) {
|
|
||||||
for (var i = 0, j = this.seq.length; i < j; i++) {
|
|
||||||
this.seq[i].setTag(tag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function Variants() { this.variants = copy_arguments(arguments, 0); }
|
|
||||||
Variants.prototype.tokens = function() { return this.variants[0].tokens(); };
|
|
||||||
Variants.prototype.sel = function(i) { return this.variants[0].sel(i); };
|
|
||||||
Variants.prototype.toIndex = function() { return this.variants[0].toIndex(); };
|
|
||||||
Variants.prototype.setTag = function(tag) {
|
|
||||||
for (var i = 0, j = this.variants.length; i < j; i++) {
|
|
||||||
this.variants[i].setTag(tag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function Rp(index,value) { this.index = index; this.value = value; }
|
|
||||||
Rp.prototype.tokens = function() { return new Array(this.index.tokens()); };
|
|
||||||
Rp.prototype.sel = function(i) { return this.value.arr[i.toIndex()]; };
|
|
||||||
Rp.prototype.toIndex = function() { return this.index.toIndex(); };
|
|
||||||
Rp.prototype.setTag = function(tag) { this.index.setTag(tag) };
|
|
||||||
|
|
||||||
function Suffix(prefix,suffix) {
|
|
||||||
this.prefix = new String(prefix);
|
|
||||||
if (prefix.tag) { this.prefix.tag = prefix.tag; }
|
|
||||||
this.suffix = suffix;
|
|
||||||
};
|
|
||||||
Suffix.prototype.tokens = function() {
|
|
||||||
var xs = this.suffix.tokens();
|
|
||||||
for (var i in xs) {
|
|
||||||
xs[i] = new String(this.prefix + xs[i]);
|
|
||||||
xs[i].setTag(this.prefix.tag);
|
|
||||||
}
|
|
||||||
return xs;
|
|
||||||
};
|
|
||||||
Suffix.prototype.sel = function(i) { return new Suffix(this.prefix, this.suffix.sel(i)); };
|
|
||||||
Suffix.prototype.setTag = function(tag) { if (!this.prefix.tag) { this.prefix.setTag(tag); } };
|
|
||||||
|
|
||||||
function Meta() { }
|
|
||||||
Meta.prototype.tokens = function() {
|
|
||||||
var newString = new String("?");
|
|
||||||
newString.setTag(this.tag);
|
|
||||||
return new Array(newString);
|
|
||||||
};
|
|
||||||
Meta.prototype.toIndex = function() { return 0; };
|
|
||||||
Meta.prototype.sel = function(i) { return this; };
|
|
||||||
Meta.prototype.setTag = function(tag) { if (!this.tag) { this.tag = tag; } };
|
|
||||||
|
|
||||||
function Str(value) { this.value = value; }
|
|
||||||
Str.prototype.tokens = function() {
|
|
||||||
var newString = new String(this.value);
|
|
||||||
newString.setTag(this.tag);
|
|
||||||
return new Array(newString);
|
|
||||||
};
|
|
||||||
Str.prototype.setTag = function(tag) { if (!this.tag) { this.tag = tag; } };
|
|
||||||
|
|
||||||
function Int(value) { this.value = value; }
|
|
||||||
Int.prototype.tokens = function() {
|
|
||||||
var newString = new String(this.value.toString());
|
|
||||||
newString.setTag(this.tag);
|
|
||||||
return new Array(newString);
|
|
||||||
};
|
|
||||||
Int.prototype.toIndex = function() { return this.value; };
|
|
||||||
Int.prototype.setTag = function(tag) { if (!this.tag) { this.tag = tag; } };
|
|
||||||
|
|
||||||
/* Type annotation */
|
/* Type annotation */
|
||||||
|
|
||||||
function GFAbstract(startcat, types) {
|
function GFAbstract(startcat, types) {
|
||||||
@@ -284,47 +209,166 @@ function Type(args, cat) {
|
|||||||
|
|
||||||
/* Linearization */
|
/* Linearization */
|
||||||
|
|
||||||
function GFConcrete(flags, rules, parser) {
|
function GFConcrete(flags, productions, functions, sequences, startCats, totalFIds) {
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
this.rules = rules;
|
this.productions = productions;
|
||||||
if (parser) {
|
this.functions = functions;
|
||||||
this.parser = parser;
|
this.sequences = sequences;
|
||||||
} else {
|
this.startCats = startCats;
|
||||||
this.parser = undefined;
|
this.totalFIds = totalFIds;
|
||||||
}
|
|
||||||
|
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]) {
|
||||||
|
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];
|
||||||
|
if (set == null) {
|
||||||
|
set = new Array();
|
||||||
|
lproductions[key] = set;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
fun.lins[j] = sequences[fun.lins[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GFConcrete.prototype.rule = function (name, cs) {
|
GFConcrete.prototype.linearizeSyms = function (tree, tag) {
|
||||||
var r = this.rules[name];
|
var res = new Array();
|
||||||
if (r) {
|
|
||||||
return this.rules[name](cs);
|
if (tree.isString()) {
|
||||||
|
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]]});
|
||||||
|
} else if (tree.isFloat()) {
|
||||||
|
var sym = new SymKS(tree.name);
|
||||||
|
sym.tag = tag;
|
||||||
|
res.push({fid: -3, table: [[sym]]});
|
||||||
|
} else if (tree.isMeta()) {
|
||||||
|
// 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]]});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
window.alert("Missing rule " + name);
|
var cs = new Array();
|
||||||
|
for (var i in tree.args) {
|
||||||
|
// TODO: we should handle the case for nondeterministic linearization
|
||||||
|
cs.push(this.linearizeSyms(tree.args[i],tag + "-" + i)[0]);
|
||||||
|
}
|
||||||
|
var key = tree.name;
|
||||||
|
for (var i in cs) {
|
||||||
|
key = key + "_" + cs[i].fid
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in this.lproductions[key]) {
|
||||||
|
var rule = this.lproductions[key][i];
|
||||||
|
var row = {fid: rule.fid, table: new Array()};
|
||||||
|
for (var j in rule.fun.lins) {
|
||||||
|
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) {
|
||||||
|
case "Arg":
|
||||||
|
case "Lit":
|
||||||
|
var ts = cs[sym.i].table[sym.label];
|
||||||
|
for (var l in ts) {
|
||||||
|
toks.push(ts[l]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "KS":
|
||||||
|
case "KP":
|
||||||
|
toks.push(this.tagIt(sym,tag));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.push(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
};
|
};
|
||||||
GFConcrete.prototype.addRule = function (name, f) { this.rules[name] = f; };
|
GFConcrete.prototype.syms2toks = function (syms) {
|
||||||
GFConcrete.prototype.lindef = function (cat, v) { return this.rules[cat]([new Str(v)]); } ;
|
var ts = new Array();
|
||||||
GFConcrete.prototype.linearize = function (tree) {
|
for (var i in syms) {
|
||||||
return this.unlex(this.linearizeToTerm(tree).tokens());
|
var sym = syms[i];
|
||||||
|
switch (sym.id) {
|
||||||
|
case "KS":
|
||||||
|
for (var j in sym.tokens) {
|
||||||
|
ts.push(this.tagIt(sym.tokens[j],sym.tag));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "KP":
|
||||||
|
for (var j in sym.tokens) {
|
||||||
|
ts.push(this.tagIt(sym.tokens[j],sym.tag));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ts;
|
||||||
};
|
};
|
||||||
GFConcrete.prototype.linearizeToTerm = function (tree) {
|
GFConcrete.prototype.linearizeAll = function (tree) {
|
||||||
if (tree.isMeta()) {
|
var res = this.linearizeSyms(tree,"0");
|
||||||
if (isUndefined(tree.type)) {
|
for (var l in res) {
|
||||||
return new Meta();
|
res[l] = this.unlex(this.syms2toks(res[l].table[0]));
|
||||||
} else {
|
}
|
||||||
return this.lindef(tree.type, tree.name);
|
|
||||||
}
|
return res;
|
||||||
} else {
|
|
||||||
var cs = new Array();
|
|
||||||
for (var i in tree.args) {
|
|
||||||
cs.push(this.linearizeToTerm(tree.args[i]));
|
|
||||||
}
|
|
||||||
if (tree.isLiteral()) {
|
|
||||||
return new Arr(new Str(tree.name));
|
|
||||||
} else {
|
|
||||||
return this.rule(tree.name, cs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
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) {
|
||||||
|
var res = this.linearizeSyms(tree,"0");
|
||||||
|
return this.syms2toks(res[0].table[0]);
|
||||||
|
}
|
||||||
GFConcrete.prototype.unlex = function (ts) {
|
GFConcrete.prototype.unlex = function (ts) {
|
||||||
if (ts.length == 0) {
|
if (ts.length == 0) {
|
||||||
return "";
|
return "";
|
||||||
@@ -345,29 +389,20 @@ GFConcrete.prototype.unlex = function (ts) {
|
|||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
GFConcrete.prototype.tagAndLinearize = function (tree) {
|
GFConcrete.prototype.tagIt = function (obj, tag) {
|
||||||
return this.tagAndLinearizeToTerm(tree, "0").tokens();
|
if (isString(obj)) {
|
||||||
};
|
var o = new String(obj);
|
||||||
GFConcrete.prototype.tagAndLinearizeToTerm = function (tree, route) {
|
o.setTag(tag);
|
||||||
if (tree.isMeta()) {
|
return o;
|
||||||
if (isUndefined(tree.type)) {
|
} else {
|
||||||
var newMeta = new Meta();
|
var me = arguments.callee;
|
||||||
newMeta.setTag(route);
|
if (arguments.length == 2) {
|
||||||
return newMeta;
|
me.prototype = obj;
|
||||||
} else {
|
var o = new me();
|
||||||
var newTerm = this.lindef(tree.type, tree.name);
|
o.tag = tag;
|
||||||
newTerm.setTag(route);
|
return o;
|
||||||
return newTerm;
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
var cs = new Array();
|
|
||||||
for (var i in tree.args) {
|
|
||||||
cs.push(this.tagAndLinearizeToTerm(tree.args[i], route + "-" + i));
|
|
||||||
}
|
|
||||||
var newTerm = this.rule(tree.name, cs);
|
|
||||||
newTerm.setTag(route);
|
|
||||||
return newTerm;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
@@ -405,42 +440,12 @@ function dumpObject (obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function copy_arguments(args, start) {
|
|
||||||
var arr = new Array();
|
|
||||||
for (var i = 0; i < args.length - start; i++) {
|
|
||||||
arr[i] = args[i + start];
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/* -------------------------------- PARSING -------------------------------- */
|
/* -------------------------------- PARSING -------------------------------- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
function Parser(productions, functions, sequences, startCats, totalCats) {
|
GFConcrete.prototype.showRules = function () {
|
||||||
this.productions = productions;
|
|
||||||
this.functions = functions;
|
|
||||||
this.sequences = sequences;
|
|
||||||
this.startCats = startCats;
|
|
||||||
this.totalCats = totalCats;
|
|
||||||
|
|
||||||
for (var fid in productions) {
|
|
||||||
for (var i in productions[fid]) {
|
|
||||||
var rule = productions[fid][i];
|
|
||||||
rule.fun = functions[rule.fun];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i in functions) {
|
|
||||||
var fun = functions[i];
|
|
||||||
for (var j in fun.lins) {
|
|
||||||
fun.lins[j] = sequences[fun.lins[j]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Parser.prototype.showRules = function () {
|
|
||||||
var ruleStr = new Array();
|
var ruleStr = new Array();
|
||||||
ruleStr.push("");
|
ruleStr.push("");
|
||||||
for (var i = 0, j = this.rules.length; i < j; i++) {
|
for (var i = 0, j = this.rules.length; i < j; i++) {
|
||||||
@@ -448,7 +453,7 @@ Parser.prototype.showRules = function () {
|
|||||||
}
|
}
|
||||||
return ruleStr.join("");
|
return ruleStr.join("");
|
||||||
};
|
};
|
||||||
Parser.prototype.tokenize = function (string) {
|
GFConcrete.prototype.tokenize = function (string) {
|
||||||
var inToken = false;
|
var inToken = false;
|
||||||
var start, end;
|
var start, end;
|
||||||
var tokens = new Array();
|
var tokens = new Array();
|
||||||
@@ -484,7 +489,7 @@ Parser.prototype.tokenize = function (string) {
|
|||||||
}
|
}
|
||||||
return tokens;
|
return tokens;
|
||||||
};
|
};
|
||||||
Parser.prototype.parseString = function (string, cat) {
|
GFConcrete.prototype.parseString = function (string, cat) {
|
||||||
var tokens = this.tokenize(string);
|
var tokens = this.tokenize(string);
|
||||||
|
|
||||||
var ps = new ParseState(this, cat);
|
var ps = new ParseState(this, cat);
|
||||||
@@ -497,7 +502,7 @@ Parser.prototype.parseString = function (string, cat) {
|
|||||||
/**
|
/**
|
||||||
* Generate list of suggestions given an input string
|
* Generate list of suggestions given an input string
|
||||||
*/
|
*/
|
||||||
Parser.prototype.complete = function (input, cat) {
|
GFConcrete.prototype.complete = function (input, cat) {
|
||||||
|
|
||||||
// Parameter defaults
|
// Parameter defaults
|
||||||
if (input == null) input = "";
|
if (input == null) input = "";
|
||||||
@@ -558,19 +563,19 @@ Parser.prototype.complete = function (input, cat) {
|
|||||||
return { 'consumed' : tokens, 'suggestions' : suggs };
|
return { 'consumed' : tokens, 'suggestions' : suggs };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rule Object Definition
|
// Apply Object Definition
|
||||||
|
|
||||||
function Rule(fun, args) {
|
function Apply(fun, args) {
|
||||||
this.id = "Rule";
|
this.id = "Apply";
|
||||||
this.fun = fun;
|
this.fun = fun;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
Rule.prototype.show = function (cat) {
|
Apply.prototype.show = function (cat) {
|
||||||
var recStr = new Array();
|
var recStr = new Array();
|
||||||
recStr.push(cat, " -> ", fun.name, " [", this.args, "]");
|
recStr.push(cat, " -> ", fun.name, " [", this.args, "]");
|
||||||
return recStr.join("");
|
return recStr.join("");
|
||||||
};
|
};
|
||||||
Rule.prototype.isEqual = function (obj) {
|
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;
|
return false;
|
||||||
|
|
||||||
@@ -582,6 +587,12 @@ Rule.prototype.isEqual = function (obj) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function PArg() {
|
||||||
|
this.fid = arguments[arguments.length-1];
|
||||||
|
if (arguments.length > 1)
|
||||||
|
this.hypos = arguments.slice(0,arguments.length-1);
|
||||||
|
}
|
||||||
|
|
||||||
// Coerce Object Definition
|
// Coerce Object Definition
|
||||||
|
|
||||||
function Coerce(arg) {
|
function Coerce(arg) {
|
||||||
@@ -618,7 +629,7 @@ Const.prototype.isEqual = function (obj) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function FFun(name,lins) {
|
function CncFun(name,lins) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.lins = lins;
|
this.lins = lins;
|
||||||
}
|
}
|
||||||
@@ -626,39 +637,39 @@ function FFun(name,lins) {
|
|||||||
// Definition of symbols present in linearization records
|
// Definition of symbols present in linearization records
|
||||||
|
|
||||||
// Object to represent argument projections in grammar rules
|
// Object to represent argument projections in grammar rules
|
||||||
function Arg(i, label) {
|
function SymCat(i, label) {
|
||||||
this.id = "Arg";
|
this.id = "Arg";
|
||||||
this.i = i;
|
this.i = i;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
Arg.prototype.getId = function () { return this.id; };
|
SymCat.prototype.getId = function () { return this.id; };
|
||||||
Arg.prototype.getArgNum = function () { return this.i };
|
SymCat.prototype.getArgNum = function () { return this.i };
|
||||||
Arg.prototype.show = function () {
|
SymCat.prototype.show = function () {
|
||||||
var argStr = new Array();
|
var argStr = new Array();
|
||||||
argStr.push(this.i, this.label);
|
argStr.push(this.i, this.label);
|
||||||
return argStr.join(".");
|
return argStr.join(".");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Object to represent terminals in grammar rules
|
// Object to represent terminals in grammar rules
|
||||||
function KS() {
|
function SymKS() {
|
||||||
this.id = "KS";
|
this.id = "KS";
|
||||||
this.tokens = arguments;
|
this.tokens = arguments;
|
||||||
}
|
}
|
||||||
KS.prototype.getId = function () { return this.id; };
|
SymKS.prototype.getId = function () { return this.id; };
|
||||||
KS.prototype.show = function () {
|
SymKS.prototype.show = function () {
|
||||||
var terminalStr = new Array();
|
var terminalStr = new Array();
|
||||||
terminalStr.push('"', this.tokens, '"');
|
terminalStr.push('"', this.tokens, '"');
|
||||||
return terminalStr.join("");
|
return terminalStr.join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Object to represent pre in grammar rules
|
// Object to represent pre in grammar rules
|
||||||
function KP(tokens,alts) {
|
function SymKP(tokens,alts) {
|
||||||
this.id = "KP";
|
this.id = "KP";
|
||||||
this.tokens = tokens;
|
this.tokens = tokens;
|
||||||
this.alts = alts;
|
this.alts = alts;
|
||||||
}
|
}
|
||||||
KP.prototype.getId = function () { return this.id; };
|
SymKP.prototype.getId = function () { return this.id; };
|
||||||
KP.prototype.show = function () {
|
SymKP.prototype.show = function () {
|
||||||
var terminalStr = new Array();
|
var terminalStr = new Array();
|
||||||
terminalStr.push('"', this.tokens, '"');
|
terminalStr.push('"', this.tokens, '"');
|
||||||
return terminalStr.join("");
|
return terminalStr.join("");
|
||||||
@@ -670,13 +681,13 @@ function Alt(tokens, prefixes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Object to represent pre in grammar rules
|
// Object to represent pre in grammar rules
|
||||||
function Lit(i,label) {
|
function SymLit(i,label) {
|
||||||
this.id = "Lit";
|
this.id = "Lit";
|
||||||
this.i = i;
|
this.i = i;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
Lit.prototype.getId = function () { return this.id; };
|
SymLit.prototype.getId = function () { return this.id; };
|
||||||
Lit.prototype.show = function () {
|
SymLit.prototype.show = function () {
|
||||||
var argStr = new Array();
|
var argStr = new Array();
|
||||||
argStr.push(this.i, this.label);
|
argStr.push(this.i, this.label);
|
||||||
return argStr.join(".");
|
return argStr.join(".");
|
||||||
@@ -729,15 +740,15 @@ Trie.prototype.isEmpty = function() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ParseState(parser, startCat) {
|
function ParseState(concrete, startCat) {
|
||||||
this.parser = parser;
|
this.concrete = concrete;
|
||||||
this.startCat = startCat;
|
this.startCat = startCat;
|
||||||
this.items = new Trie();
|
this.items = new Trie();
|
||||||
this.chart = new Chart(parser);
|
this.chart = new Chart(concrete);
|
||||||
|
|
||||||
var items = new Array();
|
var items = new Array();
|
||||||
|
|
||||||
var fids = parser.startCats[startCat];
|
var fids = concrete.startCats[startCat];
|
||||||
if (fids != null) {
|
if (fids != null) {
|
||||||
var fid;
|
var fid;
|
||||||
for (fid = fids.s; fid <= fids.e; fid++) {
|
for (fid = fids.s; fid <= fids.e; fid++) {
|
||||||
@@ -841,11 +852,11 @@ ParseState.prototype.extractTrees = function() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
var totalCats = this.parser.totalCats;
|
var totalFIds = this.concrete.totalFIds;
|
||||||
var forest = this.chart.forest;
|
var forest = this.chart.forest;
|
||||||
|
|
||||||
function go(fid) {
|
function go(fid) {
|
||||||
if (fid < totalCats) {
|
if (fid < totalFIds) {
|
||||||
return [new Fun("?")];
|
return [new Fun("?")];
|
||||||
} else {
|
} else {
|
||||||
var trees = new Array();
|
var trees = new Array();
|
||||||
@@ -861,7 +872,7 @@ ParseState.prototype.extractTrees = function() {
|
|||||||
var arg_ts = new Array();
|
var arg_ts = new Array();
|
||||||
for (var k in rule.args) {
|
for (var k in rule.args) {
|
||||||
arg_ix[k] = 0;
|
arg_ix[k] = 0;
|
||||||
arg_ts[k] = go(rule.args[k]);
|
arg_ts[k] = go(rule.args[k].fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -893,7 +904,7 @@ ParseState.prototype.extractTrees = function() {
|
|||||||
|
|
||||||
|
|
||||||
var trees = new Array();
|
var trees = new Array();
|
||||||
var fids = this.parser.startCats[this.startCat];
|
var fids = this.concrete.startCats[this.startCat];
|
||||||
if (fids != null) {
|
if (fids != null) {
|
||||||
var fid0;
|
var fid0;
|
||||||
for (fid0 = fids.s; fid0 <= fids.e; fid0++) {
|
for (fid0 = fids.s; fid0 <= fids.e; fid0++) {
|
||||||
@@ -936,7 +947,7 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
|
|||||||
if (item.dot < lin.length) {
|
if (item.dot < lin.length) {
|
||||||
var sym = lin[item.dot];
|
var sym = lin[item.dot];
|
||||||
switch (sym.id) {
|
switch (sym.id) {
|
||||||
case "Arg": var fid = item.args[sym.i];
|
case "Arg": var fid = item.args[sym.i].fid;
|
||||||
var label = sym.label;
|
var label = sym.label;
|
||||||
|
|
||||||
var items = this.chart.lookupAC(fid,label);
|
var items = this.chart.lookupAC(fid,label);
|
||||||
@@ -975,7 +986,7 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
|
|||||||
tokenCallback(alt.tokens, pitem);
|
tokenCallback(alt.tokens, pitem);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Lit": var fid = item.args[sym.i];
|
case "Lit": var fid = item.args[sym.i].fid;
|
||||||
var rules = this.chart.forest[fid];
|
var rules = this.chart.forest[fid];
|
||||||
if (rules != null) {
|
if (rules != null) {
|
||||||
tokenCallback(rules[0].toks, item.shiftOverTokn());
|
tokenCallback(rules[0].toks, item.shiftOverTokn());
|
||||||
@@ -1004,7 +1015,7 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.chart.insertPC(item.fid,item.lbl,item.offset,fid);
|
this.chart.insertPC(item.fid,item.lbl,item.offset,fid);
|
||||||
this.chart.forest[fid] = [new Rule(item.fun,item.args)];
|
this.chart.forest[fid] = [new Apply(item.fun,item.args)];
|
||||||
} else {
|
} else {
|
||||||
var labels = this.chart.labelsAC(fid);
|
var labels = this.chart.labelsAC(fid);
|
||||||
if (labels != null) {
|
if (labels != null) {
|
||||||
@@ -1014,7 +1025,7 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var rules = this.chart.forest[fid];
|
var rules = this.chart.forest[fid];
|
||||||
var rule = new Rule(item.fun,item.args);
|
var rule = new Apply(item.fun,item.args);
|
||||||
|
|
||||||
var isMember = false;
|
var isMember = false;
|
||||||
for (var j in rules) {
|
for (var j in rules) {
|
||||||
@@ -1030,16 +1041,16 @@ ParseState.prototype.process = function (agenda,literalCallback,tokenCallback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Chart(parser) {
|
function Chart(concrete) {
|
||||||
this.active = new Object();
|
this.active = new Object();
|
||||||
this.actives = new Array();
|
this.actives = new Array();
|
||||||
this.passive = new Object();
|
this.passive = new Object();
|
||||||
this.forest = new Object();
|
this.forest = new Object();
|
||||||
this.nextId = parser.totalCats;
|
this.nextId = concrete.totalFIds;
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
|
|
||||||
for (var fid in parser.productions) {
|
for (var fid in concrete.pproductions) {
|
||||||
this.forest[fid] = parser.productions[fid];
|
this.forest[fid] = concrete.pproductions[fid];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Chart.prototype.lookupAC = function (fid,label) {
|
Chart.prototype.lookupAC = function (fid,label) {
|
||||||
@@ -1096,7 +1107,7 @@ Chart.prototype.expandForest = function (fid) {
|
|||||||
for (var i in rules0) {
|
for (var i in rules0) {
|
||||||
var rule = rules0[i];
|
var rule = rules0[i];
|
||||||
switch (rule.id) {
|
switch (rule.id) {
|
||||||
case "Rule": rules.push(rule); break;
|
case "Apply": rules.push(rule); break;
|
||||||
case "Coerce": go(forest[rule.arg]); break;
|
case "Coerce": go(forest[rule.arg]); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1129,9 +1140,9 @@ ActiveItem.prototype.shiftOverArg = function (i,fid) {
|
|||||||
for (var k in this.args) {
|
for (var k in this.args) {
|
||||||
nargs[k] = this.args[k];
|
nargs[k] = this.args[k];
|
||||||
}
|
}
|
||||||
nargs[i] = fid;
|
nargs[i] = new PArg(fid);
|
||||||
return new ActiveItem(this.offset,this.dot+1,this.fun,this.seq,nargs,this.fid,this.lbl);
|
return new ActiveItem(this.offset,this.dot+1,this.fun,this.seq,nargs,this.fid,this.lbl);
|
||||||
}
|
}
|
||||||
ActiveItem.prototype.shiftOverTokn = function () {
|
ActiveItem.prototype.shiftOverTokn = function () {
|
||||||
return new ActiveItem(this.offset,this.dot+1,this.fun,this.seq,this.args,this.fid,this.lbl);
|
return new ActiveItem(this.offset,this.dot+1,this.fun,this.seq,this.args,this.fid,this.lbl);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user