more with cleaner demo

This commit is contained in:
adueck 2023-08-19 20:14:30 +04:00
parent 1da82dc4da
commit 56b92a912c
8 changed files with 282 additions and 24 deletions

View File

@ -10,14 +10,47 @@ import {
renderVP, renderVP,
} from "../components/library"; } from "../components/library";
const working = [
"limited demo vocab",
"phrases with simple verbs",
"basic verb tenses",
"noun phrases (except participles)",
"mini-pronouns for shrunken servants",
"grammar error correction",
];
const todo = [
"participles",
"compound verbs",
"adverbial phrases",
"relative clauses",
"equative verbs",
"perfect tenses",
"ability verbs",
"imperative verbs",
"passive verbs",
"quantifiers",
"demonstrative pronouns",
"mini-pronouns for possesives",
"approximate spelling",
];
const examples = [
"سړي زه ولیدم",
"تلم به",
"یو به مې ړلې",
"د غټې ماشومې زاړه پلار ولیدم",
"ستا پخواني ملګري مې ولیدل",
"ما ډوډۍ خوړله",
];
function ParserDemo({ opts }: { opts: T.TextOptions }) { function ParserDemo({ opts }: { opts: T.TextOptions }) {
const [text, setText] = useState<string>(""); const [text, setText] = useState<string>("");
const [result, setResult] = useState< const [result, setResult] = useState<
ReturnType<typeof parsePhrase>["success"] ReturnType<typeof parsePhrase>["success"]
>([]); >([]);
const [errors, setErrors] = useState<string[]>([]); const [errors, setErrors] = useState<string[]>([]);
function handleChange(e: React.ChangeEvent<HTMLInputElement>) { function handleInput(value: string) {
const value = e.target.value;
if (!value) { if (!value) {
setText(""); setText("");
setResult([]); setResult([]);
@ -31,11 +64,30 @@ function ParserDemo({ opts }: { opts: T.TextOptions }) {
} }
return ( return (
<div className="mt-3" style={{ marginBottom: "1000px" }}> <div className="mt-3" style={{ marginBottom: "1000px" }}>
<div>Type a sentence to parse</div> <div className="mb-2">Type a sentence to parse</div>
<div className="small text-muted"> <div className="small text-muted mb-2">
(NOT DONE!! limited vocab, and not working for APs, compound verbs, or <div>
grammatically transitive verbs... yet 👷) <strong>NOT DONE:</strong> <em>sort of</em> works with:{` `}
{working.map((x) => (
<span className="mr-2" key={x}>
{x}
</span>
))}
{todo.map((x) => (
<span className="mr-2" key={x}>
{x}
</span>
))}
</div>
</div> </div>
<div className="mt-2 text-right">working examples</div>
<ul dir="rtl" className="text-right">
{examples.map((ex) => (
<li key={ex} className="clickable" onClick={() => handleInput(ex)}>
{ex}
</li>
))}
</ul>
<div className="form-group mb-2"> <div className="form-group mb-2">
<input <input
dir="rtl" dir="rtl"
@ -48,7 +100,7 @@ function ParserDemo({ opts }: { opts: T.TextOptions }) {
}`} }`}
type="text" type="text"
value={text} value={text}
onChange={handleChange} onChange={(e) => handleInput(e.target.value)}
/> />
</div> </div>
{errors.length > 0 && ( {errors.length > 0 && (

View File

@ -26,7 +26,6 @@ import {
endsWith, endsWith,
trimOffPs, trimOffPs,
undoAaXuPattern, undoAaXuPattern,
prevValNotA,
lastVowelNotA, lastVowelNotA,
} from "./p-text-helpers"; } from "./p-text-helpers";
import * as T from "../../types"; import * as T from "../../types";

View File

@ -42,6 +42,9 @@ export function shouldCheckTpp(s: string): boolean {
} }
export function verbLookup(input: string): T.VerbEntry[] { export function verbLookup(input: string): T.VerbEntry[] {
// TODO:
// only look up forms if there's an ending
// or is third person thing
const s = input.slice(0, -1); const s = input.slice(0, -1);
// IMPORTANT TODO FOR EFFECIANCY! // IMPORTANT TODO FOR EFFECIANCY!
// check endings TODO: ONLY LOOKUP THE VERB POSSIBILITIES IF IT HAS A LEGITIMATE ENDING // check endings TODO: ONLY LOOKUP THE VERB POSSIBILITIES IF IT HAS A LEGITIMATE ENDING
@ -127,7 +130,10 @@ export function verbLookup(input: string): T.VerbEntry[] {
) || ) ||
[s, sAddedAa, "و" + s].includes(entry.ssp || "") || [s, sAddedAa, "و" + s].includes(entry.ssp || "") ||
(entry.separationAtP && (entry.separationAtP &&
// TODO this is super ugly, do check of short and long function
(entry.p.slice(entry.separationAtP) === s || (entry.p.slice(entry.separationAtP) === s ||
entry.p.slice(entry.separationAtP, -1) === s ||
(checkTpp && entry.p.slice(entry.separationAtP, -1) === input) ||
entry.psp?.slice(entry.separationAtP) === s || entry.psp?.slice(entry.separationAtP) === s ||
(entry.prp && (entry.prp &&
[ [

View File

@ -73,18 +73,22 @@ function phMatches(ph: T.ParsedPH | undefined, vb: T.ParsedVBE | undefined) {
if (!ph) { if (!ph) {
return true; return true;
} }
const v = vb && vb.type === "VB" && vb.info.type === "verb" && vb.info.verb; if (!vb) {
if (!v) {
return true; return true;
} }
const verbPh = getPhFromVerb(v); if (vb.info.type !== "verb") {
return false;
}
const verbPh = getPhFromVerb(vb.info.verb, vb.info.base);
return verbPh === ph.s; return verbPh === ph.s;
} }
function getPhFromVerb(v: T.VerbEntry): string { function getPhFromVerb(v: T.VerbEntry, base: "root" | "stem"): string {
// TODO!! what to do about yo / bo ??? // TODO!! what to do about yo / bo ???
if (v.entry.separationAtP) { if (v.entry.separationAtP) {
return v.entry.p.slice(0, v.entry.separationAtP); const p =
base === "root" ? v.entry.prp || v.entry.p : v.entry.ssp || v.entry.p;
return p.slice(0, v.entry.separationAtP);
} }
// TODO or آ // TODO or آ
if (v.entry.p.startsWith("ا")) { if (v.entry.p.startsWith("ا")) {

View File

@ -11,7 +11,7 @@ import {
import { verbLookup, wordQuery } from "./lookup"; import { verbLookup, wordQuery } from "./lookup";
import { parseVerb } from "./parse-verb"; import { parseVerb } from "./parse-verb";
import { tokenizer } from "./tokenizer"; import { tokenizer } from "./tokenizer";
import { removeKeys } from "./utils"; import { getPeople, removeKeys } from "./utils";
const wahul = wordQuery("وهل", "verb"); const wahul = wordQuery("وهل", "verb");
const leekul = wordQuery("لیکل", "verb"); const leekul = wordQuery("لیکل", "verb");
@ -383,6 +383,11 @@ const tests: {
}, },
], ],
}, },
// but not for kedul
{
input: "کې",
output: [],
},
], ],
}, },
{ {
@ -729,6 +734,32 @@ const tests: {
}, },
], ],
}, },
{
input: "کېناست",
output: [
{
ph: "کې",
root: {
persons: [T.Person.ThirdSingMale],
aspects: ["imperfective", "perfective"],
},
verb: kenaastul,
},
],
},
{
input: "ناست",
output: [
{
ph: undefined,
root: {
persons: [T.Person.ThirdSingMale],
aspects: ["perfective"],
},
verb: kenaastul,
},
],
},
{ {
input: "پرېږدو", input: "پرېږدو",
output: [ output: [

View File

@ -73,7 +73,7 @@ function matchVerbs(
return e.psp === base; return e.psp === base;
} }
if (e.c.includes("intrans.")) { if (e.c.includes("intrans.")) {
const miniRoot = e.p.slice(0, -3); const miniRoot = e.p !== "کېدل" && e.p.slice(0, -3);
return miniRoot + "ېږ" === base || miniRoot === base; return miniRoot + "ېږ" === base || miniRoot === base;
} else { } else {
return e.p.slice(0, -1) === base; return e.p.slice(0, -1) === base;
@ -168,7 +168,7 @@ function matchVerbs(
]; ];
} }
} else if (e.c.includes("intrans.")) { } else if (e.c.includes("intrans.")) {
const miniRoot = e.p.slice(0, -3); const miniRoot = e.p !== "کېدل" && e.p.slice(0, -3);
const miniRootEg = miniRoot + "ېږ"; const miniRootEg = miniRoot + "ېږ";
if ([miniRoot, miniRootEg].includes(base)) { if ([miniRoot, miniRootEg].includes(base)) {
return [ return [

View File

@ -3,7 +3,6 @@
import * as T from "../../../types"; import * as T from "../../../types";
import { import {
makeObjectSelectionComplete, makeObjectSelectionComplete,
makeSubjectSelection,
makeSubjectSelectionComplete, makeSubjectSelectionComplete,
} from "../phrase-building/blocks-utils"; } from "../phrase-building/blocks-utils";
import { import {
@ -20,6 +19,8 @@ const sarey = wordQuery("سړی", "noun");
const rasedul = wordQuery("رسېدل", "verb"); const rasedul = wordQuery("رسېدل", "verb");
const maashoom = wordQuery("ماشوم", "noun"); const maashoom = wordQuery("ماشوم", "noun");
const leedul = wordQuery("لیدل", "verb"); const leedul = wordQuery("لیدل", "verb");
const kenaastul = wordQuery("کېناستل", "verb");
const wurul = wordQuery("وړل", "verb");
const tests: { const tests: {
label: string; label: string;
@ -91,7 +92,7 @@ const tests: {
verb: { verb: {
type: "verb", type: "verb",
verb: tlul, verb: tlul,
transitivity: "transitive", transitivity: "intransitive",
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
@ -129,7 +130,7 @@ const tests: {
verb: { verb: {
type: "verb", type: "verb",
verb: tlul, verb: tlul,
transitivity: "transitive", transitivity: "intransitive",
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
@ -168,7 +169,7 @@ const tests: {
verb: { verb: {
type: "verb", type: "verb",
verb: rasedul, verb: rasedul,
transitivity: "transitive", transitivity: "intransitive",
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
@ -208,7 +209,7 @@ const tests: {
verb: { verb: {
type: "verb", type: "verb",
verb: rasedul, verb: rasedul,
transitivity: "transitive", transitivity: "intransitive",
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
@ -252,7 +253,7 @@ const tests: {
verb: { verb: {
type: "verb", type: "verb",
verb: tlul, verb: tlul,
transitivity: "transitive", transitivity: "intransitive",
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,
@ -268,6 +269,46 @@ const tests: {
}, },
})), })),
}, },
{
input: "کې به ناست",
output: [
{
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(T.Person.ThirdSingMale),
}),
},
{
key: 2,
block: {
type: "objectSelection",
selection: "none",
},
},
],
verb: {
type: "verb",
verb: kenaastul,
transitivity: "intransitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "habitualPerfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
},
],
},
], ],
}, },
{ {
@ -938,6 +979,129 @@ const tests: {
})) }))
), ),
}, },
{
input: "ودې وینم",
output: getPeople(2, "sing").flatMap((objectPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>((subjectPerson) => ({
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: "subjunctiveVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: true,
},
}))
),
},
{
input: "وینم به دې",
output: getPeople(2, "sing").flatMap((objectPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>((subjectPerson) => ({
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: "imperfectiveFuture",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: true,
},
}))
),
},
{
input: "یو به مې ړلې",
output: [...getPeople(2, "sing"), T.Person.ThirdPlurFemale].flatMap(
(objectPerson) =>
getPeople(1, "sing").map<T.VPSelectionComplete>(
(subjectPerson) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjectPerson),
}),
},
{
key: 2,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(objectPerson),
}),
},
],
verb: {
type: "verb",
verb: wurul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "habitualPerfectivePast",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: true,
},
})
)
),
},
], ],
}, },
]; ];

View File

@ -32,7 +32,7 @@ import { isFirstOrSecondPersPronoun } from "../phrase-building/render-vp";
// make impossible subjects like I saw me, error // make impossible subjects like I saw me, error
// کې به ناست not working! // TODO: learn how to yank / use plugin for JSON neovim
// TODO: transitivity options // TODO: transitivity options
@ -72,7 +72,9 @@ export function parseVP(
const v: T.VerbSelectionComplete = { const v: T.VerbSelectionComplete = {
type: "verb", type: "verb",
verb: verb.info.verb, verb: verb.info.verb,
transitivity: "transitive", transitivity: verb.info.verb.entry.c.includes("intrans")
? "intransitive"
: "transitive",
canChangeTransitivity: false, canChangeTransitivity: false,
canChangeStatDyn: false, canChangeStatDyn: false,
negative: false, negative: false,