APs included in the parsing of intransitive and grammatically transitive VPs

This commit is contained in:
adueck 2023-09-26 16:28:10 -04:00
parent 174e34f069
commit 3575c1da4f
2 changed files with 234 additions and 205 deletions

View File

@ -1474,177 +1474,177 @@ const tests: {
}, },
})), })),
}, },
{ // {
input: "ما خندل", // input: "ما خندل",
output: getPeople(1, "sing").map<T.VPSelectionComplete>((person) => ({ // output: getPeople(1, "sing").map<T.VPSelectionComplete>((person) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(person), // selection: makePronounSelection(person),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: { // block: {
type: "objectSelection", // type: "objectSelection",
selection: T.Person.ThirdPlurMale, // selection: T.Person.ThirdPlurMale,
}, // },
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: khandul, // verb: khandul,
transitivity: "grammatically transitive", // transitivity: "grammatically transitive",
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "imperfectivePast", // tense: "imperfectivePast",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: false, // removeKing: false,
shrinkServant: false, // shrinkServant: false,
}, // },
})), // })),
}, // },
{ // {
input: "خندل مې", // input: "خندل مې",
output: getPeople(1, "sing").map<T.VPSelectionComplete>((person) => ({ // output: getPeople(1, "sing").map<T.VPSelectionComplete>((person) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(person), // selection: makePronounSelection(person),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: { // block: {
type: "objectSelection", // type: "objectSelection",
selection: T.Person.ThirdPlurMale, // selection: T.Person.ThirdPlurMale,
}, // },
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: khandul, // verb: khandul,
transitivity: "grammatically transitive", // transitivity: "grammatically transitive",
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "imperfectivePast", // tense: "imperfectivePast",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: false, // removeKing: false,
shrinkServant: true, // shrinkServant: true,
}, // },
})), // })),
}, // },
{ // {
input: "خندل", // input: "خندل",
output: [], // output: [],
}, // },
{ // {
input: "خاندم مې", // input: "خاندم مې",
output: [], // output: [],
error: true, // error: true,
}, // },
{ // {
input: "زه وینم", // input: "زه وینم",
output: getPeople(1, "sing").map<T.VPSelectionComplete>((person) => ({ // output: getPeople(1, "sing").map<T.VPSelectionComplete>((person) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(person), // selection: makePronounSelection(person),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: { // block: {
type: "objectSelection", // type: "objectSelection",
selection: T.Person.ThirdPlurMale, // selection: T.Person.ThirdPlurMale,
}, // },
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: leedul, // verb: leedul,
transitivity: "grammatically transitive", // transitivity: "grammatically transitive",
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "presentVerb", // tense: "presentVerb",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: false, // removeKing: false,
shrinkServant: false, // shrinkServant: false,
}, // },
})), // })),
}, // },
{ // {
input: "ما ولیدل", // input: "ما ولیدل",
output: getPeople(1, "sing").flatMap<T.VPSelectionComplete>((person) => // output: getPeople(1, "sing").flatMap<T.VPSelectionComplete>((person) =>
( // (
["transitive", "grammatically transitive"] as const // ["transitive", "grammatically transitive"] as const
).map<T.VPSelectionComplete>((transitivity) => ({ // ).map<T.VPSelectionComplete>((transitivity) => ({
blocks: [ // blocks: [
{ // {
key: 1, // key: 1,
block: makeSubjectSelectionComplete({ // block: makeSubjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(person), // selection: makePronounSelection(person),
}), // }),
}, // },
{ // {
key: 2, // key: 2,
block: // block:
transitivity === "grammatically transitive" // transitivity === "grammatically transitive"
? { // ? {
type: "objectSelection", // type: "objectSelection",
selection: T.Person.ThirdPlurMale, // selection: T.Person.ThirdPlurMale,
} // }
: makeObjectSelectionComplete({ // : makeObjectSelectionComplete({
type: "NP", // type: "NP",
selection: makePronounSelection(T.Person.ThirdPlurMale), // selection: makePronounSelection(T.Person.ThirdPlurMale),
}), // }),
}, // },
], // ],
verb: { // verb: {
type: "verb", // type: "verb",
verb: leedul, // verb: leedul,
transitivity, // transitivity,
canChangeTransitivity: false, // canChangeTransitivity: false,
canChangeStatDyn: false, // canChangeStatDyn: false,
negative: false, // negative: false,
tense: "perfectivePast", // tense: "perfectivePast",
canChangeVoice: true, // canChangeVoice: true,
isCompound: false, // isCompound: false,
voice: "active", // voice: "active",
}, // },
externalComplement: undefined, // externalComplement: undefined,
form: { // form: {
removeKing: transitivity === "transitive", // removeKing: transitivity === "transitive",
shrinkServant: false, // shrinkServant: false,
}, // },
})) // }))
), // ),
}, // },
], ],
}, },
]; ];

View File

