M impls/ts/brzo.ts => impls/ts/brzo.ts +40 -30
@@ 1,86 1,96 @@
+const enum languageKind {
+ Empty,
+ Epsilon,
+ Char,
+ Cat,
+ Alt,
+ Rep
+};
+
interface Empty {
- kind: "empty";
+ kind: languageKind.Empty;
}
-function empty(): Empty { return { kind: "empty" } }
+function empty(): Empty { return { kind: languageKind.Empty } }
interface Epsilon {
- kind: "epsilon";
+ kind: languageKind.Epsilon;
}
+function epsilon(): Epsilon { return { kind: languageKind.Epsilon } }
+
interface Char {
- kind: "char"
+ kind: languageKind.Char
value: string;
}
-function char(value: string): Char { return { kind: "char", value } }
+function char(value: string): Char { return { kind: languageKind.Char, value } }
interface Cat {
- kind: "cat"
+ kind: languageKind.Cat
left: Language
right: Language
}
function cat(left: Language, right: Language): Cat {
- return { kind: "cat", left, right }
+ return { kind: languageKind.Cat, left, right }
}
interface Alt {
- kind: "alt"
+ kind: languageKind.Alt
left: Language
right: Language
}
function alt(left: Language, right: Language): Alt {
- return { kind: "alt", left, right }
+ return { kind: languageKind.Alt, left, right }
}
interface Rep {
- kind: "rep";
+ kind: languageKind.Rep;
value: Language;
}
-function rep(value: Language): Rep { return { kind: "rep", value: value } }
+function rep(value: Language): Rep { return { kind: languageKind.Rep, value } }
type Language = Empty | Epsilon | Rep | Cat | Alt | Char
function is_nullable(l: Language): boolean {
switch (l.kind) {
- case "empty":
+ case languageKind.Empty:
return false;
- case "epsilon":
+ case languageKind.Epsilon:
return true;
- case "char":
+ case languageKind.Char:
return false;
- case "alt":
+ case languageKind.Alt:
return is_nullable(l.left) || is_nullable(l.right);
- case "cat":
+ case languageKind.Cat:
return is_nullable(l.left) && is_nullable(l.right);
- case "rep":
+ case languageKind.Rep:
return true;
}
}
function derive(pat: Language, char: string): Language {
switch (pat.kind) {
- case "epsilon":
- case "empty":
+ case languageKind.Empty:
+ case languageKind.Epsilon:
return empty();
- case "char":
+ case languageKind.Char:
if (pat.value == char) {
- return { kind: "epsilon" };
+ return epsilon();
} else {
- return { kind: "empty" };
+ return empty();
}
- case "rep":
+ case languageKind.Rep:
return cat(derive(pat.value, char), pat);
- case "alt":
- return {
- kind: "alt",
- left: derive(pat.left, char),
- right: derive(pat.right, char)
- };
- case "cat":
+ case languageKind.Alt:
+ return alt(
+ derive(pat.left, char),
+ derive(pat.right, char)
+ );
+ case languageKind.Cat:
const base = cat(derive(pat.left, char), pat.right);
if (is_nullable(pat.left)) {
return alt(derive(pat.right, char), base);
M impls/ts/package-lock.json => impls/ts/package-lock.json +1 -0
@@ 5,6 5,7 @@
"packages": {
"": {
"dependencies": {
+ "@types/node": "^16.11.6",
"jest": "^27.3.1",
"mocha": "^9.1.3",
"ts-jest": "^27.0.7",
M impls/ts/package.json => impls/ts/package.json +1 -0
@@ 1,5 1,6 @@
{
"dependencies": {
+ "@types/node": "^16.11.6",
"jest": "^27.3.1",
"mocha": "^9.1.3",
"ts-jest": "^27.0.7",
A impls/ts/tsconfig.json => impls/ts/tsconfig.json +5 -0
@@ 0,0 1,5 @@
+{
+ "compilerOptions": {
+ "strict": true
+ }
+}