diff options
| author | John J. Camilleri <john@digitalgrammars.com> | 2019-06-13 10:31:49 +0200 |
|---|---|---|
| committer | John J. Camilleri <john@digitalgrammars.com> | 2019-06-13 10:31:49 +0200 |
| commit | d252cfd6109e44a68b3c90be56ad6398faa866ab (patch) | |
| tree | f3946a10c4c02fb0bea2db29755e57d4df6d1fad /src/runtime | |
| parent | 46a1bdc7ea469d3b9b1f4c57e6d3c636480d385c (diff) | |
gflib.ts: handled unimplemented functions during linearisation
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/typescript/gflib.ts | 83 | ||||
| -rw-r--r-- | src/runtime/typescript/js/gflib.js | 59 |
2 files changed, 115 insertions, 27 deletions
diff --git a/src/runtime/typescript/gflib.ts b/src/runtime/typescript/gflib.ts index 8b7bb0fc5..9ed3afb52 100644 --- a/src/runtime/typescript/gflib.ts +++ b/src/runtime/typescript/gflib.ts @@ -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, diff --git a/src/runtime/typescript/js/gflib.js b/src/runtime/typescript/js/gflib.js index 6fdadcf0e..f44e8ade7 100644 --- a/src/runtime/typescript/js/gflib.js +++ b/src/runtime/typescript/js/gflib.js @@ -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; + } + } + }); +} |
