more on imperatives
This commit is contained in:
parent
8c336e8a71
commit
02b6396686
|
@ -0,0 +1,243 @@
|
|||
const expected = [
|
||||
{
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 2,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 3,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 2,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 3,
|
||||
type: "VB",
|
||||
},
|
||||
];
|
||||
|
||||
const received = [
|
||||
{
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 2,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 3,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 2,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
imperative: true,
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 3,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 5,
|
||||
type: "VB",
|
||||
},
|
||||
{
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: {
|
||||
entry: {
|
||||
c: "v. trans.",
|
||||
e: "to accept, to believe",
|
||||
ec: "accepting",
|
||||
f: "manul",
|
||||
g: "manul",
|
||||
p: "منل",
|
||||
r: 4,
|
||||
tppf: "maanu",
|
||||
tppp: "مانه",
|
||||
ts: 1527815085,
|
||||
},
|
||||
},
|
||||
},
|
||||
person: 5,
|
||||
type: "VB",
|
||||
},
|
||||
];
|
|
@ -33,6 +33,7 @@ const alwatul = wordQuery("الوتل", "verb");
|
|||
|
||||
// TODO: azmoyul etc
|
||||
// TODO: cleaner and more thorough handling of ا seperating verbs ee - wee etc
|
||||
// TODO: test imperatives
|
||||
|
||||
const tests: {
|
||||
label: string;
|
||||
|
@ -47,6 +48,10 @@ const tests: {
|
|||
persons: T.Person[];
|
||||
aspects: T.Aspect[];
|
||||
};
|
||||
imperative?: {
|
||||
persons: T.Person[];
|
||||
aspects: T.Aspect[];
|
||||
};
|
||||
verb: T.VerbEntry;
|
||||
}[];
|
||||
}[];
|
||||
|
@ -191,11 +196,30 @@ const tests: {
|
|||
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
aspects: ["imperfective", "perfective"],
|
||||
},
|
||||
imperative: {
|
||||
persons: getPeople(2, "pl"),
|
||||
aspects: ["imperfective", "perfective"],
|
||||
},
|
||||
verb: manul,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "منه",
|
||||
output: [
|
||||
{
|
||||
imperative: {
|
||||
persons: getPeople(2, "sing"),
|
||||
aspects: ["imperfective", "perfective"],
|
||||
},
|
||||
root: {
|
||||
persons: [T.Person.ThirdSingFemale],
|
||||
aspects: ["imperfective", "perfective"],
|
||||
},
|
||||
verb: manul,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "منلم",
|
||||
output: [
|
||||
|
@ -258,6 +282,10 @@ const tests: {
|
|||
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
aspects: ["imperfective", "perfective"],
|
||||
},
|
||||
imperative: {
|
||||
persons: getPeople(2, "pl"),
|
||||
aspects: ["imperfective", "perfective"],
|
||||
},
|
||||
verb: rasedul,
|
||||
},
|
||||
],
|
||||
|
@ -309,7 +337,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "خورې",
|
||||
output: [
|
||||
|
@ -322,7 +349,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "خوړي",
|
||||
output: [],
|
||||
|
@ -351,7 +377,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "کوت",
|
||||
output: [
|
||||
|
@ -376,7 +401,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "خلم",
|
||||
output: [
|
||||
|
@ -401,7 +425,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "خیستلم",
|
||||
output: [
|
||||
|
@ -426,7 +449,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
input: "لوځې",
|
||||
output: [
|
||||
|
@ -913,7 +935,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
// TODO: It would probably be more effecient just to return the kedul verb options
|
||||
// and then when we put things together with the perfective head parsed they could
|
||||
// become raatlul etc...
|
||||
|
@ -994,7 +1015,7 @@ tests.forEach(({ label, cases }) => {
|
|||
const madeVbsS = output.reduce<T.ParsedVBE[]>((acc, o) => {
|
||||
return [
|
||||
...acc,
|
||||
...(["root", "stem"] as const).flatMap((base) =>
|
||||
...(["root", "stem", "imperative"] as const).flatMap((base) =>
|
||||
(o[base]?.aspects || []).flatMap((aspect) =>
|
||||
(o[base]?.persons || []).flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
|
@ -1003,8 +1024,13 @@ tests.forEach(({ label, cases }) => {
|
|||
info: {
|
||||
type: "verb" as const,
|
||||
aspect,
|
||||
base,
|
||||
base: base === "imperative" ? "stem" : base,
|
||||
verb: o.verb,
|
||||
...(base === "imperative"
|
||||
? {
|
||||
imperative: true,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
])
|
||||
|
|
|
@ -36,7 +36,9 @@ export function parseVerb(
|
|||
errors: [],
|
||||
}));
|
||||
}
|
||||
const people = getVerbEnding(first.s);
|
||||
const ending = first.s.at(-1) || "";
|
||||
const people = getVerbEnding(ending);
|
||||
const imperativePeople = getImperativeVerbEnding(ending);
|
||||
// First do rough verb lookup, grab wide pool of possible verbs (low searching complexity for fast lookup)
|
||||
// TODO: can optimize this to not have to look for possible stems/roots if none
|
||||
const verbs = lookup(first.s, "verb");
|
||||
|
@ -44,7 +46,7 @@ export function parseVerb(
|
|||
// console.log({ verbs: JSON.stringify(verbs) });
|
||||
// }
|
||||
// Then find out which ones match exactly and how
|
||||
return matchVerbs(first.s, verbs, people).map((body) => ({
|
||||
return matchVerbs(first.s, verbs, people, imperativePeople).map((body) => ({
|
||||
tokens: rest,
|
||||
body,
|
||||
errors: [],
|
||||
|
@ -57,7 +59,8 @@ function matchVerbs(
|
|||
people: {
|
||||
root: T.Person[];
|
||||
stem: T.Person[];
|
||||
}
|
||||
},
|
||||
imperativePeople: T.Person[]
|
||||
): T.ParsedVBE[] {
|
||||
const w: T.ParsedVBE[] = [];
|
||||
const lEnding = s.endsWith("ل");
|
||||
|
@ -65,7 +68,7 @@ function matchVerbs(
|
|||
const matchShortOrLong = (b: string, x: string) => {
|
||||
return b === x || (!lEnding && b === x.slice(0, -1));
|
||||
};
|
||||
if (people.stem.length) {
|
||||
if (people.stem.length || imperativePeople.length) {
|
||||
const stemMatches = {
|
||||
imperfective: entries.filter(({ entry: e }) => {
|
||||
if (e.c.includes("comp")) {
|
||||
|
@ -152,6 +155,19 @@ function matchVerbs(
|
|||
},
|
||||
});
|
||||
});
|
||||
imperativePeople.forEach((person) => {
|
||||
w.push({
|
||||
type: "VB",
|
||||
person,
|
||||
info: {
|
||||
type: "verb",
|
||||
aspect: aspect as T.Aspect,
|
||||
base: "stem",
|
||||
verb: removeFVarientsFromVerb(verb),
|
||||
imperative: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -291,16 +307,26 @@ function matchVerbs(
|
|||
return w;
|
||||
}
|
||||
|
||||
function getVerbEnding(p: string): {
|
||||
root: T.Person[];
|
||||
function getImperativeVerbEnding(e: string): T.Person[] {
|
||||
if (e === "ه") {
|
||||
return [T.Person.SecondSingMale, T.Person.SecondSingFemale];
|
||||
}
|
||||
if (e === "ئ") {
|
||||
return [T.Person.SecondPlurMale, T.Person.SecondPlurFemale];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function getVerbEnding(e: string): {
|
||||
stem: T.Person[];
|
||||
root: T.Person[];
|
||||
} {
|
||||
if (p.endsWith("م")) {
|
||||
if (e === "م") {
|
||||
return {
|
||||
root: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||
stem: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||
};
|
||||
} else if (p.endsWith("ې")) {
|
||||
} else if (e === "ې") {
|
||||
return {
|
||||
root: [
|
||||
T.Person.SecondSingMale,
|
||||
|
@ -309,7 +335,7 @@ function getVerbEnding(p: string): {
|
|||
],
|
||||
stem: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||
};
|
||||
} else if (p.endsWith("ي")) {
|
||||
} else if (e === "ي") {
|
||||
return {
|
||||
stem: [
|
||||
T.Person.ThirdSingMale,
|
||||
|
@ -319,22 +345,22 @@ function getVerbEnding(p: string): {
|
|||
],
|
||||
root: [],
|
||||
};
|
||||
} else if (p.endsWith("و")) {
|
||||
} else if (e === "و") {
|
||||
return {
|
||||
root: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||
stem: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||
};
|
||||
} else if (p.endsWith("ئ")) {
|
||||
} else if (e === "ئ") {
|
||||
return {
|
||||
root: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
stem: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
};
|
||||
} else if (p.endsWith("ه")) {
|
||||
} else if (e === "ه") {
|
||||
return {
|
||||
root: [T.Person.ThirdSingFemale],
|
||||
stem: [],
|
||||
};
|
||||
} else if (p.endsWith("ل")) {
|
||||
} else if (e === "ل") {
|
||||
return {
|
||||
root: [T.Person.ThirdPlurMale],
|
||||
stem: [],
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
startsVerbSection,
|
||||
} from "./utils";
|
||||
import {
|
||||
getSubjectSelection,
|
||||
makeObjectSelectionComplete,
|
||||
makeSubjectSelectionComplete,
|
||||
} from "../phrase-building/blocks-utils";
|
||||
|
@ -22,8 +23,10 @@ import { parseBlocks } from "./parse-blocks";
|
|||
import { makePronounSelection } from "../phrase-building/make-selections";
|
||||
import { isFirstOrSecondPersPronoun } from "../phrase-building/render-vp";
|
||||
import { LookupFunction } from "./lookup";
|
||||
import { personToGenNum } from "../misc-helpers";
|
||||
import { isSecondPerson, personToGenNum } from "../misc-helpers";
|
||||
import { equals, zip } from "rambda";
|
||||
import { isPrimitive } from "util";
|
||||
import { isImperativeTense } from "../type-predicates";
|
||||
// to hide equatives type-doubling issue
|
||||
|
||||
// TODO: word query for kawul/kedul/stat/dyn
|
||||
|
@ -74,16 +77,16 @@ function getTenses(
|
|||
blocks: T.ParsedBlock[],
|
||||
ba: boolean
|
||||
): {
|
||||
tense: T.VerbTense | T.PerfectTense;
|
||||
tense: T.VerbTense | T.PerfectTense | T.ImperativeTense;
|
||||
person: T.Person;
|
||||
transitivities: T.Transitivity[];
|
||||
negative: boolean;
|
||||
verb: T.VerbEntry;
|
||||
}[] {
|
||||
const negIndex = blocks.findIndex(
|
||||
(x) => x.type === "negative" && !x.imperative
|
||||
);
|
||||
const negative = negIndex !== -1;
|
||||
const negIndex = blocks.findIndex((x) => x.type === "negative");
|
||||
const negative: T.NegativeBlock | undefined = blocks[negIndex] as
|
||||
| T.NegativeBlock
|
||||
| undefined;
|
||||
const phIndex = blocks.findIndex((x) => x.type === "PH");
|
||||
const vbeIndex = blocks.findIndex((x) => x.type === "VB");
|
||||
const ph = phIndex !== -1 ? (blocks[phIndex] as T.ParsedPH) : undefined;
|
||||
|
@ -101,13 +104,28 @@ function getTenses(
|
|||
return [];
|
||||
}
|
||||
}
|
||||
const tense = getTenseFromRootsStems(ba, verb.info.base, verb.info.aspect);
|
||||
const tense = getTenseFromRootsStems(
|
||||
ba,
|
||||
verb.info.base,
|
||||
verb.info.aspect,
|
||||
!!negative,
|
||||
verb.info.imperative
|
||||
);
|
||||
if (!tense) {
|
||||
return [];
|
||||
}
|
||||
const transitivities = getTransitivities(verb.info.verb);
|
||||
if (verb.info.imperative && negative && !negative.imperative) {
|
||||
return [];
|
||||
}
|
||||
if (!verb.info.imperative && negative && negative.imperative) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
tense,
|
||||
transitivities,
|
||||
negative,
|
||||
negative: !!negative,
|
||||
person: verb.person,
|
||||
verb: verb.info.verb,
|
||||
},
|
||||
|
@ -141,7 +159,7 @@ function getTenses(
|
|||
{
|
||||
tense,
|
||||
transitivities,
|
||||
negative,
|
||||
negative: !!negative,
|
||||
person: equative.person,
|
||||
verb: pPart.info.verb,
|
||||
},
|
||||
|
@ -159,7 +177,7 @@ function finishPossibleVPSs({
|
|||
tokens,
|
||||
person,
|
||||
}: {
|
||||
tense: T.VerbTense | T.PerfectTense;
|
||||
tense: T.VerbTense | T.PerfectTense | T.ImperativeTense;
|
||||
transitivities: T.Transitivity[];
|
||||
npsAndAps: (T.ParsedNP | T.APSelection)[];
|
||||
miniPronouns: T.ParsedMiniPronoun[];
|
||||
|
@ -169,7 +187,8 @@ function finishPossibleVPSs({
|
|||
person: T.Person;
|
||||
}): T.ParseResult<T.VPSelectionComplete>[] {
|
||||
const isPast = isPastTense(tense);
|
||||
return transitivities.flatMap<T.ParseResult<T.VPSelectionComplete>>(
|
||||
return transitivities
|
||||
.flatMap<T.ParseResult<T.VPSelectionComplete>>(
|
||||
(transitivity): T.ParseResult<T.VPSelectionComplete>[] => {
|
||||
const v: T.VerbSelectionComplete = {
|
||||
type: "verb",
|
||||
|
@ -211,7 +230,20 @@ function finishPossibleVPSs({
|
|||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
.filter(checkImperative2ndPers);
|
||||
}
|
||||
|
||||
function checkImperative2ndPers({
|
||||
body: vps,
|
||||
}: T.ParseResult<T.VPSelectionComplete>): boolean {
|
||||
if (!isImperativeTense(vps.verb.tense)) {
|
||||
return true;
|
||||
}
|
||||
const subjectPerson = getPersonFromNP(
|
||||
getSubjectSelection(vps.blocks).selection
|
||||
);
|
||||
return isSecondPerson(subjectPerson);
|
||||
}
|
||||
|
||||
function finishIntransitive({
|
||||
|
@ -271,8 +303,9 @@ function finishIntransitive({
|
|||
},
|
||||
];
|
||||
}
|
||||
if (getPersonFromNP(nps[0].selection) !== person) {
|
||||
errors.push({ message: "subject must agree with intransitive verb" });
|
||||
const subjectPerson = getPersonFromNP(nps[0].selection);
|
||||
if (isImperativeTense(v.tense) && !isSecondPerson(subjectPerson)) {
|
||||
return [];
|
||||
}
|
||||
if (nps[0].inflected) {
|
||||
errors.push({
|
||||
|
@ -864,8 +897,21 @@ function getPeopleFromMiniPronouns(kids: T.ParsedKid[]): T.Person[] {
|
|||
function getTenseFromRootsStems(
|
||||
hasBa: boolean,
|
||||
base: "root" | "stem",
|
||||
aspect: T.Aspect
|
||||
): T.VerbTense {
|
||||
aspect: T.Aspect,
|
||||
negative: boolean,
|
||||
imperative?: true
|
||||
): T.VerbTense | T.ImperativeTense | undefined {
|
||||
if (imperative) {
|
||||
if (base === "root") {
|
||||
return undefined;
|
||||
}
|
||||
if (hasBa) {
|
||||
return undefined;
|
||||
}
|
||||
return aspect === "imperfective" || negative
|
||||
? "imperfectiveImperative"
|
||||
: "perfectiveImperative";
|
||||
}
|
||||
if (!hasBa) {
|
||||
if (base === "root") {
|
||||
return aspect === "perfective" ? "perfectivePast" : "imperfectivePast";
|
||||
|
|
|
@ -291,8 +291,8 @@ export function uncompleteVPSelection(
|
|||
: isPerfectTense(tense)
|
||||
? "perfect"
|
||||
: isImperativeTense(tense)
|
||||
? "modal"
|
||||
: "imperative";
|
||||
? "imperative"
|
||||
: "modal";
|
||||
return {
|
||||
...vps,
|
||||
verb: {
|
||||
|
|
|
@ -1257,6 +1257,7 @@ export type VBE = VB & {
|
|||
aspect: Aspect;
|
||||
base: "stem" | "root";
|
||||
verb: VerbEntry;
|
||||
imperative?: true;
|
||||
abilityAux?: boolean;
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue