gflib.ts: handled unimplemented functions during linearisation

This commit is contained in:
John J. Camilleri
2019-06-13 10:31:49 +02:00
parent 46a1bdc7ea
commit d252cfd610
2 changed files with 115 additions and 27 deletions

View File

@@ -374,7 +374,25 @@ class GFConcrete {
}
let key = tree.name
for (let i in cs) {
key = key + '_' + cs[i].fid
if (isUndefined(cs[i])) {
// Some arguments into this function are undefined
return [{
fid: -5, // signal to parent that I cannot lin properly
table: [[new SymKS(`[${tree.name}]`).tagWith(tag)]]
}]
} else if (cs[i].fid === -5) {
// My child cannot lin properly, just find first matching rule for me
// TODO probably not general enough
for (let k in this.lproductions) {
if (k.includes(tree.name)) {
key = k
break
}
}
break
} else {
key = key + '_' + cs[i].fid
}
}
for (let i in this.lproductions[key]) {
@@ -470,12 +488,18 @@ class GFConcrete {
public linearize(tree: Fun): string {
let res = this.linearizeSyms(tree,'0')
return this.unlex(this.syms2toks(res[0].table[0]))
if (res.length > 0)
return this.unlex(this.syms2toks(res[0].table[0]))
else
return ''
}
public tagAndLinearize(tree: Fun): TaggedString[] {
let res = this.linearizeSyms(tree,'0')
return this.syms2toks(res[0].table[0])
if (res.length > 0)
return this.syms2toks(res[0].table[0])
else
return []
}
private unlex(ts: TaggedString[]): string {
@@ -1489,8 +1513,6 @@ class ActiveItem {
* Utilities
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
/* from Remedial JavaScript by Douglas Crockford, http://javascript.crockford.com/remedial.html */
// function isString(a: any): boolean {
// return typeof a == 'string' || a instanceof String
@@ -1498,7 +1520,7 @@ class ActiveItem {
// function isArray(a: any): boolean {
// return a && typeof a == 'object' && a.constructor == Array
// }
function isUndefined(a: any): boolean {
function isUndefined(a: any): boolean { // eslint-disable-line @typescript-eslint/no-explicit-any
return typeof a == 'undefined'
}
// function isBoolean(a: any): boolean {
@@ -1535,22 +1557,47 @@ function isUndefined(a: any): boolean {
// }
// }
// A polyfill with provides the String.startsWith function for older targets
// If you are targeting ES6(2015) or later, you don't need this
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith#Polyfill
// if (!String.prototype.startsWith) {
/**
* Polyfills for older targets
*/
interface String {
startsWith: (search: string, pos?: number) => boolean;
includes: (search: string, start?: number) => boolean;
}
Object.defineProperty(String.prototype, 'startsWith', {
value: function(search: string, pos?: number): boolean {
pos = !pos || pos < 0 ? 0 : +pos
return this.substring(pos, pos + search.length) === search
}
})
// }
// If you want to make this into a proper module, uncomment this:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith#Polyfill
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function(search: string, pos?: number): boolean {
pos = !pos || pos < 0 ? 0 : +pos
return this.substring(pos, pos + search.length) === search
}
})
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill
if (!String.prototype.includes) {
Object.defineProperty(String.prototype, 'includes', {
value: function(search: string, start?: number): boolean {
'use strict'
if (typeof start !== 'number') {
start = 0
}
if (start + search.length > this.length) {
return false
} else {
return this.indexOf(search, start) !== -1
}
}
})
}
/**
* gflib.ts as a module
* If you want to make this into a proper module, uncomment this:
*/
// export {
// GFGrammar,
// GFAbstract,

View File

@@ -303,7 +303,24 @@ var GFConcrete = (function () {
}
var key = tree.name;
for (var i in cs_1) {
key = key + '_' + cs_1[i].fid;
if (isUndefined(cs_1[i])) {
return [{
fid: -5,
table: [[new SymKS("[" + tree.name + "]").tagWith(tag)]]
}];
}
else if (cs_1[i].fid === -5) {
for (var k in this.lproductions) {
if (k.includes(tree.name)) {
key = k;
break;
}
}
break;
}
else {
key = key + '_' + cs_1[i].fid;
}
}
for (var i in this.lproductions[key]) {
var rule = this.lproductions[key][i];
@@ -399,11 +416,17 @@ var GFConcrete = (function () {
};
GFConcrete.prototype.linearize = function (tree) {
var res = this.linearizeSyms(tree, '0');
return this.unlex(this.syms2toks(res[0].table[0]));
if (res.length > 0)
return this.unlex(this.syms2toks(res[0].table[0]));
else
return '';
};
GFConcrete.prototype.tagAndLinearize = function (tree) {
var res = this.linearizeSyms(tree, '0');
return this.syms2toks(res[0].table[0]);
if (res.length > 0)
return this.syms2toks(res[0].table[0]);
else
return [];
};
GFConcrete.prototype.unlex = function (ts) {
if (ts.length == 0) {
@@ -1113,9 +1136,27 @@ var ActiveItem = (function () {
function isUndefined(a) {
return typeof a == 'undefined';
}
Object.defineProperty(String.prototype, 'startsWith', {
value: function (search, pos) {
pos = !pos || pos < 0 ? 0 : +pos;
return this.substring(pos, pos + search.length) === search;
}
});
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function (search, pos) {
pos = !pos || pos < 0 ? 0 : +pos;
return this.substring(pos, pos + search.length) === search;
}
});
}
if (!String.prototype.includes) {
Object.defineProperty(String.prototype, 'includes', {
value: function (search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
}
else {
return this.indexOf(search, start) !== -1;
}
}
});
}