mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 19:42:50 -06:00
Use strict mode in TypeScript, catch some more corner cases
This commit is contained in:
@@ -6,6 +6,11 @@
|
|||||||
* A port of the pure JavaScript runtime (/src/runtime/javascript/gflib.js) into TypeScript
|
* A port of the pure JavaScript runtime (/src/runtime/javascript/gflib.js) into TypeScript
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// We use wrapper type String (instead of primitive string) as we
|
||||||
|
// extend its prototype with tagging information.
|
||||||
|
// This linting rule doesn't allow use of String, thus must be disabled:
|
||||||
|
/* eslint-disable @typescript-eslint/ban-types */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GF grammar is one abstract and multiple concretes
|
* A GF grammar is one abstract and multiple concretes
|
||||||
*/
|
*/
|
||||||
@@ -22,8 +27,8 @@ class GFGrammar { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|||||||
input: string,
|
input: string,
|
||||||
fromLang: string,
|
fromLang: string,
|
||||||
toLang: string
|
toLang: string
|
||||||
): {[key: string]: {[key: string]: string}[]} {
|
): {[key: string]: {[key: string]: String}[]} {
|
||||||
let outputs: {[key: string]: {[key: string]: string}[]} = {}
|
let outputs: {[key: string]: {[key: string]: String}[]} = {}
|
||||||
let fromConcs = this.concretes
|
let fromConcs = this.concretes
|
||||||
if (fromLang) {
|
if (fromLang) {
|
||||||
fromConcs = {}
|
fromConcs = {}
|
||||||
@@ -214,15 +219,17 @@ class GFAbstract {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
public parseTree(str: string, type: string): Fun {
|
public parseTree(str: string, type: string): Fun | null {
|
||||||
return this.annotate(this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g), 0), type)
|
let pt = this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g) || [], 0)
|
||||||
|
return pt ? this.annotate(pt, type) : null
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseTree_(tokens: string[], prec: number): Fun {
|
private parseTree_(tokens: string[], prec: number): Fun | null {
|
||||||
if (tokens.length == 0 || tokens[0] == ')') {
|
if (tokens.length == 0 || tokens[0] == ')') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let t = tokens.shift()
|
let t = tokens.shift()
|
||||||
|
if (!t) return null
|
||||||
if (t == '(') {
|
if (t == '(') {
|
||||||
let tree = this.parseTree_(tokens, 0)
|
let tree = this.parseTree_(tokens, 0)
|
||||||
tokens.shift()
|
tokens.shift()
|
||||||
@@ -233,7 +240,7 @@ class GFAbstract {
|
|||||||
} else {
|
} else {
|
||||||
let tree = new Fun(t)
|
let tree = new Fun(t)
|
||||||
if (prec == 0) {
|
if (prec == 0) {
|
||||||
let c: Fun
|
let c: Fun | null
|
||||||
let i: number
|
let i: number
|
||||||
for (i = 0; (c = this.parseTree_(tokens, 1)) !== null; i++) {
|
for (i = 0; (c = this.parseTree_(tokens, 1)) !== null; i++) {
|
||||||
tree.setArg(i,c)
|
tree.setArg(i,c)
|
||||||
@@ -356,7 +363,7 @@ class GFConcrete {
|
|||||||
res.push({fid: -3, table: [[sym]]})
|
res.push({fid: -3, table: [[sym]]})
|
||||||
} else if (tree.isMeta()) {
|
} else if (tree.isMeta()) {
|
||||||
// TODO: Use lindef here
|
// TODO: Use lindef here
|
||||||
let cat = this.startCats[tree.type]
|
let cat = this.startCats[tree.type as string]
|
||||||
|
|
||||||
let sym = new SymKS(tree.name)
|
let sym = new SymKS(tree.name)
|
||||||
sym.tag = tag
|
sym.tag = tag
|
||||||
@@ -413,15 +420,15 @@ class GFConcrete {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
private syms2toks(syms: Sym[]): string[] {
|
private syms2toks(syms: Sym[]): String[] {
|
||||||
let ts: string[] = []
|
let ts: String[] = []
|
||||||
for (let i = 0; i < syms.length; i++) {
|
for (let i = 0; i < syms.length; i++) {
|
||||||
let sym0 = syms[i]
|
let sym0 = syms[i]
|
||||||
switch (sym0.id) {
|
switch (sym0.id) {
|
||||||
case 'KS': {
|
case 'KS': {
|
||||||
let sym = sym0 as SymKS
|
let sym = sym0 as SymKS
|
||||||
for (let j in sym.tokens) {
|
for (let j in sym.tokens) {
|
||||||
ts.push(sym.tokens[j].tagWith(sym.tag))
|
ts.push(sym.tokens[j].tagWith(sym.tag as string))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -437,7 +444,7 @@ class GFConcrete {
|
|||||||
if (alt.prefixes.some((p: string): boolean => nextToken.startsWith(p))) {
|
if (alt.prefixes.some((p: string): boolean => nextToken.startsWith(p))) {
|
||||||
alt.tokens.forEach((symks: SymKS): void => {
|
alt.tokens.forEach((symks: SymKS): void => {
|
||||||
symks.tokens.forEach((t: string): void => {
|
symks.tokens.forEach((t: string): void => {
|
||||||
ts.push(t.tagWith(sym.tag))
|
ts.push(t.tagWith(sym.tag as string))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
addedAlt = true
|
addedAlt = true
|
||||||
@@ -450,7 +457,7 @@ class GFConcrete {
|
|||||||
// Fall through here when no alts (or none apply)
|
// Fall through here when no alts (or none apply)
|
||||||
sym.tokens.forEach((symks: SymKS): void => {
|
sym.tokens.forEach((symks: SymKS): void => {
|
||||||
symks.tokens.forEach((t: string): void => {
|
symks.tokens.forEach((t: string): void => {
|
||||||
ts.push(t.tagWith(sym.tag))
|
ts.push(t.tagWith(sym.tag as string))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
@@ -460,23 +467,23 @@ class GFConcrete {
|
|||||||
return ts
|
return ts
|
||||||
}
|
}
|
||||||
|
|
||||||
public linearizeAll(tree: Fun): string[] {
|
public linearizeAll(tree: Fun): String[] {
|
||||||
return this.linearizeSyms(tree,'0').map((r): string => {
|
return this.linearizeSyms(tree,'0').map((r): String => {
|
||||||
return this.unlex(this.syms2toks(r.table[0]))
|
return this.unlex(this.syms2toks(r.table[0]))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public linearize(tree: Fun): string {
|
public linearize(tree: Fun): String {
|
||||||
let res = this.linearizeSyms(tree,'0')
|
let res = this.linearizeSyms(tree,'0')
|
||||||
return this.unlex(this.syms2toks(res[0].table[0]))
|
return this.unlex(this.syms2toks(res[0].table[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
public tagAndLinearize(tree: Fun): string[] {
|
public tagAndLinearize(tree: Fun): String[] {
|
||||||
let res = this.linearizeSyms(tree,'0')
|
let res = this.linearizeSyms(tree,'0')
|
||||||
return this.syms2toks(res[0].table[0])
|
return this.syms2toks(res[0].table[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
private unlex(ts: string[]): string {
|
private unlex(ts: String[]): String {
|
||||||
if (ts.length == 0) {
|
if (ts.length == 0) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@@ -486,8 +493,8 @@ class GFConcrete {
|
|||||||
|
|
||||||
let s = ''
|
let s = ''
|
||||||
for (let i = 0; i < ts.length; i++) {
|
for (let i = 0; i < ts.length; i++) {
|
||||||
let t: string = ts[i]
|
let t: String = ts[i]
|
||||||
let after: string | null = i < ts.length-1 ? ts[i+1] : null
|
let after: String | null = i < ts.length-1 ? ts[i+1] : null
|
||||||
s += t
|
s += t
|
||||||
if (after != null
|
if (after != null
|
||||||
&& !t.match(noSpaceAfter)
|
&& !t.match(noSpaceAfter)
|
||||||
@@ -526,7 +533,8 @@ class GFConcrete {
|
|||||||
|
|
||||||
private tokenize(string: string): string[] {
|
private tokenize(string: string): string[] {
|
||||||
let inToken = false
|
let inToken = false
|
||||||
let start: number, end: number
|
let start = 0
|
||||||
|
let end: number
|
||||||
let tokens = []
|
let tokens = []
|
||||||
|
|
||||||
let i: number
|
let i: number
|
||||||
@@ -619,8 +627,7 @@ class GFConcrete {
|
|||||||
let suggs: string[] = []
|
let suggs: string[] = []
|
||||||
if (acc.value) {
|
if (acc.value) {
|
||||||
acc.value.forEach((a: ActiveItem): void =>{
|
acc.value.forEach((a: ActiveItem): void =>{
|
||||||
a.seq.forEach((s: SymKS | SymKP): void => {
|
a.seq.forEach((s: Sym): void => {
|
||||||
if (s.tokens == null) return
|
|
||||||
switch (s.id) {
|
switch (s.id) {
|
||||||
case 'KS': {
|
case 'KS': {
|
||||||
(s as SymKS).tokens.forEach((t: string): void => {
|
(s as SymKS).tokens.forEach((t: string): void => {
|
||||||
@@ -659,9 +666,9 @@ interface Taggable {
|
|||||||
*/
|
*/
|
||||||
interface String {
|
interface String {
|
||||||
tag?: string;
|
tag?: string;
|
||||||
tagWith: (tag: string) => string;
|
tagWith: (tag: string) => String;
|
||||||
}
|
}
|
||||||
String.prototype.tagWith = function (tag: string): string {
|
String.prototype.tagWith = function (tag: string): String {
|
||||||
// returns a copy
|
// returns a copy
|
||||||
let s2 = this
|
let s2 = this
|
||||||
s2.tag = tag
|
s2.tag = tag
|
||||||
@@ -741,6 +748,8 @@ class PArg {
|
|||||||
this.fid = hypos[hypos.length-1]
|
this.fid = hypos[hypos.length-1]
|
||||||
if (hypos.length > 1)
|
if (hypos.length > 1)
|
||||||
this.hypos = hypos.slice(0, hypos.length-1)
|
this.hypos = hypos.slice(0, hypos.length-1)
|
||||||
|
else
|
||||||
|
this.hypos = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,7 +922,7 @@ class SymLit {
|
|||||||
* Trie
|
* Trie
|
||||||
*/
|
*/
|
||||||
class Trie<T> {
|
class Trie<T> {
|
||||||
public value: T[]
|
public value: T[] | null
|
||||||
private items: {[key: string]: Trie<T>}
|
private items: {[key: string]: Trie<T>}
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
@@ -1193,13 +1202,13 @@ class ParseState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private process(
|
private process(
|
||||||
agenda: ActiveItem[],
|
agenda: ActiveItem[] | null,
|
||||||
literalCallback: (fid: FId) => Const | null, // this is right
|
literalCallback: (fid: FId) => Const | null, // this is right
|
||||||
tokenCallback: (tokens: string[], item: ActiveItem) => void
|
tokenCallback: (tokens: string[], item: ActiveItem) => void
|
||||||
): void {
|
): void {
|
||||||
if (agenda != null) {
|
if (agenda != null) {
|
||||||
while (agenda.length > 0) {
|
while (agenda.length > 0) {
|
||||||
let item = agenda.pop()
|
let item = agenda.pop() as ActiveItem
|
||||||
let lin = item.seq
|
let lin = item.seq
|
||||||
|
|
||||||
if (item.dot < lin.length) {
|
if (item.dot < lin.length) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
"use strict";
|
||||||
var GFGrammar = (function () {
|
var GFGrammar = (function () {
|
||||||
function GFGrammar(abstract, concretes) {
|
function GFGrammar(abstract, concretes) {
|
||||||
this.abstract = abstract;
|
this.abstract = abstract;
|
||||||
@@ -171,13 +172,16 @@ var GFAbstract = (function () {
|
|||||||
return t;
|
return t;
|
||||||
};
|
};
|
||||||
GFAbstract.prototype.parseTree = function (str, type) {
|
GFAbstract.prototype.parseTree = function (str, type) {
|
||||||
return this.annotate(this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g), 0), type);
|
var pt = this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g) || [], 0);
|
||||||
|
return pt ? this.annotate(pt, type) : null;
|
||||||
};
|
};
|
||||||
GFAbstract.prototype.parseTree_ = function (tokens, prec) {
|
GFAbstract.prototype.parseTree_ = function (tokens, prec) {
|
||||||
if (tokens.length == 0 || tokens[0] == ')') {
|
if (tokens.length == 0 || tokens[0] == ')') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var t = tokens.shift();
|
var t = tokens.shift();
|
||||||
|
if (!t)
|
||||||
|
return null;
|
||||||
if (t == '(') {
|
if (t == '(') {
|
||||||
var tree = this.parseTree_(tokens, 0);
|
var tree = this.parseTree_(tokens, 0);
|
||||||
tokens.shift();
|
tokens.shift();
|
||||||
@@ -422,7 +426,8 @@ var GFConcrete = (function () {
|
|||||||
};
|
};
|
||||||
GFConcrete.prototype.tokenize = function (string) {
|
GFConcrete.prototype.tokenize = function (string) {
|
||||||
var inToken = false;
|
var inToken = false;
|
||||||
var start, end;
|
var start = 0;
|
||||||
|
var end;
|
||||||
var tokens = [];
|
var tokens = [];
|
||||||
var i;
|
var i;
|
||||||
for (i = 0; i < string.length; i++) {
|
for (i = 0; i < string.length; i++) {
|
||||||
@@ -492,8 +497,6 @@ var GFConcrete = (function () {
|
|||||||
if (acc.value) {
|
if (acc.value) {
|
||||||
acc.value.forEach(function (a) {
|
acc.value.forEach(function (a) {
|
||||||
a.seq.forEach(function (s) {
|
a.seq.forEach(function (s) {
|
||||||
if (s.tokens == null)
|
|
||||||
return;
|
|
||||||
switch (s.id) {
|
switch (s.id) {
|
||||||
case 'KS': {
|
case 'KS': {
|
||||||
s.tokens.forEach(function (t) {
|
s.tokens.forEach(function (t) {
|
||||||
@@ -565,6 +568,8 @@ var PArg = (function () {
|
|||||||
this.fid = hypos[hypos.length - 1];
|
this.fid = hypos[hypos.length - 1];
|
||||||
if (hypos.length > 1)
|
if (hypos.length > 1)
|
||||||
this.hypos = hypos.slice(0, hypos.length - 1);
|
this.hypos = hypos.slice(0, hypos.length - 1);
|
||||||
|
else
|
||||||
|
this.hypos = [];
|
||||||
}
|
}
|
||||||
return PArg;
|
return PArg;
|
||||||
}());
|
}());
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "none",
|
"module": "none",
|
||||||
"target": "es3",
|
"target": "es3",
|
||||||
|
"strict": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"outDir": "js"
|
"outDir": "js"
|
||||||
|
|||||||
Reference in New Issue
Block a user