@ -47,7 +47,9 @@ export function parseVP(
return bindParseResult(blocks, (tokens, { blocks, kids }) => { return bindParseResult(blocks, (tokens, { blocks, kids }) => {
const ba = !!kids.find((k) => k === "ba"); const ba = !!kids.find((k) => k === "ba");
const miniPronouns = getMiniPronouns(kids); const miniPronouns = getMiniPronouns(kids);
const nps = blocks.filter((x): x is T.ParsedNP => x.type === "NP"); const npsAndAps = blocks.filter(
(x): x is T.ParsedNP | T.APSelection => x.type === "NP" || x.type === "AP"
);
const verbSection = blocks.findIndex(startsVerbSection); const verbSection = blocks.findIndex(startsVerbSection);
// TODO: would be nice if this could pass error messages about the // TODO: would be nice if this could pass error messages about the
// negative being out of place etc // negative being out of place etc
@ -60,7 +62,7 @@ export function parseVP(
finishPossibleVPSs({ finishPossibleVPSs({
tense, tense,
transitivities, transitivities,
nps, npsAndAps,
miniPronouns, miniPronouns,
tokens, tokens,
negative, negative,
@ -153,7 +155,7 @@ function getTenses(
function finishPossibleVPSs({ function finishPossibleVPSs({
tense, tense,
transitivities, transitivities,
nps, npsAndAps,
miniPronouns, miniPronouns,
negative, negative,
verb, verb,
@ -162,7 +164,7 @@ function finishPossibleVPSs({
}: { }: {
tense: T.VerbTense | T.PerfectTense; tense: T.VerbTense | T.PerfectTense;
transitivities: T.Transitivity[]; transitivities: T.Transitivity[];
nps: T.ParsedNP[]; npsAndAps: (T.ParsedNP | T.APSelection)[];
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
negative: boolean; negative: boolean;
@ -187,7 +189,7 @@ function finishPossibleVPSs({
if (transitivity === "intransitive") { if (transitivity === "intransitive") {
return finishIntransitive({ return finishIntransitive({
miniPronouns, miniPronouns,
nps, npsAndAps,
tokens, tokens,
v, v,
person, person,
@ -195,7 +197,7 @@ function finishPossibleVPSs({
} else if (transitivity === "transitive") { } else if (transitivity === "transitive") {
return finishTransitive({ return finishTransitive({
miniPronouns, miniPronouns,
nps, npsAndAps,
tokens, tokens,
v, v,
person, person,
@ -204,7 +206,7 @@ function finishPossibleVPSs({
} else { } else {
return finishGrammaticallyTransitive({ return finishGrammaticallyTransitive({
miniPronouns, miniPronouns,
nps, npsAndAps,
tokens, tokens,
v, v,
person, person,
@ -217,13 +219,13 @@ function finishPossibleVPSs({
function finishIntransitive({ function finishIntransitive({
miniPronouns, miniPronouns,
nps, npsAndAps,
tokens, tokens,
v, v,
person, person,
}: { }: {
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
nps: T.ParsedNP[]; npsAndAps: (T.ParsedNP | T.APSelection)[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
v: T.VerbSelectionComplete; v: T.VerbSelectionComplete;
person: T.Person; person: T.Person;
@ -234,20 +236,22 @@ function finishIntransitive({
message: "unknown mini-pronoun", message: "unknown mini-pronoun",
}); });
} }
const nps = npsAndAps.filter((x): x is T.ParsedNP => x.type === "NP");
if (nps.length > 1) { if (nps.length > 1) {
return []; return [];
} }
if (nps.length === 0) { if (nps.length === 0) {
const blocks: T.VPSBlockComplete[] = [ const blocks: T.VPSBlockComplete[] = [
...mapOutnpsAndAps([], npsAndAps),
{ {
key: 1, key: 3456,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(person), selection: makePronounSelection(person),
}), }),
}, },
{ {
key: 2, key: 2345,
block: { block: {
type: "objectSelection", type: "objectSelection",
selection: "none", selection: "none",
@ -279,18 +283,16 @@ function finishIntransitive({
}); });
} }
const blocks: T.VPSBlockComplete[] = [ const blocks: T.VPSBlockComplete[] = [
...mapOutnpsAndAps(["S"], npsAndAps),
{ {
key: 1, key: 2345,
block: makeSubjectSelectionComplete(nps[0].selection),
},
{
key: 2,
block: { block: {
type: "objectSelection", type: "objectSelection",
selection: "none", selection: "none",
}, },
}, },
]; ];
return [ return [
{ {
tokens, tokens,
@ -310,19 +312,20 @@ function finishIntransitive({
function finishTransitive({ function finishTransitive({
miniPronouns, miniPronouns,
nps, npsAndAps,
tokens, tokens,
v, v,
person, person,
isPast, isPast,
}: { }: {
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
nps: T.ParsedNP[]; npsAndAps: (T.ParsedNP | T.APSelection)[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
v: T.VerbSelectionComplete; v: T.VerbSelectionComplete;
person: T.Person; person: T.Person;
isPast: boolean; isPast: boolean;
}): T.ParseResult<T.VPSelectionComplete>[] { }): T.ParseResult<T.VPSelectionComplete>[] {
const nps = npsAndAps.filter((x): x is T.ParsedNP => x.type === "NP");
// transitive // transitive
if (nps.length > 2) { if (nps.length > 2) {
return []; return [];
@ -345,6 +348,7 @@ function finishTransitive({
).map((servantPerson) => ).map((servantPerson) =>
!isPast !isPast
? [ ? [
...mapOutnpsAndAps([], npsAndAps),
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
@ -361,6 +365,7 @@ function finishTransitive({
}, },
] ]
: [ : [
...mapOutnpsAndAps([], npsAndAps),
{ {
key: 1, key: 1,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
@ -395,6 +400,7 @@ function finishTransitive({
) )
); );
} }
// TODO: allow APs for this
if (nps.length === 1) { if (nps.length === 1) {
const np = nps[0]; const np = nps[0];
// possibilities // possibilities
@ -646,19 +652,20 @@ function finishTransitive({
function finishGrammaticallyTransitive({ function finishGrammaticallyTransitive({
miniPronouns, miniPronouns,
nps, npsAndAps,
tokens, tokens,
v, v,
person, person,
isPast, isPast,
}: { }: {
miniPronouns: T.ParsedMiniPronoun[]; miniPronouns: T.ParsedMiniPronoun[];
nps: T.ParsedNP[]; npsAndAps: (T.ParsedNP | T.APSelection)[];
tokens: Readonly<T.Token[]>; tokens: Readonly<T.Token[]>;
v: T.VerbSelectionComplete; v: T.VerbSelectionComplete;
person: T.Person; person: T.Person;
isPast: boolean; isPast: boolean;
}): T.ParseResult<T.VPSelectionComplete>[] { }): T.ParseResult<T.VPSelectionComplete>[] {
const nps = npsAndAps.filter((x): x is T.ParsedNP => x.type === "NP");
const errors: T.ParseError[] = []; const errors: T.ParseError[] = [];
if (isPast) { if (isPast) {
if (nps.length === 1) { if (nps.length === 1) {
@ -680,12 +687,9 @@ function finishGrammaticallyTransitive({
}); });
} }
const blocks: T.VPSBlockComplete[] = [ const blocks: T.VPSBlockComplete[] = [
...mapOutnpsAndAps(["S"], npsAndAps),
{ {
key: 1, key: 2345,
block: makeSubjectSelectionComplete(nps[0].selection),
},
{
key: 2,
block: { block: {
type: "objectSelection", type: "objectSelection",
selection: T.Person.ThirdPlurMale, selection: T.Person.ThirdPlurMale,
@ -726,15 +730,16 @@ function finishGrammaticallyTransitive({
} }
return getPeopleFromMiniPronouns(miniPronouns).map((person) => { return getPeopleFromMiniPronouns(miniPronouns).map((person) => {
const blocks: T.VPSBlockComplete[] = [ const blocks: T.VPSBlockComplete[] = [
...mapOutnpsAndAps([], npsAndAps),
{ {
key: 1, key: 2345,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(person), selection: makePronounSelection(person),
}), }),
}, },
{ {
key: 2, key: 3456,
block: { block: {
type: "objectSelection", type: "objectSelection",
selection: T.Person.ThirdPlurMale, selection: T.Person.ThirdPlurMale,
@ -777,12 +782,9 @@ function finishGrammaticallyTransitive({
}); });
} }
const blocks: T.VPSBlockComplete[] = [ const blocks: T.VPSBlockComplete[] = [
...mapOutnpsAndAps(["S"], npsAndAps),
{ {
key: 1, key: 2345,
block: makeSubjectSelectionComplete(nps[0].selection),
},
{
key: 2,
block: { block: {
type: "objectSelection", type: "objectSelection",
selection: T.Person.ThirdPlurMale, selection: T.Person.ThirdPlurMale,
@ -811,15 +813,16 @@ function finishGrammaticallyTransitive({
}); });
} }
const blocks: T.VPSBlockComplete[] = [ const blocks: T.VPSBlockComplete[] = [
...mapOutnpsAndAps([], npsAndAps),
{ {
key: 1, key: 1234,
block: makeSubjectSelectionComplete({ block: makeSubjectSelectionComplete({
type: "NP", type: "NP",
selection: makePronounSelection(person), selection: makePronounSelection(person),
}), }),
}, },
{ {
key: 2, key: 2345,
block: { block: {
type: "objectSelection", type: "objectSelection",
selection: T.Person.ThirdPlurMale, selection: T.Person.ThirdPlurMale,
@ -977,3 +980,29 @@ function getEquativeTense(
} }
return tense; return tense;
} }
function mapOutnpsAndAps(
npOrder: ("S" | "O")[],
blocks: (T.APSelection | T.ParsedNP)[]
): T.VPSBlockComplete[] {
const queue = [...npOrder];
return blocks.map((x, i): T.VPSBlockComplete => {
if (x.type === "NP") {
const c = queue.shift();
if (!c) {
throw new Error("invalid NP order in parsing");
}
return {
key: i,
block: (c === "S"
? makeSubjectSelectionComplete
: makeObjectSelectionComplete)(x.selection),
};
} else {
return {
key: i,
block: x,
};
}
});
}