working for kernel vps w/out 3rd pers masc sing

This commit is contained in:
adueck 2023-08-12 15:19:49 +04:00
parent 4893ef0d70
commit 7f031c4a71
6 changed files with 697 additions and 92 deletions

View File

@ -251,6 +251,8 @@ function getPassivePp(
}; };
} }
// TODO: Abstract out the get T.Vhead part
function getRoot( function getRoot(
verb: T.VerbEntryNoFVars, verb: T.VerbEntryNoFVars,
genderNum: T.GenderNumber, genderNum: T.GenderNumber,

View File

@ -33,29 +33,52 @@ export function lookup(s: Partial<T.DictionaryEntry>): T.DictionaryEntry[] {
export function verbLookup(input: string): T.VerbEntry[] { export function verbLookup(input: string): T.VerbEntry[] {
const s = input.slice(0, -1); const s = input.slice(0, -1);
const sWoutOo = s.startsWith("و") ? s.slice(1) : undefined;
if (s.endsWith("ېږ")) { if (s.endsWith("ېږ")) {
return verbs.filter( return verbs.filter(
({ entry }) => sWoutOo
entry.p.slice(0, -1) === s || ? ({ entry }) =>
entry.p === s.slice(0, -1) + "دل" || [s, sWoutOo].includes(entry.p.slice(0, -1)) ||
entry.p === s || [s.slice(0, -1) + "دل", sWoutOo.slice(0, -1) + "دل"].includes(
entry.psp === s || entry.p
entry.prp === s || ) ||
entry.ssp === s [s, sWoutOo].includes(entry.p) ||
(entry.psp && [s, sWoutOo].includes(entry.psp)) ||
entry.prp === s ||
entry.ssp === s
: ({ entry }) =>
entry.p.slice(0, -1) === s ||
entry.p === s.slice(0, -1) + "دل" ||
entry.p === s ||
entry.psp === s ||
entry.prp === s ||
entry.ssp === s
); );
} }
return verbs.filter( return verbs.filter(
({ entry }) => sWoutOo
entry.p.slice(0, -1) === s || ? ({ entry }) =>
// for short intransitive forms [s, sWoutOo].includes(entry.p.slice(0, -1)) ||
entry.p.slice(0, -3) === s || // for short intransitive forms
entry.p === s || [s, sWoutOo].includes(entry.p.slice(0, -3)) ||
entry.psp === s || [s, sWoutOo].includes(entry.p) ||
entry.prp === s || (entry.psp && [s, sWoutOo].includes(entry.psp)) ||
entry.ssp === s || entry.prp === s ||
(entry.separationAtP && entry.ssp === s ||
(entry.p.slice(entry.separationAtP) === s || (entry.separationAtP &&
entry.psp?.slice(entry.separationAtP) === s)) (entry.p.slice(entry.separationAtP) === s ||
entry.psp?.slice(entry.separationAtP) === s))
: ({ entry }) =>
entry.p.slice(0, -1) === s ||
// for short intransitive forms
entry.p.slice(0, -3) === s ||
entry.p === s ||
entry.psp === s ||
entry.prp === s ||
entry.ssp === s ||
(entry.separationAtP &&
(entry.p.slice(entry.separationAtP) === s ||
entry.psp?.slice(entry.separationAtP) === s))
); );
} }

View File

@ -20,7 +20,7 @@ export function parsePhrase(
} { } {
const res = [ const res = [
...parseNP(s, lookup).filter(({ tokens }) => !tokens.length), ...parseNP(s, lookup).filter(({ tokens }) => !tokens.length),
...parseVerb(s, verbLookup), // ...parseVerb(s, verbLookup),
...parseVP(s, lookup, verbLookup), ...parseVP(s, lookup, verbLookup),
]; ];

View File

@ -7,6 +7,7 @@ import { tokenizer } from "./tokenizer";
const wahul = wordQuery("وهل", "verb"); const wahul = wordQuery("وهل", "verb");
const leekul = wordQuery("لیکل", "verb"); const leekul = wordQuery("لیکل", "verb");
const manul = wordQuery("منل", "verb"); const manul = wordQuery("منل", "verb");
const gaalul = wordQuery("ګالل", "verb");
const rasedul = wordQuery("رسېدل", "verb"); const rasedul = wordQuery("رسېدل", "verb");
const leedul = wordQuery("لیدل", "verb"); const leedul = wordQuery("لیدل", "verb");
const khorul = wordQuery("خوړل", "verb"); const khorul = wordQuery("خوړل", "verb");
@ -20,6 +21,7 @@ const tests: {
cases: { cases: {
input: string; input: string;
output: { output: {
ph: string | undefined;
root?: { root?: {
persons: T.Person[]; persons: T.Person[];
aspects: T.Aspect[]; aspects: T.Aspect[];
@ -39,6 +41,7 @@ const tests: {
input: "وهلم", input: "وهلم",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -51,6 +54,7 @@ const tests: {
input: "وهم", input: "وهم",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -67,6 +71,7 @@ const tests: {
input: "وهې", input: "وهې",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [ persons: [
T.Person.SecondSingMale, T.Person.SecondSingMale,
@ -87,6 +92,7 @@ const tests: {
input: "لیکم", input: "لیکم",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -103,6 +109,7 @@ const tests: {
input: "لیکلو", input: "لیکلو",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale], persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -115,6 +122,7 @@ const tests: {
input: "لیکل", input: "لیکل",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.ThirdPlurMale], persons: [T.Person.ThirdPlurMale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -131,6 +139,7 @@ const tests: {
input: "منله", input: "منله",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.ThirdSingFemale], persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -143,6 +152,7 @@ const tests: {
input: "مني", input: "مني",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [ persons: [
T.Person.ThirdSingMale, T.Person.ThirdSingMale,
@ -160,6 +170,7 @@ const tests: {
input: "منئ", input: "منئ",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale], persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -172,6 +183,71 @@ const tests: {
}, },
], ],
}, },
// with perfective head
{
input: "ومنلم",
output: [
{
ph: "و",
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
},
verb: manul,
},
],
},
{
input: "منلم",
output: [
{
ph: undefined,
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective", "imperfective"],
},
verb: manul,
},
],
},
{
input: "وګاللې",
output: [
{
ph: "و",
root: {
persons: [
T.Person.SecondSingFemale,
T.Person.SecondSingMale,
T.Person.ThirdPlurFemale,
],
aspects: ["perfective"],
},
verb: gaalul,
},
],
},
{
input: "وګالې",
output: [
{
ph: "و",
root: {
persons: [
T.Person.SecondSingFemale,
T.Person.SecondSingMale,
T.Person.ThirdPlurFemale,
],
aspects: ["perfective"],
},
stem: {
persons: [T.Person.SecondSingFemale, T.Person.SecondSingMale],
aspects: ["perfective"],
},
verb: gaalul,
},
],
},
], ],
}, },
{ {
@ -181,6 +257,7 @@ const tests: {
input: "رسېدلم", input: "رسېدلم",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -193,6 +270,7 @@ const tests: {
input: "رسېدم", input: "رسېدم",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -201,10 +279,24 @@ const tests: {
}, },
], ],
}, },
{
input: "ورسېدم",
output: [
{
ph: "و",
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
},
verb: rasedul,
},
],
},
{ {
input: "رسېږې", input: "رسېږې",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale], persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -213,11 +305,25 @@ const tests: {
}, },
], ],
}, },
{
input: "ورسېږې",
output: [
{
ph: "و",
stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["perfective"],
},
verb: rasedul,
},
],
},
// short version of intransitive as well // short version of intransitive as well
{ {
input: "رسئ", input: "رسئ",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale], persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -226,6 +332,19 @@ const tests: {
}, },
], ],
}, },
{
input: "ورسئ",
output: [
{
ph: "و",
stem: {
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
aspects: ["perfective"],
},
verb: rasedul,
},
],
},
], ],
}, },
{ {
@ -235,6 +354,7 @@ const tests: {
input: "وینم", input: "وینم",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -247,6 +367,7 @@ const tests: {
input: "وینم", input: "وینم",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -259,6 +380,7 @@ const tests: {
input: "لیده", input: "لیده",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.ThirdSingFemale], persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -267,10 +389,37 @@ const tests: {
}, },
], ],
}, },
{
input: "ولیده",
output: [
{
ph: "و",
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"],
},
verb: leedul,
},
],
},
{
input: "ولیدله",
output: [
{
ph: "و",
root: {
persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"],
},
verb: leedul,
},
],
},
{ {
input: "خورې", input: "خورې",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale], persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -279,6 +428,19 @@ const tests: {
}, },
], ],
}, },
{
input: "وخورې",
output: [
{
ph: "و",
stem: {
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
aspects: ["perfective"],
},
verb: khorul,
},
],
},
{ {
input: "خوړي", input: "خوړي",
output: [], output: [],
@ -287,6 +449,7 @@ const tests: {
input: "خوړم", input: "خوړم",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -295,6 +458,19 @@ const tests: {
}, },
], ],
}, },
{
input: "وخوړم",
output: [
{
ph: "و",
root: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"],
},
verb: khorul,
},
],
},
], ],
}, },
{ {
@ -304,6 +480,7 @@ const tests: {
input: "کېني", input: "کېني",
output: [ output: [
{ {
ph: "کې",
stem: { stem: {
persons: [ persons: [
T.Person.ThirdSingMale, T.Person.ThirdSingMale,
@ -321,6 +498,7 @@ const tests: {
input: "نم", input: "نم",
output: [ output: [
{ {
ph: undefined,
stem: { stem: {
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
aspects: ["perfective"], aspects: ["perfective"],
@ -333,6 +511,7 @@ const tests: {
input: "پرېږدو", input: "پرېږدو",
output: [ output: [
{ {
ph: "پرې",
stem: { stem: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale], persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -341,10 +520,32 @@ const tests: {
}, },
], ],
}, },
{
input: "ږدو",
output: [
{
ph: undefined,
stem: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["perfective"],
},
verb: prexodul,
},
{
ph: undefined,
stem: {
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
aspects: ["imperfective", "perfective"],
},
verb: kexodul,
},
],
},
{ {
input: "پرېښوده", input: "پرېښوده",
output: [ output: [
{ {
ph: "پرې",
root: { root: {
persons: [T.Person.ThirdSingFemale], persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -357,6 +558,7 @@ const tests: {
input: "ښودله", input: "ښودله",
output: [ output: [
{ {
ph: undefined,
root: { root: {
persons: [T.Person.ThirdSingFemale], persons: [T.Person.ThirdSingFemale],
aspects: ["imperfective", "perfective"], aspects: ["imperfective", "perfective"],
@ -364,6 +566,7 @@ const tests: {
verb: xodul, verb: xodul,
}, },
{ {
ph: undefined,
root: { root: {
persons: [T.Person.ThirdSingFemale], persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"], aspects: ["perfective"],
@ -371,6 +574,7 @@ const tests: {
verb: prexodul, verb: prexodul,
}, },
{ {
ph: undefined,
root: { root: {
persons: [T.Person.ThirdSingFemale], persons: [T.Person.ThirdSingFemale],
aspects: ["perfective"], aspects: ["perfective"],
@ -388,21 +592,39 @@ tests.forEach(({ label, cases }) => {
cases.forEach(({ input, output }) => { cases.forEach(({ input, output }) => {
const tokens = tokenizer(input); const tokens = tokenizer(input);
const vbs = parseVerb(tokens, verbLookup).map((r) => r.body); const vbs = parseVerb(tokens, verbLookup).map((r) => r.body);
const madeVbsS = output.reduce<Omit<T.VBE, "ps">[]>((acc, o) => { const madeVbsS = output.reduce<
[{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">][]
>((acc, o) => {
return [ return [
...acc, ...acc,
...(["root", "stem"] as const).flatMap((base) => ...(["root", "stem"] as const).flatMap((base) =>
(o[base]?.aspects || []).flatMap((aspect) => (o[base]?.aspects || []).flatMap((aspect) =>
(o[base]?.persons || []).flatMap((person) => ({ (o[base]?.persons || []).flatMap<
type: "VB" as const, [{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">]
person, >((person) => {
info: { const r: [
type: "verb" as const, { type: "PH"; s: string } | undefined,
aspect, Omit<T.VBE, "ps">
base, ] = [
verb: o.verb, aspect === "perfective" && o.ph
}, ? {
})) type: "PH",
s: o.ph,
}
: undefined,
{
type: "VB" as const,
person,
info: {
type: "verb" as const,
aspect,
base,
verb: o.verb,
},
},
];
return [r];
})
) )
), ),
]; ];
@ -411,3 +633,194 @@ tests.forEach(({ label, cases }) => {
}); });
}); });
}); });
const b = [
[
undefined,
{
info: {
aspect: "imperfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 6,
type: "VB",
},
],
[
undefined,
{
info: {
aspect: "imperfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 7,
type: "VB",
},
],
[
undefined,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to leave, abandon, forsake, let go, allow",
ec: "abandon",
f: "prexodúl",
g: "prexodul",
i: 2516,
noOo: true,
p: "پرېښودل",
psf: "preGd",
psp: "پرېږد",
r: 4,
separationAtF: 3,
separationAtP: 3,
ts: 1527815190,
},
},
},
person: 6,
type: "VB",
},
],
[
undefined,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to leave, abandon, forsake, let go, allow",
ec: "abandon",
f: "prexodúl",
g: "prexodul",
i: 2516,
noOo: true,
p: "پرېښودل",
psf: "preGd",
psp: "پرېږد",
r: 4,
separationAtF: 3,
separationAtP: 3,
ts: 1527815190,
},
},
},
person: 7,
type: "VB",
},
],
[
{ s: "کې", type: "PH" },
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 6,
type: "VB",
},
],
[
{ s: "کې", type: "PH" },
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. trans.",
e: "to put, to put down, to set in place",
ec: "put,puts,putting,put,put",
f: "kexodul",
g: "kexodul",
i: 11193,
noOo: true,
p: "کېښودل",
psf: "Gd",
psp: "ږد",
r: 4,
separationAtF: 2,
separationAtP: 2,
ssf: "kéGd",
ssp: "کېږد",
ts: 1527812284,
},
},
},
person: 7,
type: "VB",
},
],
];

View File

@ -3,7 +3,7 @@ import * as T from "../../../types";
export function parseVerb( export function parseVerb(
tokens: Readonly<T.Token[]>, tokens: Readonly<T.Token[]>,
verbLookup: (s: string) => T.VerbEntry[] verbLookup: (s: string) => T.VerbEntry[]
): T.ParseResult<Omit<T.VBE, "ps">>[] { ): T.ParseResult<[{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">]>[] {
if (tokens.length === 0) { if (tokens.length === 0) {
return []; return [];
} }
@ -25,9 +25,13 @@ function matchVerbs(
root: T.Person[]; root: T.Person[];
stem: T.Person[]; stem: T.Person[];
} }
): Omit<T.VBE, "ps">[] { ): [{ type: "PH"; s: string } | undefined, Omit<T.VBE, "ps">][] {
const w: Omit<T.VBE, "ps">[] = []; const w: ReturnType<typeof matchVerbs> = [];
const lEnding = s.endsWith("ل");
const base = s.endsWith("ل") ? s : s.slice(0, -1); const base = s.endsWith("ل") ? s : s.slice(0, -1);
const matchShortOrLong = (b: string, x: string) => {
return b === x || (!lEnding && b === x.slice(0, -1));
};
if (people.stem.length) { if (people.stem.length) {
const stemMatches = { const stemMatches = {
imperfective: entries.filter(({ entry: e }) => { imperfective: entries.filter(({ entry: e }) => {
@ -44,39 +48,135 @@ function matchVerbs(
return e.p.slice(0, -1) === base; return e.p.slice(0, -1) === base;
} }
}), }),
perfective: entries.filter(({ entry: e }) => { perfective: entries.reduce<
{ ph: string | undefined; entry: T.VerbEntry }[]
>((acc, entry) => {
const e = entry.entry;
if (e.c.includes("comp")) { if (e.c.includes("comp")) {
return false; return acc;
} }
if (e.ssp) { if (e.ssp) {
const bSep = e.separationAtP ? e.ssp.slice(e.separationAtP) : ""; const bRest = e.separationAtP ? e.ssp.slice(e.separationAtP) : "";
return bSep === base || e.ssp === base; if (bRest === base) {
} return [
if (e.psp) { ...acc,
const bSep = e.separationAtP ? e.psp.slice(e.separationAtP) : ""; {
return bSep === base || e.psp === base; ph: undefined,
} entry,
if (e.c.includes("intrans.")) { },
];
}
if (e.ssp === base) {
return [
...acc,
{
ph: e.separationAtF
? e.ssp.slice(0, e.separationAtP)
: undefined,
entry,
},
];
}
} else if (e.psp) {
const bRest = e.separationAtP ? e.psp.slice(e.separationAtP) : "";
if (bRest === base) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
if (e.psp === base && e.separationAtP) {
return [
...acc,
{
ph: e.psp.slice(0, e.separationAtP),
entry,
},
];
}
if ((base.startsWith("و") && base.slice(1)) === e.psp) {
return [
...acc,
{
ph: "و",
entry,
},
];
}
if (base === e.psp) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
} else if (e.c.includes("intrans.")) {
const miniRoot = e.p.slice(0, -3); const miniRoot = e.p.slice(0, -3);
return miniRoot + "ېږ" === base || miniRoot === base; const miniRootEg = miniRoot + "ېږ";
if ([miniRoot, miniRootEg].includes(base)) {
return [
...acc,
{
ph: undefined,
entry,
},
];
} else if (
base.startsWith("و") &&
[miniRoot, miniRootEg].includes(base.slice(1))
) {
return [
...acc,
{
ph: "و", // TODO: check for وا etc
entry,
},
];
}
} else { } else {
return e.p.slice(0, -1) === base; const eb = e.p.slice(0, -1);
if (eb === base) {
return [
...acc,
{
ph: undefined,
entry,
},
];
} else if (base.startsWith("و") && eb === base.slice(1)) {
return [
...acc,
{
ph: "و",
entry,
},
];
}
} }
}), return acc;
}, []),
}; };
Object.entries(stemMatches).forEach(([aspect, entries]) => { Object.entries(stemMatches).forEach(([aspect, entries]) => {
entries.forEach((verb) => { entries.forEach((verb) => {
people.stem.forEach((person) => { people.stem.forEach((person) => {
w.push({ w.push([
type: "VB", "ph" in verb && verb.ph ? { type: "PH", s: verb.ph } : undefined,
person, {
info: { type: "VB",
type: "verb", person,
aspect: aspect as T.Aspect, info: {
base: "stem", type: "verb",
verb: verb, aspect: aspect as T.Aspect,
base: "stem",
verb: "ph" in verb ? verb.entry : verb,
},
}, },
}); ]);
}); });
}); });
}); });
@ -84,43 +184,76 @@ function matchVerbs(
if (people.root.length) { if (people.root.length) {
const rootMatches = { const rootMatches = {
imperfective: entries.filter( imperfective: entries.filter(
({ entry: e }) => ({ entry: e }) => !e.c.includes("comp") && matchShortOrLong(base, e.p)
!e.c.includes("comp") &&
(base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1)))
), ),
perfective: entries.filter(({ entry: e }) => { perfective: entries.reduce<
{ ph: string | undefined; entry: T.VerbEntry }[]
>((acc, entry) => {
const e = entry.entry;
if (e.c.includes("comp")) { if (e.c.includes("comp")) {
return false; return acc;
} }
if (e.separationAtP) { if (e.separationAtP) {
const bSep = e.p.slice(e.separationAtP); const b = e.prp || e.p;
return ( const bHead = b.slice(0, e.separationAtP);
base === bSep || const bRest = b.slice(e.separationAtP);
base === e.p || if (matchShortOrLong(base, b)) {
(!s.endsWith("ل") && return [
(base === e.p.slice(0, -1) || base === bSep.slice(0, -1))) ...acc,
); {
} else { ph: bHead,
// TODO: perfective roots are so rare could optimize this with a couple of checks? entry,
return e.prp },
? e.prp === base || e.prp.slice(0, -1) === base ];
: base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1)); } else if (matchShortOrLong(base, bRest)) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
} else if (!e.prp) {
const baseNoOo = base.startsWith("و") && base.slice(1);
if (baseNoOo && matchShortOrLong(baseNoOo, e.p)) {
return [
...acc,
{
ph: "و",
entry,
},
];
} else if (matchShortOrLong(base, e.p)) {
return [
...acc,
{
ph: undefined,
entry,
},
];
}
} }
}), return acc;
}, []),
}; };
Object.entries(rootMatches).forEach(([aspect, entries]) => { Object.entries(rootMatches).forEach(([aspect, entries]) => {
entries.forEach((verb) => { entries.forEach((verb) => {
people.root.forEach((person) => { people.root.forEach((person) => {
w.push({ w.push([
type: "VB", "ph" in verb && verb.ph ? { type: "PH", s: verb.ph } : undefined,
person, {
info: { type: "VB",
type: "verb", person,
aspect: aspect as T.Aspect, info: {
base: "root", type: "verb",
verb: verb, aspect: aspect as T.Aspect,
base: "root",
verb: "ph" in verb ? verb.entry : verb,
},
}, },
}); ]);
}); });
}); });
}); });

View File

@ -101,18 +101,18 @@ export function parseVP(
})); }));
}).filter(({ errors }) => !errors.length); }).filter(({ errors }) => !errors.length);
// TODO: be able to bind mulitple vals // TODO: be able to bind mulitple vals
return bindParseResult(vb, (tokens, { np1, np2, v }) => { return bindParseResult(vb, (tokens, { np1, np2, v: [ph, v] }) => {
const w: T.ParseResult<T.VPSelectionComplete>[] = []; const w: T.ParseResult<T.VPSelectionComplete>[] = [];
const isPast = v.info.type === "verb" && v.info.base === "root"; if (v.info.type === "equative") {
throw new Error("not yet implemented");
}
const isPast = v.info.base === "root";
const intransitive = const intransitive =
v.info.type === "verb" && v.info.verb.entry.c.includes("intrans."); v.info.type === "verb" && v.info.verb.entry.c.includes("intrans.");
if (intransitive) {
if (!np2) { if (np2) return [];
const errors: T.ParseError[] = [];
const s = np1; const s = np1;
if (!intransitive) { const errors: T.ParseError[] = [];
return [];
}
if (s.inflected) { if (s.inflected) {
errors.push({ errors.push({
message: "subject of intransitive verb should not be inflected", message: "subject of intransitive verb should not be inflected",
@ -143,7 +143,7 @@ export function parseVP(
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
tense: isPast ? "imperfectivePast" : "presentVerb", tense: getTenseFromRootsStems(false, v.info.base, v.info.aspect),
canChangeVoice: true, canChangeVoice: true,
isCompound: false, isCompound: false,
voice: "active", voice: "active",
@ -162,8 +162,18 @@ export function parseVP(
errors, errors,
}); });
} else { } else {
// transitive verb
if (!(np1 && np2)) return [];
[[np1, np2, false] as const, [np2, np1, true] as const].forEach( [[np1, np2, false] as const, [np2, np1, true] as const].forEach(
([s, o, reversed]) => { ([s, o, reversed]) => {
if (v.info.type === "equative") {
throw new Error("not yet implemented");
}
if (!s || !o) return [];
// TODO: check if perfective head MATCHES verb
if (v.info.aspect === "perfective" && !ph) {
return [];
}
const subjPerson = getPersonFromNP(s.selection); const subjPerson = getPersonFromNP(s.selection);
const errors: T.ParseError[] = []; const errors: T.ParseError[] = [];
if (intransitive) { if (intransitive) {
@ -230,7 +240,7 @@ export function parseVP(
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
tense: isPast ? "imperfectivePast" : "presentVerb", tense: getTenseFromRootsStems(false, v.info.base, v.info.aspect),
canChangeVoice: true, canChangeVoice: true,
isCompound: false, isCompound: false,
voice: "active", voice: "active",
@ -254,3 +264,27 @@ export function parseVP(
return w; return w;
}); });
} }
function getTenseFromRootsStems(
hasBa: boolean,
base: "root" | "stem",
aspect: T.Aspect
): T.VerbTense {
if (!hasBa) {
if (base === "root") {
return aspect === "perfective" ? "perfectivePast" : "imperfectivePast";
} else {
return aspect === "imperfective" ? "presentVerb" : "subjunctiveVerb";
}
} else {
if (base === "root") {
return aspect === "perfective"
? "habitualPerfectivePast"
: "habitualImperfectivePast";
} else {
return aspect === "imperfective"
? "imperfectiveFuture"
: "perfectiveFuture";
}
}
}