more for vps

This commit is contained in:
adueck 2023-08-18 19:42:58 +04:00
parent 4b54289c48
commit 773ae85002
10 changed files with 846 additions and 979 deletions

View File

@ -1,554 +0,0 @@
const b = [
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come",
ec: "come,comes,coming,came,come",
f: "raatlúl",
g: "raatlul",
noOo: true,
p: "راتلل",
pprtf: "raaghúlay",
pprtp: "راغلی",
prf: "ráaghlul",
prp: "راغلل",
psf: "raadz",
psp: "راځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "ráash",
ssp: "راش",
tppf: "ráaghay",
tppp: "راغی",
ts: 1527815216,
},
},
},
person: 4,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come",
ec: "come,comes,coming,came,come",
f: "raatlúl",
g: "raatlul",
noOo: true,
p: "راتلل",
pprtf: "raaghúlay",
pprtp: "راغلی",
prf: "ráaghlul",
prp: "راغلل",
psf: "raadz",
psp: "راځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "ráash",
ssp: "راش",
tppf: "ráaghay",
tppp: "راغی",
ts: 1527815216,
},
},
},
person: 5,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come",
ec: "come,comes,coming,came,come",
f: "raatlúl",
g: "raatlul",
noOo: true,
p: "راتلل",
pprtf: "raaghúlay",
pprtp: "راغلی",
prf: "ráaghlul",
prp: "راغلل",
psf: "raadz",
psp: "راځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "ráash",
ssp: "راش",
tppf: "ráaghay",
tppp: "راغی",
ts: 1527815216,
},
},
},
person: 10,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come",
ec: "come,comes,coming,came,come",
f: "raatlúl",
g: "raatlul",
noOo: true,
p: "راتلل",
pprtf: "raaghúlay",
pprtp: "راغلی",
prf: "ráaghlul",
prp: "راغلل",
psf: "raadz",
psp: "راځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "ráash",
ssp: "راش",
tppf: "ráaghay",
tppp: "راغی",
ts: 1527815216,
},
},
},
person: 11,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to become _____",
ec: "become",
f: "kedul",
g: "kedul",
noOo: true,
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "shwul",
prp: "شول",
r: 2,
ssf: "sh",
ssp: "ش",
ts: 1581086654898,
},
},
},
person: 4,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to become _____",
ec: "become",
f: "kedul",
g: "kedul",
noOo: true,
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "shwul",
prp: "شول",
r: 2,
ssf: "sh",
ssp: "ش",
ts: 1581086654898,
},
},
},
person: 5,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to become _____",
ec: "become",
f: "kedul",
g: "kedul",
noOo: true,
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "shwul",
prp: "شول",
r: 2,
ssf: "sh",
ssp: "ش",
ts: 1581086654898,
},
},
},
person: 10,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to become _____",
ec: "become",
f: "kedul",
g: "kedul",
noOo: true,
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "shwul",
prp: "شول",
r: 2,
ssf: "sh",
ssp: "ش",
ts: 1581086654898,
},
},
},
person: 11,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
diacExcept: true,
e: "to happen, occur",
ec: "happen",
f: "kedul",
g: "kedul",
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "óoshwul",
prp: "وشول",
r: 2,
separationAtF: 2,
separationAtP: 1,
ssf: "óosh",
ssp: "وش",
ts: 1527812754,
},
},
},
person: 4,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
diacExcept: true,
e: "to happen, occur",
ec: "happen",
f: "kedul",
g: "kedul",
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "óoshwul",
prp: "وشول",
r: 2,
separationAtF: 2,
separationAtP: 1,
ssf: "óosh",
ssp: "وش",
ts: 1527812754,
},
},
},
person: 5,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
diacExcept: true,
e: "to happen, occur",
ec: "happen",
f: "kedul",
g: "kedul",
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "óoshwul",
prp: "وشول",
r: 2,
separationAtF: 2,
separationAtP: 1,
ssf: "óosh",
ssp: "وش",
ts: 1527812754,
},
},
},
person: 10,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
diacExcept: true,
e: "to happen, occur",
ec: "happen",
f: "kedul",
g: "kedul",
p: "کېدل",
pprtf: "shúway",
pprtp: "شوی",
prf: "óoshwul",
prp: "وشول",
r: 2,
separationAtF: 2,
separationAtP: 1,
ssf: "óosh",
ssp: "وش",
ts: 1527812754,
},
},
},
person: 11,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come / go over to (third person or place)",
ec: "come,comes,coming,came,come",
f: "wărtlul",
g: "wartlul",
noOo: true,
p: "ورتلل",
pprtf: "wărghúlay",
pprtp: "ورغلی",
prf: "wárghlul",
prp: "ورغلل",
psf: "wărdz",
psp: "ورځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "wársh",
ssp: "ورش",
tppf: "wărghay",
tppp: "ورغی",
ts: 1585228579997,
},
},
},
person: 4,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come / go over to (third person or place)",
ec: "come,comes,coming,came,come",
f: "wărtlul",
g: "wartlul",
noOo: true,
p: "ورتلل",
pprtf: "wărghúlay",
pprtp: "ورغلی",
prf: "wárghlul",
prp: "ورغلل",
psf: "wărdz",
psp: "ورځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "wársh",
ssp: "ورش",
tppf: "wărghay",
tppp: "ورغی",
ts: 1585228579997,
},
},
},
person: 5,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come / go over to (third person or place)",
ec: "come,comes,coming,came,come",
f: "wărtlul",
g: "wartlul",
noOo: true,
p: "ورتلل",
pprtf: "wărghúlay",
pprtp: "ورغلی",
prf: "wárghlul",
prp: "ورغلل",
psf: "wărdz",
psp: "ورځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "wársh",
ssp: "ورش",
tppf: "wărghay",
tppp: "ورغی",
ts: 1585228579997,
},
},
},
person: 10,
type: "VB",
},
],
[
null,
{
info: {
aspect: "perfective",
base: "stem",
type: "verb",
verb: {
entry: {
c: "v. intrans.",
e: "to come / go over to (third person or place)",
ec: "come,comes,coming,came,come",
f: "wărtlul",
g: "wartlul",
noOo: true,
p: "ورتلل",
pprtf: "wărghúlay",
pprtp: "ورغلی",
prf: "wárghlul",
prp: "ورغلل",
psf: "wărdz",
psp: "ورځ",
r: 4,
separationAtF: 3,
separationAtP: 2,
ssf: "wársh",
ssp: "ورش",
tppf: "wărghay",
tppp: "ورغی",
ts: 1585228579997,
},
},
},
person: 11,
type: "VB",
},
],
];

