Compare commits
No commits in common. "b5e33b1db999f35eafa5b8c7fb35c1e305618260" and "5f356fdb63e80706ffb58995142bd89c1c9afbee" have entirely different histories.
b5e33b1db9
...
5f356fdb63
|
@ -11,7 +11,7 @@ const working = [
|
|||
"phrases with simple verbs",
|
||||
"basic verb tenses",
|
||||
"noun phrases",
|
||||
"mini-pronouns",
|
||||
"mini-pronouns for shrunken servants",
|
||||
"grammar error correction",
|
||||
"negatives",
|
||||
"imperative verbs",
|
||||
|
@ -21,12 +21,14 @@ const working = [
|
|||
const todo = [
|
||||
"compound verbs",
|
||||
"adjectival participles",
|
||||
"adverbial phrases",
|
||||
"relative clauses",
|
||||
"equative verbs",
|
||||
"ability verbs",
|
||||
"passive verbs",
|
||||
"quantifiers",
|
||||
"demonstrative pronouns",
|
||||
"mini-pronouns for possesives",
|
||||
"approximate spelling",
|
||||
];
|
||||
|
||||
|
@ -36,7 +38,7 @@ const examples = [
|
|||
"یو به مې ړلې",
|
||||
"د غټې ماشومې زاړه پلار ولیدم",
|
||||
"ستا پخواني ملګري مې ولیدل",
|
||||
"پرون مې دې ملګرې ولیده",
|
||||
"پرون مې ولیدې",
|
||||
"ما ډوډۍ خوړله",
|
||||
"وامې نه خیست",
|
||||
"وبه مې وینې",
|
||||
|
|
|
@ -13,7 +13,7 @@ import { lookup, wordQuery } from "./lookup";
|
|||
import { parseVP } from "./parse-vp";
|
||||
import { tokenizer } from "./tokenizer";
|
||||
import { tlul } from "./irreg-verbs";
|
||||
import { addShrunkenPossesor, getPeople, removeKeys } from "./utils";
|
||||
import { getPeople, removeKeys } from "./utils";
|
||||
|
||||
const sarey = wordQuery("سړی", "noun");
|
||||
const rasedul = wordQuery("رسېدل", "verb");
|
||||
|
@ -259,11 +259,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "ماشوم ځې",
|
||||
output: [],
|
||||
error: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -895,9 +890,8 @@ const tests: {
|
|||
],
|
||||
},
|
||||
{
|
||||
input: "سړی یې ووهي",
|
||||
output: [
|
||||
...getPeople(3, "both").map<T.VPSelectionComplete>((person) => ({
|
||||
input: "سړی یې وویني",
|
||||
output: getPeople(3, "both").map((person) => ({
|
||||
blocks: [
|
||||
{
|
||||
key: 1,
|
||||
|
@ -916,7 +910,7 @@ const tests: {
|
|||
],
|
||||
verb: {
|
||||
type: "verb",
|
||||
verb: wahul,
|
||||
verb: leedul,
|
||||
transitivity: "transitive",
|
||||
canChangeTransitivity: false,
|
||||
canChangeStatDyn: false,
|
||||
|
@ -932,58 +926,11 @@ const tests: {
|
|||
shrinkServant: true,
|
||||
},
|
||||
})),
|
||||
...getPeople(3, "both").flatMap<T.VPSelectionComplete>((person) =>
|
||||
getPeople(3, "both").map<T.VPSelectionComplete>((person2) => ({
|
||||
blocks: [
|
||||
{
|
||||
key: 1,
|
||||
block: makeSubjectSelectionComplete({
|
||||
type: "NP",
|
||||
selection: makePronounSelection(person),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
block: makeObjectSelectionComplete(
|
||||
addShrunkenPossesor(
|
||||
{
|
||||
type: "NP",
|
||||
selection: makeNounSelection(sarey, undefined),
|
||||
},
|
||||
person2
|
||||
)
|
||||
),
|
||||
},
|
||||
],
|
||||
verb: {
|
||||
type: "verb",
|
||||
verb: wahul,
|
||||
transitivity: "transitive",
|
||||
canChangeTransitivity: false,
|
||||
canChangeStatDyn: false,
|
||||
negative: false,
|
||||
tense: "subjunctiveVerb",
|
||||
canChangeVoice: true,
|
||||
isCompound: false,
|
||||
voice: "active",
|
||||
},
|
||||
externalComplement: undefined,
|
||||
form: {
|
||||
removeKing: true,
|
||||
shrinkServant: false,
|
||||
},
|
||||
}))
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "سړی مو ویني",
|
||||
output: [
|
||||
// the man sees you/us
|
||||
...[
|
||||
...getPeople(1, "pl"),
|
||||
...getPeople(2, "pl"),
|
||||
].map<T.VPSelectionComplete>((person) => ({
|
||||
output: [...getPeople(1, "pl"), ...getPeople(2, "pl")].map(
|
||||
(person) => ({
|
||||
blocks: [
|
||||
{
|
||||
key: 1,
|
||||
|
@ -1017,98 +964,13 @@ const tests: {
|
|||
removeKing: false,
|
||||
shrinkServant: true,
|
||||
},
|
||||
})),
|
||||
// your/our man sees
|
||||
...[
|
||||
...getPeople(1, "pl"),
|
||||
...getPeople(2, "pl"),
|
||||
].map<T.VPSelectionComplete>((person) => ({
|
||||
blocks: [
|
||||
{
|
||||
key: 1,
|
||||
block: makeSubjectSelectionComplete(
|
||||
addShrunkenPossesor(
|
||||
{
|
||||
type: "NP",
|
||||
selection: makeNounSelection(sarey, undefined),
|
||||
},
|
||||
person
|
||||
)
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
block: {
|
||||
type: "objectSelection",
|
||||
selection: T.Person.ThirdPlurMale,
|
||||
},
|
||||
},
|
||||
],
|
||||
verb: {
|
||||
type: "verb",
|
||||
verb: leedul,
|
||||
transitivity: "grammatically transitive",
|
||||
canChangeTransitivity: false,
|
||||
canChangeStatDyn: false,
|
||||
negative: false,
|
||||
tense: "presentVerb",
|
||||
canChangeVoice: true,
|
||||
isCompound: false,
|
||||
voice: "active",
|
||||
},
|
||||
externalComplement: undefined,
|
||||
form: {
|
||||
removeKing: false,
|
||||
shrinkServant: false,
|
||||
},
|
||||
})),
|
||||
// they/he sees your/our man
|
||||
...[
|
||||
...getPeople(1, "pl"),
|
||||
...getPeople(2, "pl"),
|
||||
].flatMap<T.VPSelectionComplete>((possPers) =>
|
||||
getPeople(3, "both").map<T.VPSelectionComplete>((subjPers) => ({
|
||||
blocks: [
|
||||
{
|
||||
key: 1,
|
||||
block: makeSubjectSelectionComplete({
|
||||
type: "NP",
|
||||
selection: makePronounSelection(subjPers),
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
block: makeObjectSelectionComplete(
|
||||
addShrunkenPossesor(
|
||||
{
|
||||
type: "NP",
|
||||
selection: makeNounSelection(sarey, undefined),
|
||||
},
|
||||
possPers
|
||||
)
|
||||
),
|
||||
},
|
||||
],
|
||||
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,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import * as T from "../../../types";
|
||||
import {
|
||||
addShrunkenPossesor,
|
||||
bindParseResult,
|
||||
canTakeShrunkenPossesor,
|
||||
isNeg,
|
||||
isNonOoPh,
|
||||
isPH,
|
||||
|
@ -30,8 +28,6 @@ import { equals, zip } from "rambda";
|
|||
import { isImperativeTense } from "../type-predicates";
|
||||
// to hide equatives type-doubling issue
|
||||
|
||||
// TODO: problem with 3rd pers sing verb endings اواز مې دې واورېده
|
||||
|
||||
// TODO: word query for kawul/kedul/stat/dyn
|
||||
|
||||
// TODO: test all types with pronouns
|
||||
|
@ -47,14 +43,11 @@ export function parseVP(
|
|||
return [];
|
||||
}
|
||||
const blocks = parseBlocks(tokens, lookup, [], []);
|
||||
return bindParseResult(
|
||||
createPossesivePossibilities(blocks),
|
||||
(tokens, { blocks, kids }) => {
|
||||
return bindParseResult(blocks, (tokens, { blocks, kids }) => {
|
||||
const ba = kids.some((k) => k === "ba");
|
||||
const miniPronouns = getMiniPronouns(kids);
|
||||
const npsAndAps = blocks.filter(
|
||||
(x): x is T.ParsedNP | T.APSelection =>
|
||||
x.type === "NP" || x.type === "AP"
|
||||
(x): x is T.ParsedNP | T.APSelection => x.type === "NP" || x.type === "AP"
|
||||
);
|
||||
const verbSection = blocks.findIndex(startsVerbSection);
|
||||
// TODO: would be nice if this could pass error messages about the
|
||||
|
@ -64,8 +57,7 @@ export function parseVP(
|
|||
}
|
||||
const tenses = getTenses(blocks, ba);
|
||||
// TODO get errors from the get tenses (perfect verbs not agreeing)
|
||||
return tenses.flatMap(
|
||||
({ tense, person, transitivities, negative, verb }) =>
|
||||
return tenses.flatMap(({ tense, person, transitivities, negative, verb }) =>
|
||||
finishPossibleVPSs({
|
||||
tense,
|
||||
transitivities,
|
||||
|
@ -77,8 +69,7 @@ export function parseVP(
|
|||
person,
|
||||
})
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getTenses(
|
||||
|
@ -320,11 +311,6 @@ function finishIntransitive({
|
|||
message: "subject of intransitive verb must not be inflected",
|
||||
});
|
||||
}
|
||||
if (subjectPerson !== person) {
|
||||
errors.push({
|
||||
message: "subject and verb must agree for intransitive verb",
|
||||
});
|
||||
}
|
||||
const blocks: T.VPSBlockComplete[] = [
|
||||
...mapOutnpsAndAps(["S"], npsAndAps),
|
||||
{
|
||||
|
@ -501,9 +487,6 @@ function finishTransitive({
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (miniPronouns.length > 1) {
|
||||
errors.push({ message: "unknown mini-pronoun" });
|
||||
}
|
||||
if (np.inflected) {
|
||||
errors.push({
|
||||
message: !isPast
|
||||
|
@ -570,9 +553,6 @@ function finishTransitive({
|
|||
}));
|
||||
});
|
||||
} else {
|
||||
const miniPronErrors: T.ParseError[] = miniPronouns.length
|
||||
? [{ message: "unknown mini-pronoun" }]
|
||||
: [];
|
||||
if (isPast) {
|
||||
return (
|
||||
[
|
||||
|
@ -618,7 +598,7 @@ function finishTransitive({
|
|||
shrinkServant: false,
|
||||
},
|
||||
} as T.VPSelectionComplete,
|
||||
[...miniPronErrors, ...errors]
|
||||
errors
|
||||
);
|
||||
});
|
||||
} else {
|
||||
|
@ -677,7 +657,7 @@ function finishTransitive({
|
|||
shrinkServant: false,
|
||||
},
|
||||
} as T.VPSelectionComplete,
|
||||
[...miniPronErrors, ...errors]
|
||||
errors
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -1053,143 +1033,3 @@ function mapOutnpsAndAps(
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of blocks and kids, produces all possible arrangements
|
||||
* with the mini-pronouns being used as possesives, or not
|
||||
*
|
||||
* Case 1: no mini pronouns
|
||||
* 1. return as is
|
||||
*
|
||||
* Case 2: one mini pronoun
|
||||
* 1. don't use any as possesive
|
||||
* 2. use the mini pronoun as a possesive (in all possible places)
|
||||
*
|
||||
* Case 3: two mini pronouns
|
||||
* 1. don't use any as possesive
|
||||
* 2. use first as possesive
|
||||
* 3. use second as possesive
|
||||
* 4. use both as possesives
|
||||
*
|
||||
* @param blocks
|
||||
* @returns
|
||||
*/
|
||||
function createPossesivePossibilities(
|
||||
blocks: T.ParseResult<{
|
||||
kids: T.ParsedKid[];
|
||||
blocks: T.ParsedBlock[];
|
||||
}>[]
|
||||
): T.ParseResult<{
|
||||
kids: T.ParsedKid[];
|
||||
blocks: T.ParsedBlock[];
|
||||
}>[] {
|
||||
function pullOutMiniPronoun(
|
||||
body: {
|
||||
kids: T.ParsedKid[];
|
||||
blocks: T.ParsedBlock[];
|
||||
},
|
||||
pos: 0 | 1
|
||||
): {
|
||||
adjusted: {
|
||||
kids: T.ParsedKid[];
|
||||
blocks: T.ParsedBlock[];
|
||||
};
|
||||
miniPronoun: T.ParsedMiniPronoun;
|
||||
} {
|
||||
const miniPronoun = getMiniPronouns(body.kids)[pos];
|
||||
if (!miniPronoun) {
|
||||
throw new Error("tried to pull out non-existent mini-pronoun");
|
||||
}
|
||||
return {
|
||||
miniPronoun,
|
||||
adjusted: {
|
||||
kids: body.kids.filter((x) => x !== miniPronoun),
|
||||
blocks: body.blocks,
|
||||
},
|
||||
};
|
||||
}
|
||||
function spreadOutPoss(
|
||||
body: {
|
||||
kids: T.ParsedKid[];
|
||||
blocks: T.ParsedBlock[];
|
||||
},
|
||||
pos: 0 | 1
|
||||
): {
|
||||
kids: T.ParsedKid[];
|
||||
blocks: T.ParsedBlock[];
|
||||
}[] {
|
||||
const { miniPronoun, adjusted } = pullOutMiniPronoun(body, pos);
|
||||
const people = getPeopleFromMiniPronouns([miniPronoun]);
|
||||
// TODO: turn into reduce?
|
||||
// TODO: allow possesives for sandwiches
|
||||
return adjusted.blocks
|
||||
.flatMap((x, i) => {
|
||||
if (
|
||||
(x.type === "NP" && canTakeShrunkenPossesor(x.selection)) ||
|
||||
(x.type === "AP" && canTakeShrunkenPossesor(x))
|
||||
) {
|
||||
return addPossesiveAtIndex(people, adjusted.blocks, i);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
.map((xb) => ({
|
||||
kids: adjusted.kids,
|
||||
blocks: xb,
|
||||
}));
|
||||
}
|
||||
function addPossesiveAtIndex(
|
||||
people: T.Person[],
|
||||
blocks: T.ParsedBlock[],
|
||||
i: number
|
||||
): T.ParsedBlock[][] {
|
||||
return people.map((person) => {
|
||||
return blocks.map((x, j) => {
|
||||
if (i !== j) return x;
|
||||
// TODO: this is redundant ?
|
||||
if (x.type === "NP" && canTakeShrunkenPossesor(x.selection)) {
|
||||
return {
|
||||
...x,
|
||||
selection: addShrunkenPossesor(x.selection, person),
|
||||
};
|
||||
} else if (x.type === "AP" && canTakeShrunkenPossesor(x)) {
|
||||
return addShrunkenPossesor(x, person);
|
||||
} else {
|
||||
throw new Error(
|
||||
"improper index for adding possesor - addPossesiveAtIndex"
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return blocks.flatMap((b) => {
|
||||
const miniPronouns = getMiniPronouns(b.body.kids);
|
||||
if (miniPronouns.length === 0) {
|
||||
return b;
|
||||
} else if (miniPronouns.length === 1) {
|
||||
const withFirstMiniAsPossesive = spreadOutPoss(b.body, 0);
|
||||
return [b.body, ...withFirstMiniAsPossesive].map((x) => ({
|
||||
tokens: b.tokens,
|
||||
body: x,
|
||||
errors: b.errors,
|
||||
}));
|
||||
} else {
|
||||
const withFirstMiniAsPossesive = spreadOutPoss(b.body, 0);
|
||||
const withSecondMiniAsPossesive = spreadOutPoss(b.body, 1);
|
||||
return [
|
||||
// using none of the mini-pronouns as possesives
|
||||
b.body,
|
||||
// using the first mini-pronoun as a possesive
|
||||
...withFirstMiniAsPossesive,
|
||||
// using the second mini-pronoun as a prossesive
|
||||
...withSecondMiniAsPossesive,
|
||||
// using both mini pronouns as possesives
|
||||
...withFirstMiniAsPossesive.flatMap((x) => spreadOutPoss(x, 0)),
|
||||
].map((x) => ({
|
||||
tokens: b.tokens,
|
||||
body: x,
|
||||
errors: b.errors,
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -174,61 +174,3 @@ export function startsVerbSection(b: T.ParsedBlock): boolean {
|
|||
b.type === "negative"
|
||||
);
|
||||
}
|
||||
|
||||
export function canTakeShrunkenPossesor(
|
||||
block: T.NPSelection | T.APSelection
|
||||
): boolean {
|
||||
if (block.type === "NP") {
|
||||
return block.selection.type !== "pronoun" && !block.selection.possesor;
|
||||
}
|
||||
if (block.selection.type === "sandwich") {
|
||||
return canTakeShrunkenPossesor(block.selection.inside);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function addShrunkenPossesor(
|
||||
b: T.NPSelection,
|
||||
person: T.Person
|
||||
): T.NPSelection;
|
||||
export function addShrunkenPossesor(
|
||||
b: T.APSelection,
|
||||
person: T.Person
|
||||
): T.APSelection;
|
||||
export function addShrunkenPossesor(
|
||||
b: T.NPSelection | T.APSelection,
|
||||
person: T.Person
|
||||
): T.NPSelection | T.APSelection {
|
||||
if (b.selection.type === "adverb" || b.selection.type === "pronoun") {
|
||||
throw new Error("cannot add shrunken possesor");
|
||||
}
|
||||
if (b.type === "AP") {
|
||||
return {
|
||||
...b,
|
||||
selection: {
|
||||
...b.selection,
|
||||
inside: addShrunkenPossesor(b.selection.inside, person),
|
||||
},
|
||||
};
|
||||
}
|
||||
if (b.selection.possesor) {
|
||||
throw new Error("cannot add another possesor");
|
||||
}
|
||||
return {
|
||||
...b,
|
||||
selection: {
|
||||
...b.selection,
|
||||
possesor: {
|
||||
shrunken: true,
|
||||
np: {
|
||||
type: "NP",
|
||||
selection: {
|
||||
type: "pronoun",
|
||||
distance: "far",
|
||||
person,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -252,7 +252,7 @@ function pronounPossEng(p: T.Person): string {
|
|||
if (p === T.Person.ThirdSingFemale) {
|
||||
return "her/its";
|
||||
}
|
||||
return `their (${gend(p)})`;
|
||||
return `their ${gend(p)}`;
|
||||
}
|
||||
|
||||
export function getEnglishFromRendered(
|
||||
|
|
Loading…
Reference in New Issue