From 7f031c4a7142bf44d0e220085ff29ec12c8231b4 Mon Sep 17 00:00:00 2001 From: adueck Date: Sat, 12 Aug 2023 15:19:49 +0400 Subject: [PATCH] working for kernel vps w/out 3rd pers masc sing --- .../src/new-verb-engine/roots-and-stems.ts | 2 + src/lib/src/parsing/lookup.tsx | 59 ++- src/lib/src/parsing/parse-phrase.ts | 2 +- src/lib/src/parsing/parse-verb.test.ts | 435 +++++++++++++++++- src/lib/src/parsing/parse-verb.ts | 237 +++++++--- src/lib/src/parsing/parse-vp.ts | 54 ++- 6 files changed, 697 insertions(+), 92 deletions(-) diff --git a/src/lib/src/new-verb-engine/roots-and-stems.ts b/src/lib/src/new-verb-engine/roots-and-stems.ts index 5bd1c59..b75ab17 100644 --- a/src/lib/src/new-verb-engine/roots-and-stems.ts +++ b/src/lib/src/new-verb-engine/roots-and-stems.ts @@ -251,6 +251,8 @@ function getPassivePp( }; } +// TODO: Abstract out the get T.Vhead part + function getRoot( verb: T.VerbEntryNoFVars, genderNum: T.GenderNumber, diff --git a/src/lib/src/parsing/lookup.tsx b/src/lib/src/parsing/lookup.tsx index bd97888..61866f8 100644 --- a/src/lib/src/parsing/lookup.tsx +++ b/src/lib/src/parsing/lookup.tsx @@ -33,29 +33,52 @@ export function lookup(s: Partial): T.DictionaryEntry[] { export function verbLookup(input: string): T.VerbEntry[] { const s = input.slice(0, -1); + const sWoutOo = s.startsWith("و") ? s.slice(1) : undefined; if (s.endsWith("ېږ")) { return verbs.filter( - ({ 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 + sWoutOo + ? ({ entry }) => + [s, sWoutOo].includes(entry.p.slice(0, -1)) || + [s.slice(0, -1) + "دل", sWoutOo.slice(0, -1) + "دل"].includes( + entry.p + ) || + [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( - ({ 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)) + sWoutOo + ? ({ entry }) => + [s, sWoutOo].includes(entry.p.slice(0, -1)) || + // for short intransitive forms + [s, sWoutOo].includes(entry.p.slice(0, -3)) || + [s, sWoutOo].includes(entry.p) || + (entry.psp && [s, sWoutOo].includes(entry.psp)) || + entry.prp === s || + entry.ssp === s || + (entry.separationAtP && + (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)) ); } diff --git a/src/lib/src/parsing/parse-phrase.ts b/src/lib/src/parsing/parse-phrase.ts index be1e9f8..42b9cf3 100644 --- a/src/lib/src/parsing/parse-phrase.ts +++ b/src/lib/src/parsing/parse-phrase.ts @@ -20,7 +20,7 @@ export function parsePhrase( } { const res = [ ...parseNP(s, lookup).filter(({ tokens }) => !tokens.length), - ...parseVerb(s, verbLookup), + // ...parseVerb(s, verbLookup), ...parseVP(s, lookup, verbLookup), ]; diff --git a/src/lib/src/parsing/parse-verb.test.ts b/src/lib/src/parsing/parse-verb.test.ts index f38f553..2d11d15 100644 --- a/src/lib/src/parsing/parse-verb.test.ts +++ b/src/lib/src/parsing/parse-verb.test.ts @@ -7,6 +7,7 @@ import { tokenizer } from "./tokenizer"; const wahul = wordQuery("وهل", "verb"); const leekul = wordQuery("لیکل", "verb"); const manul = wordQuery("منل", "verb"); +const gaalul = wordQuery("ګالل", "verb"); const rasedul = wordQuery("رسېدل", "verb"); const leedul = wordQuery("لیدل", "verb"); const khorul = wordQuery("خوړل", "verb"); @@ -20,6 +21,7 @@ const tests: { cases: { input: string; output: { + ph: string | undefined; root?: { persons: T.Person[]; aspects: T.Aspect[]; @@ -39,6 +41,7 @@ const tests: { input: "وهلم", output: [ { + ph: undefined, root: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["imperfective", "perfective"], @@ -51,6 +54,7 @@ const tests: { input: "وهم", output: [ { + ph: undefined, root: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["imperfective", "perfective"], @@ -67,6 +71,7 @@ const tests: { input: "وهې", output: [ { + ph: undefined, root: { persons: [ T.Person.SecondSingMale, @@ -87,6 +92,7 @@ const tests: { input: "لیکم", output: [ { + ph: undefined, root: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["imperfective", "perfective"], @@ -103,6 +109,7 @@ const tests: { input: "لیکلو", output: [ { + ph: undefined, root: { persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale], aspects: ["imperfective", "perfective"], @@ -115,6 +122,7 @@ const tests: { input: "لیکل", output: [ { + ph: undefined, root: { persons: [T.Person.ThirdPlurMale], aspects: ["imperfective", "perfective"], @@ -131,6 +139,7 @@ const tests: { input: "منله", output: [ { + ph: undefined, root: { persons: [T.Person.ThirdSingFemale], aspects: ["imperfective", "perfective"], @@ -143,6 +152,7 @@ const tests: { input: "مني", output: [ { + ph: undefined, stem: { persons: [ T.Person.ThirdSingMale, @@ -160,6 +170,7 @@ const tests: { input: "منئ", output: [ { + ph: undefined, stem: { persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale], 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: "رسېدلم", output: [ { + ph: undefined, root: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["imperfective", "perfective"], @@ -193,6 +270,7 @@ const tests: { input: "رسېدم", output: [ { + ph: undefined, root: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], 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: "رسېږې", output: [ { + ph: undefined, stem: { persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale], 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 { input: "رسئ", output: [ { + ph: undefined, stem: { persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale], 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: "وینم", output: [ { + ph: undefined, stem: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["imperfective", "perfective"], @@ -247,6 +367,7 @@ const tests: { input: "وینم", output: [ { + ph: undefined, stem: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["imperfective", "perfective"], @@ -259,6 +380,7 @@ const tests: { input: "لیده", output: [ { + ph: undefined, root: { persons: [T.Person.ThirdSingFemale], 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: "خورې", output: [ { + ph: undefined, stem: { persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale], 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: "خوړي", output: [], @@ -287,6 +449,7 @@ const tests: { input: "خوړم", output: [ { + ph: undefined, root: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], 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: "کېني", output: [ { + ph: "کې", stem: { persons: [ T.Person.ThirdSingMale, @@ -321,6 +498,7 @@ const tests: { input: "نم", output: [ { + ph: undefined, stem: { persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale], aspects: ["perfective"], @@ -333,6 +511,7 @@ const tests: { input: "پرېږدو", output: [ { + ph: "پرې", stem: { persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale], 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: "پرېښوده", output: [ { + ph: "پرې", root: { persons: [T.Person.ThirdSingFemale], aspects: ["imperfective", "perfective"], @@ -357,6 +558,7 @@ const tests: { input: "ښودله", output: [ { + ph: undefined, root: { persons: [T.Person.ThirdSingFemale], aspects: ["imperfective", "perfective"], @@ -364,6 +566,7 @@ const tests: { verb: xodul, }, { + ph: undefined, root: { persons: [T.Person.ThirdSingFemale], aspects: ["perfective"], @@ -371,6 +574,7 @@ const tests: { verb: prexodul, }, { + ph: undefined, root: { persons: [T.Person.ThirdSingFemale], aspects: ["perfective"], @@ -388,21 +592,39 @@ tests.forEach(({ label, cases }) => { cases.forEach(({ input, output }) => { const tokens = tokenizer(input); const vbs = parseVerb(tokens, verbLookup).map((r) => r.body); - const madeVbsS = output.reduce[]>((acc, o) => { + const madeVbsS = output.reduce< + [{ type: "PH"; s: string } | undefined, Omit][] + >((acc, o) => { return [ ...acc, ...(["root", "stem"] as const).flatMap((base) => (o[base]?.aspects || []).flatMap((aspect) => - (o[base]?.persons || []).flatMap((person) => ({ - type: "VB" as const, - person, - info: { - type: "verb" as const, - aspect, - base, - verb: o.verb, - }, - })) + (o[base]?.persons || []).flatMap< + [{ type: "PH"; s: string } | undefined, Omit] + >((person) => { + const r: [ + { type: "PH"; s: string } | undefined, + Omit + ] = [ + 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", + }, + ], +]; diff --git a/src/lib/src/parsing/parse-verb.ts b/src/lib/src/parsing/parse-verb.ts index 01e3124..95fdf45 100644 --- a/src/lib/src/parsing/parse-verb.ts +++ b/src/lib/src/parsing/parse-verb.ts @@ -3,7 +3,7 @@ import * as T from "../../../types"; export function parseVerb( tokens: Readonly, verbLookup: (s: string) => T.VerbEntry[] -): T.ParseResult>[] { +): T.ParseResult<[{ type: "PH"; s: string } | undefined, Omit]>[] { if (tokens.length === 0) { return []; } @@ -25,9 +25,13 @@ function matchVerbs( root: T.Person[]; stem: T.Person[]; } -): Omit[] { - const w: Omit[] = []; +): [{ type: "PH"; s: string } | undefined, Omit][] { + const w: ReturnType = []; + const lEnding = s.endsWith("ل"); 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) { const stemMatches = { imperfective: entries.filter(({ entry: e }) => { @@ -44,39 +48,135 @@ function matchVerbs( 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")) { - return false; + return acc; } if (e.ssp) { - const bSep = e.separationAtP ? e.ssp.slice(e.separationAtP) : ""; - return bSep === base || e.ssp === base; - } - if (e.psp) { - const bSep = e.separationAtP ? e.psp.slice(e.separationAtP) : ""; - return bSep === base || e.psp === base; - } - if (e.c.includes("intrans.")) { + const bRest = e.separationAtP ? e.ssp.slice(e.separationAtP) : ""; + if (bRest === base) { + return [ + ...acc, + { + ph: undefined, + entry, + }, + ]; + } + 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); - 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 { - 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]) => { entries.forEach((verb) => { people.stem.forEach((person) => { - w.push({ - type: "VB", - person, - info: { - type: "verb", - aspect: aspect as T.Aspect, - base: "stem", - verb: verb, + w.push([ + "ph" in verb && verb.ph ? { type: "PH", s: verb.ph } : undefined, + { + type: "VB", + person, + info: { + type: "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) { const rootMatches = { imperfective: entries.filter( - ({ entry: e }) => - !e.c.includes("comp") && - (base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1))) + ({ entry: e }) => !e.c.includes("comp") && matchShortOrLong(base, e.p) ), - 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")) { - return false; + return acc; } if (e.separationAtP) { - const bSep = e.p.slice(e.separationAtP); - return ( - base === bSep || - base === e.p || - (!s.endsWith("ل") && - (base === e.p.slice(0, -1) || base === bSep.slice(0, -1))) - ); - } else { - // TODO: perfective roots are so rare could optimize this with a couple of checks? - return e.prp - ? e.prp === base || e.prp.slice(0, -1) === base - : base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1)); + const b = e.prp || e.p; + const bHead = b.slice(0, e.separationAtP); + const bRest = b.slice(e.separationAtP); + if (matchShortOrLong(base, b)) { + return [ + ...acc, + { + ph: bHead, + entry, + }, + ]; + } 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]) => { entries.forEach((verb) => { people.root.forEach((person) => { - w.push({ - type: "VB", - person, - info: { - type: "verb", - aspect: aspect as T.Aspect, - base: "root", - verb: verb, + w.push([ + "ph" in verb && verb.ph ? { type: "PH", s: verb.ph } : undefined, + { + type: "VB", + person, + info: { + type: "verb", + aspect: aspect as T.Aspect, + base: "root", + verb: "ph" in verb ? verb.entry : verb, + }, }, - }); + ]); }); }); }); diff --git a/src/lib/src/parsing/parse-vp.ts b/src/lib/src/parsing/parse-vp.ts index 7c3b41e..ed04e03 100644 --- a/src/lib/src/parsing/parse-vp.ts +++ b/src/lib/src/parsing/parse-vp.ts @@ -101,18 +101,18 @@ export function parseVP( })); }).filter(({ errors }) => !errors.length); // 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[] = []; - 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 = v.info.type === "verb" && v.info.verb.entry.c.includes("intrans."); - - if (!np2) { - const errors: T.ParseError[] = []; + if (intransitive) { + if (np2) return []; const s = np1; - if (!intransitive) { - return []; - } + const errors: T.ParseError[] = []; if (s.inflected) { errors.push({ message: "subject of intransitive verb should not be inflected", @@ -143,7 +143,7 @@ export function parseVP( canChangeTransitivity: false, canChangeStatDyn: false, negative: false, - tense: isPast ? "imperfectivePast" : "presentVerb", + tense: getTenseFromRootsStems(false, v.info.base, v.info.aspect), canChangeVoice: true, isCompound: false, voice: "active", @@ -162,8 +162,18 @@ export function parseVP( errors, }); } else { + // transitive verb + if (!(np1 && np2)) return []; [[np1, np2, false] as const, [np2, np1, true] as const].forEach( ([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 errors: T.ParseError[] = []; if (intransitive) { @@ -230,7 +240,7 @@ export function parseVP( canChangeTransitivity: false, canChangeStatDyn: false, negative: false, - tense: isPast ? "imperfectivePast" : "presentVerb", + tense: getTenseFromRootsStems(false, v.info.base, v.info.aspect), canChangeVoice: true, isCompound: false, voice: "active", @@ -254,3 +264,27 @@ export function parseVP( 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"; + } + } +}