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 { parseBlock } from "./parse-block";
import { fmapParseResult } from "../fp-ps";
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";
export function parseBlocks(
tokens: Readonly<T.Token[]>,
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[],
verbLookup: (s: string) => T.VerbEntry[],
prevBlocks: (
| {
inflected: boolean;
selection: T.NPSelection;
}
| {
type: "PH";
s: string;
}
| Omit<T.VBE, "ps">
)[],
blocks: T.ParsedBlock[],
kids: T.ParsedKid[]
): T.ParseResult<{
kids: T.ParsedKid[];
blocks: (
| {
inflected: boolean;
selection: T.NPSelection;
}
| {
type: "PH";
s: string;
}
| Omit<T.VBE, "ps">
)[];
blocks: T.ParsedBlock[];
}>[] {
if (tokens.length === 0) {
// console.log("at end", { prevBlocks, kids });
return returnParseResult(tokens, { blocks: prevBlocks, kids });
return returnParseResult(tokens, { blocks, kids });
}
const block = parseBlock(tokens, lookup, verbLookup);
const prevPh: T.ParsedPH | undefined = blocks.find(
(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 allResults = [...block, ...kidsR] as T.ParseResult<
| [
{
inflected: boolean;
selection: T.NPSelection;
}
]
| [
(
| {
type: "PH";
s: string;
}
| undefined
),
Omit<T.VBE, "ps">
]
| []
| { kids: T.ParsedKid[] }
const allResults = [...np, ...ph, ...vb, ...kidsR] as T.ParseResult<
T.ParsedBlock[] | { kids: T.ParsedKid[] }
>[];
if (!allResults.length) {
return [
{
tokens: [],
body: { blocks: prevBlocks, kids },
errors: [],
},
];
}
// TODO: is this necessary?
// if (!allResults.length) {
// return [
// {
// tokens,
// body: { blocks, kids },
// errors: [],
// },
// ];
// }
return bindParseResult(allResults, (tokens, r) => {
if ("kids" in r) {
return {
next: parseBlocks(tokens, lookup, verbLookup, prevBlocks, [
next: parseBlocks(tokens, lookup, verbLookup, blocks, [
...kids,
...r.kids,
]),
errors:
prevBlocks.length !== 1
blocks.length !== 1
? [{ message: "kids' section out of place" }]
: [],
};
}
// filter out the empty PH pieces
// for some reason ts won't let me do filter here
const newBlocks = r.flatMap((x) => (x ? [x] : []));
return parseBlocks(
tokens,
lookup,
verbLookup,
[...prevBlocks, ...newBlocks],
kids
);
if (prevPh && r.some((x) => "type" in x && x.type === "PH")) {
return [];
}
const vb = r.find((x): x is T.ParsedVBE => "type" in x && x.type === "VB");
if (!phMatches(prevPh, vb)) {
return [];
}
return parseBlocks(tokens, lookup, verbLookup, [...blocks, ...r], 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(
s: Readonly<T.Token[]>,
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[]
): T.ParseResult<{ inflected: boolean; selection: T.NPSelection }>[] {
): T.ParseResult<T.ParsedNP>[] {
if (s.length === 0) {
return [];
}
@ -34,7 +34,6 @@ export function parseNP(
};
}
// @ts-ignore grrr webpack is having trouble with this
return fmapParseResult(makeNPSl, [
...parsePronoun(s),
...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 { tokenizer } from "./tokenizer";
import { tlul } from "./irreg-verbs";
import { removeKeys } from "./utils";
import { getPeople, removeKeys } from "./utils";
const sarey = wordQuery("سړی", "noun");
const rasedul = wordQuery("رسېدل", "verb");
@ -71,79 +71,79 @@ const tests: {
cases: [
{
input: "زه ځم",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale),
}),
},
{
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",
output: getPeople(1, "sing").map((person) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
{
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",
},
{
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: false,
shrinkServant: false,
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
],
})),
},
{
input: "زه به ځم",
output: getPeople(1, "sing").map((person) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
{
key: 2,
block: {
type: "objectSelection",
selection: "none",
},
},
],
verb: {
type: "verb",
verb: tlul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "imperfectiveFuture",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
})),
},
{
input: "سړی رسېږي",
@ -232,79 +232,41 @@ const tests: {
cases: [
{
input: "ځم",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale),
}),
},
{
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",
output: getPeople(1, "sing").map((subj) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subj),
}),
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
{
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",
},
{
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,
},
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,84 +490,92 @@ const tests: {
},
{
input: "سړی ما ویني",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
output: getPeople(1, "sing").map((objPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makeNounSelection(sarey, undefined),
}),
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(objPerson),
}),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
{
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,
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
],
})),
},
],
},
{
label: "transitive no king",
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: "سړي ولیدله",
output: [
@ -562,84 +618,327 @@ const tests: {
},
{
input: "سړی وینم",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.FirstSingMale),
}),
},
{
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",
output: getPeople(1, "sing").map((subjPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjPerson),
}),
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
{
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",
},
{
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,
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
],
})),
},
],
},
{
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
// کې به ناست not working!
// TODO: transitivity options
export function parseVP(
@ -30,13 +34,10 @@ export function parseVP(
const blocks = parseBlocks(tokens, lookup, verbLookup, [], []);
return bindParseResult(blocks, (tokens, { blocks, kids }) => {
const ph = blocks.find((x) => "type" in x && x.type === "PH") as
| {
type: "PH";
s: string;
}
| T.ParsedPH
| undefined;
const verb = blocks.find((x) => "type" in x && x.type === "VB") as
| Omit<T.VBE, "ps">
| T.ParsedVBE
| undefined;
const ba = !!kids.find((k) => k === "ba");
if (!verb || verb.type !== "VB" || verb.info.type !== "verb") {
@ -47,6 +48,10 @@ export function parseVP(
if (!ph) {
return [];
}
} else {
if (ph) {
return [];
}
}
const tense = getTenseFromRootsStems(ba, verb.info.base, verb.info.aspect);
const isPast = isPastTense(tense);
@ -70,6 +75,12 @@ export function parseVP(
);
// TODO: check that verb and PH match
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) {
return [];
}
@ -90,17 +101,20 @@ export function parseVP(
},
},
];
return returnParseResult(tokens, {
blocks,
verb: v,
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
} as T.VPSelectionComplete);
return returnParseResult(
tokens,
{
blocks,
verb: v,
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
} as T.VPSelectionComplete,
errors
);
}
const errors: T.ParseError[] = [];
if (getPersonFromNP(nps[0].selection) !== verb.person) {
errors.push({ message: "subject must agree with intransitive verb" });
}
@ -141,7 +155,71 @@ export function parseVP(
return [];
}
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) {
const np = nps[0];
@ -172,13 +250,18 @@ export function parseVP(
}
: np.selection;
const servants: T.NPSelection[] = form.shrinkServant
? getPeopleFromKids(kids).map((person) => ({
? getPeopleFromMiniPronouns(kids).map((person) => ({
type: "NP",
selection: makePronounSelection(person),
}))
: [np.selection];
// check for vp structure errors
if (form.removeKing) {
if (getMiniPronouns(kids).length) {
errors.push({
message: "unknown mini-pronoun in kid's section",
});
}
if (!isPast) {
if (isFirstOrSecondPersPronoun(np.selection))
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[] = [];
for (let k of kids) {
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))
);
}
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;
};
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 = {
key: number;
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 = {
type: "mini-pronoun";