diff --git a/lib/javascript/gflib.js b/lib/javascript/gflib.js index 621f6364a..e3f30b42f 100644 --- a/lib/javascript/gflib.js +++ b/lib/javascript/gflib.js @@ -52,33 +52,48 @@ Fun.prototype.isComplete = function() { /* Concrete syntax terms */ function Arr() { this.arr = copy_arguments(arguments, 0); } -Arr.prototype.print = function() { return this.arr[0].print(); }; +Arr.prototype.tokens = function() { return this.arr[0].tokens(); }; Arr.prototype.sel = function(i) { return this.arr[i.toIndex()]; }; function Seq() { this.seq = copy_arguments(arguments, 0); } -Seq.prototype.print = function() { return join_print(this.seq, " "); }; +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; +}; function Variants() { this.variants = copy_arguments(arguments, 0); } -Variants.prototype.print = function() { return this.variants[0].print(); }; +Variants.prototype.tokens = function() { return this.variants[0].tokens(); }; function Rp(index,value) { this.index = index; this.value = value; } -Rp.prototype.print = function() { return this.index; }; +Rp.prototype.tokens = function() { return new Array(this.index); }; Rp.prototype.toIndex = function() { return this.index.toIndex(); }; function Suffix(prefix,suffix) { this.prefix = prefix; this.suffix = suffix; }; -Suffix.prototype.print = function() { return this.prefix + this.suffix.print(); }; +Suffix.prototype.tokens = function() { + var xs = this.suffix.tokens(); + for (var i in xs) { + xs[i] = this.prefix + xs[i]; + } + return xs; +}; Suffix.prototype.sel = function(i) { return new Suffix(this.prefix, this.suffix.sel(i)); }; function Meta() { } -Meta.prototype.print = function() { return "?"; }; +Meta.prototype.tokens = function() { return new Array("?"); }; Meta.prototype.toIndex = function() { return 0; }; Meta.prototype.sel = function(i) { return this; }; function Str(value) { this.value = value; } -Str.prototype.print = function() { return this.value; }; +Str.prototype.tokens = function() { return new Array(this.value); }; function Int(value) { this.value = value; } -Int.prototype.print = function() { return this.value.toString(); }; +Int.prototype.tokens = function() { return new Array(this.value.toString()); }; Int.prototype.toIndex = function() { return this.value; }; /* Type annotation */ @@ -152,7 +167,9 @@ function Concrete(abstr) { Concrete.prototype.rule = function (name, cs) { return this.rules[name](cs); }; Concrete.prototype.addRule = function (name, f) { this.rules[name] = f; }; Concrete.prototype.lindef = function (cat, v) { return this.rules["_d"+cat]([new Str(v)]); } ; -Concrete.prototype.linearize = function (tree) { return this.linearizeToTerm(tree).print(); }; +Concrete.prototype.linearize = function (tree) { + return this.unlex(this.linearizeToTerm(tree).tokens()); +}; Concrete.prototype.linearizeToTerm = function (tree) { if (tree.isMeta()) { if (isUndefined(tree.type)) { @@ -168,6 +185,27 @@ Concrete.prototype.linearizeToTerm = function (tree) { return this.rule(tree.name, cs); } }; +Concrete.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; +}; + /* Utilities */ @@ -212,16 +250,3 @@ function copy_arguments(args, start) { } return arr; } - -function join_print(values, glue) { - var str = ""; - for (var i in values) { - var s = values[i].print(); - if (s.length > 0) { - if (str.length > 0) { str += glue; } - str += s; - } - } - return str; -} -