View File

@ -1,61 +0,0 @@
import * as T from "../../../types";
import { fmapParseResult } from "../fp-ps";
import { parseNP } from "./parse-np";
import { parseVerb } from "./parse-verb";
export function parseBlock(
tokens: Readonly<T.Token[]>,
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[],
verbLookup: (s: string) => T.VerbEntry[]
): T.ParseResult<
| [
{
inflected: boolean;
selection: T.NPSelection;
}
]
| [
(
| {
type: "PH";
s: string;
}
| undefined
),
Omit<T.VBE, "ps">
]
| []
>[] {
if (tokens.length === 0) {
return [
{
tokens: [],
body: [],
errors: [],
},
];
}
return [
...(fmapParseResult((x) => [x], parseNP(tokens, lookup)) as T.ParseResult<
[
{
inflected: boolean;
selection: T.NPSelection;
}
]
>[]),
...(parseVerb(tokens, verbLookup) as T.ParseResult<
[
(
| {
type: "PH";
s: string;
}
| undefined
),
Omit<T.VBE, "ps">
]
>[]),
];
}

View File

@ -1,96 +1,94 @@
import * as T from "../../../types"; import * as T from "../../../types";
import { parseBlock } from "./parse-block"; import { fmapParseResult } from "../fp-ps";
import { parseKidsSection } from "./parse-kids-section"; import { parseKidsSection } from "./parse-kids-section";
import { parseNP } from "./parse-np";
import { parsePH } from "./parse-ph";
import { parseVerb } from "./parse-verb";
import { bindParseResult, returnParseResult } from "./utils"; import { bindParseResult, returnParseResult } from "./utils";
export function parseBlocks( export function parseBlocks(
tokens: Readonly<T.Token[]>, tokens: Readonly<T.Token[]>,
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[], lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[],
verbLookup: (s: string) => T.VerbEntry[], verbLookup: (s: string) => T.VerbEntry[],
prevBlocks: ( blocks: T.ParsedBlock[],
| {
inflected: boolean;
selection: T.NPSelection;
}
| {
type: "PH";
s: string;
}
| Omit<T.VBE, "ps">
)[],
kids: T.ParsedKid[] kids: T.ParsedKid[]
): T.ParseResult<{ ): T.ParseResult<{
kids: T.ParsedKid[]; kids: T.ParsedKid[];
blocks: ( blocks: T.ParsedBlock[];
| {
inflected: boolean;
selection: T.NPSelection;
}
| {
type: "PH";
s: string;
}
| Omit<T.VBE, "ps">
)[];
}>[] { }>[] {
if (tokens.length === 0) { if (tokens.length === 0) {
// console.log("at end", { prevBlocks, kids }); return returnParseResult(tokens, { blocks, kids });
return returnParseResult(tokens, { blocks: prevBlocks, kids });
} }
const prevPh: T.ParsedPH | undefined = blocks.find(
const block = parseBlock(tokens, lookup, verbLookup); (b): b is T.ParsedPH => "type" in b && b.type === "PH"
);
const vbExists = blocks.some((b) => "type" in b && b.type === "VB");
const np = prevPh ? [] : fmapParseResult((x) => [x], parseNP(tokens, lookup));
// UHOH... This could cause double paths ... maybe don't parse the PH in the parse VB!
const ph =
vbExists || prevPh ? [] : fmapParseResult((x) => [x], parsePH(tokens));
const vb = fmapParseResult(
([ph, v]) => (ph ? [ph, v] : [v]),
parseVerb(tokens, verbLookup)
);
const kidsR = parseKidsSection(tokens, []); const kidsR = parseKidsSection(tokens, []);
const allResults = [...block, ...kidsR] as T.ParseResult< const allResults = [...np, ...ph, ...vb, ...kidsR] as T.ParseResult<
| [ T.ParsedBlock[] | { kids: T.ParsedKid[] }
{
inflected: boolean;
selection: T.NPSelection;
}
]
| [
(
| {
type: "PH";
s: string;
}
| undefined
),
Omit<T.VBE, "ps">
]
| []
| { kids: T.ParsedKid[] }
>[]; >[];
if (!allResults.length) { // TODO: is this necessary?
return [ // if (!allResults.length) {
{ // return [
tokens: [], // {
body: { blocks: prevBlocks, kids }, // tokens,
errors: [], // body: { blocks, kids },
}, // errors: [],
]; // },
} // ];
// }
return bindParseResult(allResults, (tokens, r) => { return bindParseResult(allResults, (tokens, r) => {
if ("kids" in r) { if ("kids" in r) {
return { return {
next: parseBlocks(tokens, lookup, verbLookup, prevBlocks, [ next: parseBlocks(tokens, lookup, verbLookup, blocks, [
...kids, ...kids,
...r.kids, ...r.kids,
]), ]),
errors: errors:
prevBlocks.length !== 1 blocks.length !== 1
? [{ message: "kids' section out of place" }] ? [{ message: "kids' section out of place" }]
: [], : [],
}; };
} }
// filter out the empty PH pieces if (prevPh && r.some((x) => "type" in x && x.type === "PH")) {
// for some reason ts won't let me do filter here return [];
const newBlocks = r.flatMap((x) => (x ? [x] : [])); }
return parseBlocks( const vb = r.find((x): x is T.ParsedVBE => "type" in x && x.type === "VB");
tokens, if (!phMatches(prevPh, vb)) {
lookup, return [];
verbLookup, }
[...prevBlocks, ...newBlocks], return parseBlocks(tokens, lookup, verbLookup, [...blocks, ...r], kids);
kids
);
}); });
} }
function phMatches(ph: T.ParsedPH | undefined, vb: T.ParsedVBE | undefined) {
if (!ph) {
return true;
}
const v = vb && vb.type === "VB" && vb.info.type === "verb" && vb.info.verb;
if (!v) {
return true;
}
const verbPh = getPhFromVerb(v);
return verbPh === ph.s;
}
function getPhFromVerb(v: T.VerbEntry): string {
// TODO!! what to do about yo / bo ???
if (v.entry.separationAtP) {
return v.entry.p.slice(0, v.entry.separationAtP);
}
// TODO or آ
if (v.entry.p.startsWith("ا")) {
return "وا";
}
return "و";
}

View File

@ -6,7 +6,7 @@ import { fmapParseResult } from "../fp-ps";
export function parseNP( export function parseNP(
s: Readonly<T.Token[]>, s: Readonly<T.Token[]>,
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[] lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[]
): T.ParseResult<{ inflected: boolean; selection: T.NPSelection }>[] { ): T.ParseResult<T.ParsedNP>[] {
if (s.length === 0) { if (s.length === 0) {
return []; return [];
} }
@ -34,7 +34,6 @@ export function parseNP(
}; };
} }
// @ts-ignore grrr webpack is having trouble with this
return fmapParseResult(makeNPSl, [ return fmapParseResult(makeNPSl, [
...parsePronoun(s), ...parsePronoun(s),
...parseNoun(s, lookup), ...parseNoun(s, lookup),

View File

@ -0,0 +1,51 @@
import * as T from "../../../types";
import { returnParseResult } from "./utils";
const phs = [
"و",
"وا",
"کې",
"یو",
"بو",
"څم",
"پرې",
"کښې",
"در",
"را",
"ور",
"پرا",
];
export function parsePH(
tokens: Readonly<T.Token[]>
): T.ParseResult<{ type: "PH"; s: string }>[] {
if (tokens.length === 0) {
return [];
}
const [first, ...rest] = tokens;
if (phs.includes(first.s)) {
return returnParseResult(rest, {
type: "PH",
s: first.s,
});
}
// TODO: maybe it would be better to only do this splitting off of the perfect head
// if the next thing could be a kids section
return phs
.filter((p) => first.s.startsWith(p))
.flatMap((ph) =>
returnParseResult(
[
{
...first,
s: first.s.slice(ph.length),
},
...rest,
],
{
type: "PH",
s: ph,
} as const
)
);
}

View File

@ -14,7 +14,7 @@ import { lookup, verbLookup, wordQuery } from "./lookup";
import { parseVP } from "./parse-vp"; import { parseVP } from "./parse-vp";
import { tokenizer } from "./tokenizer"; import { tokenizer } from "./tokenizer";
import { tlul } from "./irreg-verbs"; import { tlul } from "./irreg-verbs";
import { removeKeys } from "./utils"; import { getPeople, removeKeys } from "./utils";
const sarey = wordQuery("سړی", "noun"); const sarey = wordQuery("سړی", "noun");
const rasedul = wordQuery("رسېدل", "verb"); const rasedul = wordQuery("رسېدل", "verb");
@ -71,14 +71,13 @@ const tests: {
cases: [ cases: [
{ {
input: "زه ځم", input: "زه ځم",
output: [ output: getPeople(1, "sing").map((person) => ({
{
blocks: [ blocks: [
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale), selection: makePronounSelection(person),
}), }),
}, },
{ {
@ -106,15 +105,17 @@ const tests: {
removeKing: false, removeKing: false,
shrinkServant: false, shrinkServant: false,
}, },
})),
}, },
{ {
input: "زه به ځم",
output: getPeople(1, "sing").map((person) => ({
blocks: [ blocks: [
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(person),
selection: makePronounSelection(T.Person.FirstSingFemale),
}), }),
}, },
{ {
@ -132,7 +133,7 @@ const tests: {
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
tense: "presentVerb", tense: "imperfectiveFuture",
canChangeVoice: true, canChangeVoice: true,
isCompound: false, isCompound: false,
voice: "active", voice: "active",
@ -142,8 +143,7 @@ const tests: {
removeKing: false, removeKing: false,
shrinkServant: false, shrinkServant: false,
}, },
}, })),
],
}, },
{ {
input: "سړی رسېږي", input: "سړی رسېږي",
@ -232,14 +232,13 @@ const tests: {
cases: [ cases: [
{ {
input: "ځم", input: "ځم",
output: [ output: getPeople(1, "sing").map((subj) => ({
{
blocks: [ blocks: [
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale), selection: makePronounSelection(subj),
}), }),
}, },
{ {
@ -267,44 +266,7 @@ const tests: {
removeKing: true, removeKing: true,
shrinkServant: false, shrinkServant: false,
}, },
}, })),
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingFemale),
}),
},
{
key: 2,
block: {
type: "objectSelection",
selection: "none",
},
},
],
verb: {
type: "verb",
verb: tlul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
},
],
}, },
], ],
}, },
@ -354,6 +316,92 @@ const tests: {
}, },
], ],
}, },
{
input: "سړي به ماشومه ولیده",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: {
...makeNounSelection(maashoom, undefined),
gender: "fem",
},
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "habitualPerfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
},
],
},
{
input: "سړي به ماشومه لیده",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: {
...makeNounSelection(maashoom, undefined),
gender: "fem",
},
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "habitualImperfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
},
],
},
], ],
}, },
{ {
@ -442,8 +490,7 @@ const tests: {
}, },
{ {
input: "سړی ما ویني", input: "سړی ما ویني",
output: [ output: getPeople(1, "sing").map((objPerson) => ({
{
blocks: [ blocks: [
{ {
key: 1, key: 1,
@ -456,7 +503,7 @@ const tests: {
key: 2, key: 2,
block: makeObjectSelectionComplete({ block: makeObjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale), selection: makePronounSelection(objPerson),
}), }),
}, },
], ],
@ -477,49 +524,58 @@ const tests: {
removeKing: false, removeKing: false,
shrinkServant: false, shrinkServant: false,
}, },
}, })),
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingFemale),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
},
],
}, },
], ],
}, },
{ {
label: "transitive no king", label: "transitive no king",
cases: [ cases: [
{
input: "ما وینې",
output: getPeople(1, "sing").flatMap((objectPerson) =>
getPeople(2, "sing").map<T.VPSelectionComplete>((subjPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjPerson),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(objectPerson),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
}))
),
},
{
input: "زه وینې",
output: [],
error: true,
},
{ {
input: "سړي ولیدله", input: "سړي ولیدله",
output: [ output: [
@ -562,14 +618,13 @@ const tests: {
}, },
{ {
input: "سړی وینم", input: "سړی وینم",
output: [ output: getPeople(1, "sing").map((subjPerson) => ({
{
blocks: [ blocks: [
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale), selection: makePronounSelection(subjPerson),
}), }),
}, },
{ {
@ -597,49 +652,293 @@ const tests: {
removeKing: true, removeKing: true,
shrinkServant: false, shrinkServant: false,
}, },
}, })),
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingFemale),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
},
],
}, },
], ],
}, },
{ {
label: "transitive shrunken servant", label: "transitive shrunken servant",
cases: [], cases: [
{
input: "زه دې وینم",
output: getPeople(1, "sing").flatMap((subjectPerson) =>
getPeople(2, "sing").map<T.VPSelectionComplete>((objectPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjectPerson),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(objectPerson),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: true,
},
}))
),
},
{
input: "سړی مې ولید",
output: getPeople(1, "sing").map((subjPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjPerson),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "perfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: true,
},
})),
},
{
input: "سړی دې لید",
output: [
{
blocks: [
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: {
...makePronounSelection(T.Person.ThirdSingFemale),
distance: "near",
},
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "imperfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
},
...getPeople(2, "sing").map<T.VPSelectionComplete>((subj) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subj),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "imperfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: true,
},
})),
],
},
{
input: "سړی یې وویني",
output: getPeople(3, "both").map((person) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 1,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "subjunctiveVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: true,
},
})),
},
{
input: "سړی مو ویني",
output: [...getPeople(1, "pl"), ...getPeople(2, "pl")].map(
(person) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 1,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: true,
},
})
),
},
],
},
{
label: "transitive no king shrunken servant",
cases: [
{
input: "ودې لیدم",
output: getPeople(2, "sing").flatMap((subjPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>((objPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjPerson),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(objPerson),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "perfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: true,
},
}))
),
},
],
}, },
]; ];

View File

@ -15,8 +15,12 @@ import { isFirstOrSecondPersPronoun } from "../phrase-building/render-vp";
// ماشومان سړي ولیدل // ماشومان سړي ولیدل
// ماشومانو سړي ولیدل // ماشومانو سړي ولیدل
// map over transitivities, to give transitive / gramm. transitive optionns
// make impossible subjects like I saw me, error // make impossible subjects like I saw me, error
// کې به ناست not working!
// TODO: transitivity options // TODO: transitivity options
export function parseVP( export function parseVP(
@ -30,13 +34,10 @@ export function parseVP(
const blocks = parseBlocks(tokens, lookup, verbLookup, [], []); const blocks = parseBlocks(tokens, lookup, verbLookup, [], []);
return bindParseResult(blocks, (tokens, { blocks, kids }) => { return bindParseResult(blocks, (tokens, { blocks, kids }) => {
const ph = blocks.find((x) => "type" in x && x.type === "PH") as const ph = blocks.find((x) => "type" in x && x.type === "PH") as
| { | T.ParsedPH
type: "PH";
s: string;
}
| undefined; | undefined;
const verb = blocks.find((x) => "type" in x && x.type === "VB") as const verb = blocks.find((x) => "type" in x && x.type === "VB") as
| Omit<T.VBE, "ps"> | T.ParsedVBE
| undefined; | undefined;
const ba = !!kids.find((k) => k === "ba"); const ba = !!kids.find((k) => k === "ba");
if (!verb || verb.type !== "VB" || verb.info.type !== "verb") { if (!verb || verb.type !== "VB" || verb.info.type !== "verb") {
@ -47,6 +48,10 @@ export function parseVP(
if (!ph) { if (!ph) {
return []; return [];
} }
} else {
if (ph) {
return [];
}
} }
const tense = getTenseFromRootsStems(ba, verb.info.base, verb.info.aspect); const tense = getTenseFromRootsStems(ba, verb.info.base, verb.info.aspect);
const isPast = isPastTense(tense); const isPast = isPastTense(tense);
@ -70,6 +75,12 @@ export function parseVP(
); );
// TODO: check that verb and PH match // TODO: check that verb and PH match
if (verb.info.verb.entry.c.includes("intrans")) { if (verb.info.verb.entry.c.includes("intrans")) {
const errors: T.ParseError[] = [];
if (getMiniPronouns(kids).length) {
errors.push({
message: "unknown mini-pronoun",
});
}
if (nps.length > 1) { if (nps.length > 1) {
return []; return [];
} }
@ -90,7 +101,9 @@ export function parseVP(
}, },
}, },
]; ];
return returnParseResult(tokens, { return returnParseResult(
tokens,
{
blocks, blocks,
verb: v, verb: v,
externalComplement: undefined, externalComplement: undefined,
@ -98,9 +111,10 @@ export function parseVP(
removeKing: true, removeKing: true,
shrinkServant: false, shrinkServant: false,
}, },
} as T.VPSelectionComplete); } as T.VPSelectionComplete,
errors
);
} }
const errors: T.ParseError[] = [];
if (getPersonFromNP(nps[0].selection) !== verb.person) { if (getPersonFromNP(nps[0].selection) !== verb.person) {
errors.push({ message: "subject must agree with intransitive verb" }); errors.push({ message: "subject must agree with intransitive verb" });
} }
@ -141,7 +155,71 @@ export function parseVP(
return []; return [];
} }
if (nps.length === 0) { if (nps.length === 0) {
return []; // present:
// - no king (subject)
// - servant (object) is shrunken
// past:
// - no king (object)
// - servant (subject) is shrunken
const errors: T.ParseError[] = [];
const miniPronouns = getMiniPronouns(kids);
if (miniPronouns.length > 1) {
errors.push({
message: "unknown mini-pronoun in kid's section",
});
}
const blockOpts: T.VPSBlockComplete[][] = getPeopleFromMiniPronouns(
miniPronouns
).map((person) =>
!isPast
? [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(verb.person),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
]
: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(verb.person),
}),
},
]
);
return blockOpts.flatMap((blocks) =>
returnParseResult(
tokens,
{
blocks,
verb: v,
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: true,
},
} as T.VPSelectionComplete,
errors
)
);
} }
if (nps.length === 1) { if (nps.length === 1) {
const np = nps[0]; const np = nps[0];
@ -172,13 +250,18 @@ export function parseVP(
} }
: np.selection; : np.selection;
const servants: T.NPSelection[] = form.shrinkServant const servants: T.NPSelection[] = form.shrinkServant
? getPeopleFromKids(kids).map((person) => ({ ? getPeopleFromMiniPronouns(kids).map((person) => ({
type: "NP", type: "NP",
selection: makePronounSelection(person), selection: makePronounSelection(person),
})) }))
: [np.selection]; : [np.selection];
// check for vp structure errors // check for vp structure errors
if (form.removeKing) { if (form.removeKing) {
if (getMiniPronouns(kids).length) {
errors.push({
message: "unknown mini-pronoun in kid's section",
});
}
if (!isPast) { if (!isPast) {
if (isFirstOrSecondPersPronoun(np.selection)) if (isFirstOrSecondPersPronoun(np.selection))
if (!np.inflected) { if (!np.inflected) {
@ -358,7 +441,13 @@ export function parseVP(
}); });
} }
function getPeopleFromKids(kids: T.ParsedKid[]): T.Person[] { function getMiniPronouns(kids: T.ParsedKid[]): T.ParsedMiniPronoun[] {
return kids.filter((k): k is T.ParsedMiniPronoun =>
["me", "de", "ye", "mU"].includes(k)
);
}
function getPeopleFromMiniPronouns(kids: T.ParsedKid[]): T.Person[] {
const p: T.Person[] = []; const p: T.Person[] = [];
for (let k of kids) { for (let k of kids) {
if (k === "me") { if (k === "me") {

View File

@ -0,0 +1,19 @@
import { getPeople } from "./utils";
import * as T from "../../../types";
test("getPeople", () => {
expect(getPeople(1, "sing")).toEqual([
T.Person.FirstSingMale,
T.Person.FirstSingFemale,
]);
expect(getPeople(2, "pl")).toEqual([
T.Person.SecondPlurMale,
T.Person.SecondPlurFemale,
]);
expect(getPeople(3, "both")).toEqual([
T.Person.ThirdSingMale,
T.Person.ThirdSingFemale,
T.Person.ThirdPlurMale,
T.Person.ThirdPlurFemale,
]);
});

View File

@ -108,3 +108,16 @@ export function removeKeys(a: any): any {
JSON.stringify(a, (k, v) => (k === "i" || k === "key" ? undefined : v)) JSON.stringify(a, (k, v) => (k === "i" || k === "key" ? undefined : v))
); );
} }
export function getPeople(
person: 1 | 2 | 3,
number: "sing" | "pl" | "both"
): T.Person[] {
const people: T.Person[] =
person === 1 ? [0, 1, 6, 7] : person === 2 ? [2, 3, 8, 9] : [4, 5, 10, 11];
return number === "sing"
? people.filter((p) => p < 6)
: number === "pl"
? people.filter((p) => p > 5)
: people;
}

View File

@ -1192,12 +1192,26 @@ export type Block = {
| VHead; | VHead;
}; };
export type ParsedBlock = ParsedNP | ParsedPH | ParsedVBE;
export type ParsedNP = {
inflected: boolean;
selection: NPSelection;
};
export type ParsedPH = {
type: "PH";
s: string;
};
export type ParsedVBE = Omit<VBE, "ps">;
export type Kid = { export type Kid = {
key: number; key: number;
kid: { type: "ba" } | MiniPronoun; kid: { type: "ba" } | MiniPronoun;
}; };
export type ParsedKid = "ba" | "me" | "de" | "ye" | "mU"; export type ParsedMiniPronoun = "me" | "de" | "ye" | "mU";
export type ParsedKid = "ba" | ParsedMiniPronoun;
export type MiniPronoun = { export type MiniPronoun = {
type: "mini-pronoun"; type: "mini-pronoun";