From 035e59ae19d9c47f749fcfe9e97969a02ec5a9b1 Mon Sep 17 00:00:00 2001 From: adueck Date: Tue, 29 Aug 2023 17:20:52 +0400 Subject: [PATCH] fix yoR issue --- src/demo-components/ParserDemo.tsx | 34 +++++----- src/lib/src/accent-helpers.ts | 6 ++ src/lib/src/parsing/compare.ts | 1 + src/lib/src/parsing/lookup.tsx | 32 +++++++++- src/lib/src/parsing/parse-adjective.ts | 5 +- src/lib/src/parsing/parse-blocks.ts | 27 ++------ src/lib/src/parsing/parse-noun.test.ts | 8 +-- src/lib/src/parsing/parse-noun.ts | 10 +-- src/lib/src/parsing/parse-np.ts | 8 +-- src/lib/src/parsing/parse-participle.test.ts | 6 +- src/lib/src/parsing/parse-participle.ts | 14 ++--- src/lib/src/parsing/parse-ph.ts | 1 + src/lib/src/parsing/parse-phrase.ts | 8 +-- src/lib/src/parsing/parse-possesor.test.ts | 6 +- src/lib/src/parsing/parse-possesor.ts | 15 ++--- src/lib/src/parsing/parse-verb.test.ts | 65 +++++++++++++++++++- src/lib/src/parsing/parse-verb.ts | 44 ++++++++----- src/lib/src/parsing/parse-vp.test.ts | 4 +- src/lib/src/parsing/parse-vp.ts | 14 +---- src/lib/src/phrase-building/render-np.ts | 2 +- src/types.ts | 6 +- 21 files changed, 200 insertions(+), 116 deletions(-) diff --git a/src/demo-components/ParserDemo.tsx b/src/demo-components/ParserDemo.tsx index 19805a5..5389d03 100644 --- a/src/demo-components/ParserDemo.tsx +++ b/src/demo-components/ParserDemo.tsx @@ -130,20 +130,26 @@ function ParserDemo({ opts }: { opts: T.TextOptions }) { ) : "verb" in res ? ( (() => { - const rendered = renderVP(res); - const compiled = compileVP(rendered, res.form); - return ( -
- - {compiled.e && ( -
- {compiled.e.map((e, i) => ( -
{e}
- ))} -
- )} -
- ); + try { + const rendered = renderVP(res); + const compiled = compileVP(rendered, res.form); + return ( +
+ + {compiled.e && ( +
+ {compiled.e.map((e, i) => ( +
{e}
+ ))} +
+ )} +
+ ); + } catch (e) { + console.error(e); + console.log({ res }); + return
ERROR
; + } })() ) : ( diff --git a/src/lib/src/accent-helpers.ts b/src/lib/src/accent-helpers.ts index 27b50b7..9713a52 100644 --- a/src/lib/src/accent-helpers.ts +++ b/src/lib/src/accent-helpers.ts @@ -87,6 +87,9 @@ export function accentFSylsOnNFromEnd( if (typeof syls === "string") { return accentFSylsOnNFromEnd(splitUpSyllables(syls), n); } + if (syls.length === 0) { + return ""; + } return [ ...syls.slice(0, syls.length - (n + 1)), // before accent accentLetter(syls[syls.length - (n + 1)]), // syllable to be accented @@ -114,6 +117,9 @@ const accentReplacer = [ ]; export function accentLetter(s: string): string { + if (!s) { + console.log("will crash", s); + } return s.replace(/a|ă|e|i|o|u|U/, (match) => { const r = accentReplacer.find((x) => x.vowel === match); /* istanbul ignore next */ diff --git a/src/lib/src/parsing/compare.ts b/src/lib/src/parsing/compare.ts index e69de29..8b13789 100644 --- a/src/lib/src/parsing/compare.ts +++ b/src/lib/src/parsing/compare.ts @@ -0,0 +1 @@ + diff --git a/src/lib/src/parsing/lookup.tsx b/src/lib/src/parsing/lookup.tsx index 807c491..a47aa82 100644 --- a/src/lib/src/parsing/lookup.tsx +++ b/src/lib/src/parsing/lookup.tsx @@ -7,7 +7,33 @@ import { splitVarients, undoAaXuPattern } from "../p-text-helpers"; import { arraysHaveCommon } from "../misc-helpers"; import { shortVerbEndConsonant } from "./misc"; -export function lookup(s: Partial): T.DictionaryEntry[] { +export type LookupFunction = typeof lookup; + +export function lookup( + s: Partial, + type: "nounAdj" +): T.DictionaryEntry[]; +export function lookup(s: string, type: "verb" | "participle"): T.VerbEntry[]; +export function lookup( + s: string | Partial, + type: "nounAdj" | "verb" | "participle" +): T.DictionaryEntry[] | T.VerbEntry[] { + if (type === "nounAdj") { + if (typeof s !== "object") { + throw new Error("invalid query for noun / adj lookup"); + } + return nounAdjLookup(s); + } + if (typeof s === "object") { + throw new Error("invalid query"); + } + if (type === "verb") { + return verbLookup(s); + } + return participleLookup(s); +} + +function nounAdjLookup(s: Partial): T.DictionaryEntry[] { const [key, value] = Object.entries(s)[0]; // TODO: could make this more efficient - merging ppp and app queries? if (key === "ppp") { @@ -42,7 +68,7 @@ export function shouldCheckTpp(s: string): boolean { ); } -export function participleLookup(input: string): T.VerbEntry[] { +function participleLookup(input: string): T.VerbEntry[] { if (input.endsWith("ل")) { return verbs.filter((e) => e.entry.p === input); } @@ -59,7 +85,7 @@ export function participleLookup(input: string): T.VerbEntry[] { return []; } -export function verbLookup(input: string): T.VerbEntry[] { +function verbLookup(input: string): T.VerbEntry[] { // TODO: // only look up forms if there's an ending // or is third person thing diff --git a/src/lib/src/parsing/parse-adjective.ts b/src/lib/src/parsing/parse-adjective.ts index c9d5f07..2685d30 100644 --- a/src/lib/src/parsing/parse-adjective.ts +++ b/src/lib/src/parsing/parse-adjective.ts @@ -2,10 +2,11 @@ import * as T from "../../../types"; import { makeAdjectiveSelection } from "../phrase-building/make-selections"; import { isAdjectiveEntry } from "../type-predicates"; import { getInflectionQueries } from "./inflection-query"; +import { LookupFunction } from "./lookup"; export function parseAdjective( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[] + lookup: LookupFunction ): T.ParseResult<{ inflection: (0 | 1 | 2)[]; gender: T.Gender[]; @@ -19,7 +20,7 @@ export function parseAdjective( const [first, ...rest] = tokens; const queries = getInflectionQueries(first.s, false); queries.forEach(({ search, details }) => { - const wideMatches = lookup(search).filter(isAdjectiveEntry); + const wideMatches = lookup(search, "nounAdj").filter(isAdjectiveEntry); details.forEach((deets) => { const matches = wideMatches.filter(deets.predicate); matches.forEach((m) => { diff --git a/src/lib/src/parsing/parse-blocks.ts b/src/lib/src/parsing/parse-blocks.ts index 2156ae7..3a53341 100644 --- a/src/lib/src/parsing/parse-blocks.ts +++ b/src/lib/src/parsing/parse-blocks.ts @@ -1,4 +1,5 @@ import * as T from "../../../types"; +import { LookupFunction } from "./lookup"; import { parseKidsSection } from "./parse-kids-section"; import { parseNeg } from "./parse-negative"; import { parseNP } from "./parse-np"; @@ -8,9 +9,7 @@ import { bindParseResult, returnParseResult } from "./utils"; export function parseBlocks( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], - verbLookup: (s: string) => T.VerbEntry[], - participleLookup: (s: string) => T.VerbEntry[], + lookup: LookupFunction, blocks: T.ParsedBlock[], kids: T.ParsedKid[] ): T.ParseResult<{ @@ -24,9 +23,9 @@ export function parseBlocks( (b): b is T.ParsedPH => b.type === "PH" ); const vbExists = blocks.some((b) => "type" in b && b.type === "VB"); - const np = prevPh ? [] : parseNP(tokens, lookup, participleLookup); + const np = prevPh ? [] : parseNP(tokens, lookup); const ph = vbExists || prevPh ? [] : parsePH(tokens); - const vb = parseVerb(tokens, verbLookup); + const vb = parseVerb(tokens, lookup); const neg = parseNeg(tokens); const kidsR = parseKidsSection(tokens, []); const allResults: T.ParseResult[] = [ @@ -50,14 +49,7 @@ export function parseBlocks( const errors: T.ParseError[] = []; if (r.type === "kids") { return { - next: parseBlocks( - tokens, - lookup, - verbLookup, - participleLookup, - blocks, - [...kids, ...r.kids] - ), + next: parseBlocks(tokens, lookup, blocks, [...kids, ...r.kids]), errors: blocks.length !== 1 ? [{ message: "kids' section out of place" }] @@ -78,14 +70,7 @@ export function parseBlocks( return []; } return { - next: parseBlocks( - tokens, - lookup, - verbLookup, - participleLookup, - [...blocks, r], - kids - ), + next: parseBlocks(tokens, lookup, [...blocks, r], kids), errors, }; }); diff --git a/src/lib/src/parsing/parse-noun.test.ts b/src/lib/src/parsing/parse-noun.test.ts index c6c38d0..992f9b2 100644 --- a/src/lib/src/parsing/parse-noun.test.ts +++ b/src/lib/src/parsing/parse-noun.test.ts @@ -3,7 +3,7 @@ import { makeNounSelection, } from "../phrase-building/make-selections"; import * as T from "../../../types"; -import { lookup, participleLookup, wordQuery } from "./lookup"; +import { lookup, wordQuery } from "./lookup"; import { parseNoun } from "./parse-noun"; import { tokenizer } from "./tokenizer"; import { isCompleteResult } from "./utils"; @@ -1371,9 +1371,7 @@ describe("parsing nouns", () => { test(category, () => { cases.forEach(({ input, output }) => { const tokens = tokenizer(input); - const res = parseNoun(tokens, lookup, participleLookup).map( - ({ body }) => body - ); + const res = parseNoun(tokens, lookup).map(({ body }) => body); expect(res).toEqual(output); }); }); @@ -1505,7 +1503,7 @@ describe("parsing nouns with adjectives", () => { test(category, () => { cases.forEach(({ input, output }) => { const tokens = tokenizer(input); - const res = parseNoun(tokens, lookup, participleLookup) + const res = parseNoun(tokens, lookup) .filter(isCompleteResult) .map(({ body }) => body); expect(res).toEqual(output); diff --git a/src/lib/src/parsing/parse-noun.ts b/src/lib/src/parsing/parse-noun.ts index df6fb08..0e235f3 100644 --- a/src/lib/src/parsing/parse-noun.ts +++ b/src/lib/src/parsing/parse-noun.ts @@ -8,6 +8,7 @@ import { isUnisexNounEntry, } from "../type-predicates"; import { getInflectionQueries } from "./inflection-query"; +import { LookupFunction } from "./lookup"; import { parseAdjective } from "./parse-adjective"; import { parsePossesor } from "./parse-possesor"; import { bindParseResult } from "./utils"; @@ -16,13 +17,12 @@ type NounResult = { inflected: boolean; selection: T.NounSelection }; export function parseNoun( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], - pariticipleLookup: (s: string) => T.VerbEntry[] + lookup: LookupFunction ): T.ParseResult[] { if (tokens.length === 0) { return []; } - const possesor = parsePossesor(tokens, lookup, pariticipleLookup, undefined); + const possesor = parsePossesor(tokens, lookup, undefined); if (possesor.length) { return bindParseResult(possesor, (tokens, p) => { return parseNounAfterPossesor(tokens, lookup, p, []); @@ -33,7 +33,7 @@ export function parseNoun( function parseNounAfterPossesor( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], + lookup: LookupFunction, possesor: T.PossesorSelection | undefined, adjectives: { inflection: (0 | 1 | 2)[]; @@ -55,7 +55,7 @@ function parseNounAfterPossesor( const w: ReturnType = []; searches.forEach(({ search, details }) => { - const nounEntries = lookup(search).filter(isNounEntry); + const nounEntries = lookup(search, "nounAdj").filter(isNounEntry); details.forEach((deets) => { const fittingEntries = nounEntries.filter(deets.predicate); fittingEntries.forEach((entry) => { diff --git a/src/lib/src/parsing/parse-np.ts b/src/lib/src/parsing/parse-np.ts index a88cf2b..fd99851 100644 --- a/src/lib/src/parsing/parse-np.ts +++ b/src/lib/src/parsing/parse-np.ts @@ -3,11 +3,11 @@ import { parsePronoun } from "./parse-pronoun"; import { parseNoun } from "./parse-noun"; import { fmapParseResult } from "../fp-ps"; import { parseParticiple } from "./parse-participle"; +import { LookupFunction } from "./lookup"; export function parseNP( s: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], - participleLookup: (input: string) => T.VerbEntry[] + lookup: LookupFunction ): T.ParseResult[] { if (s.length === 0) { return []; @@ -40,7 +40,7 @@ export function parseNP( return fmapParseResult(makeNPSl, [ ...parsePronoun(s), - ...parseNoun(s, lookup, participleLookup), - ...parseParticiple(s, lookup, participleLookup), + ...parseNoun(s, lookup), + ...parseParticiple(s, lookup), ]); } diff --git a/src/lib/src/parsing/parse-participle.test.ts b/src/lib/src/parsing/parse-participle.test.ts index 54d0ffa..d4352a8 100644 --- a/src/lib/src/parsing/parse-participle.test.ts +++ b/src/lib/src/parsing/parse-participle.test.ts @@ -4,7 +4,7 @@ import { makePossesorSelection, } from "../phrase-building/make-selections"; import * as T from "../../../types"; -import { lookup, participleLookup, wordQuery } from "./lookup"; +import { lookup, wordQuery } from "./lookup"; import { tokenizer } from "./tokenizer"; import { parseParticiple } from "./parse-participle"; @@ -123,9 +123,7 @@ describe("parsing participles", () => { test(label, () => { cases.forEach(({ input, output }) => { const tokens = tokenizer(input); - const res = parseParticiple(tokens, lookup, participleLookup).map( - ({ body }) => body - ); + const res = parseParticiple(tokens, lookup).map(({ body }) => body); expect(res).toEqual(output); }); }); diff --git a/src/lib/src/parsing/parse-participle.ts b/src/lib/src/parsing/parse-participle.ts index b6938fb..ef93d23 100644 --- a/src/lib/src/parsing/parse-participle.ts +++ b/src/lib/src/parsing/parse-participle.ts @@ -1,4 +1,5 @@ import * as T from "../../../types"; +import { LookupFunction } from "./lookup"; import { parsePossesor } from "./parse-possesor"; import { bindParseResult } from "./utils"; @@ -9,25 +10,24 @@ type ParticipleResult = { export function parseParticiple( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], - participleLookup: (s: string) => T.VerbEntry[] + lookup: LookupFunction ): T.ParseResult[] { if (tokens.length === 0) { return []; } - const possesor = parsePossesor(tokens, lookup, participleLookup, undefined); + const possesor = parsePossesor(tokens, lookup, undefined); if (possesor.length) { return bindParseResult(possesor, (tokens, p) => { - return parseParticipleAfterPossesor(tokens, participleLookup, p); + return parseParticipleAfterPossesor(tokens, lookup, p); }); } - return parseParticipleAfterPossesor(tokens, participleLookup, undefined); + return parseParticipleAfterPossesor(tokens, lookup, undefined); } // TODO: should have adverbs with participle function parseParticipleAfterPossesor( tokens: Readonly, - participleLookup: (s: string) => T.VerbEntry[], + lookup: LookupFunction, possesor: T.PossesorSelection | undefined ): T.ParseResult[] { if (tokens.length === 0) { @@ -38,7 +38,7 @@ function parseParticipleAfterPossesor( return []; } const inflected = first.s.endsWith("و"); - const matches = participleLookup(first.s); + const matches = lookup(first.s, "participle"); return matches.map>((verb) => ({ tokens: rest, body: { diff --git a/src/lib/src/parsing/parse-ph.ts b/src/lib/src/parsing/parse-ph.ts index 2981b4f..565ab0c 100644 --- a/src/lib/src/parsing/parse-ph.ts +++ b/src/lib/src/parsing/parse-ph.ts @@ -14,6 +14,7 @@ const phs = [ "را", "ور", "پرا", + "لا", ]; export function parsePH( diff --git a/src/lib/src/parsing/parse-phrase.ts b/src/lib/src/parsing/parse-phrase.ts index 8c2c74f..16ee70c 100644 --- a/src/lib/src/parsing/parse-phrase.ts +++ b/src/lib/src/parsing/parse-phrase.ts @@ -1,5 +1,5 @@ import * as T from "../../../types"; -import { verbLookup, lookup, participleLookup } from "./lookup"; +import { lookup } from "./lookup"; import { parseNP } from "./parse-np"; import { parseVP } from "./parse-vp"; @@ -17,11 +17,9 @@ export function parsePhrase(s: T.Token[]): { errors: string[]; } { const res = [ - ...parseNP(s, lookup, participleLookup).filter( - ({ tokens }) => !tokens.length - ), + ...parseNP(s, lookup).filter(({ tokens }) => !tokens.length), // ...parseVerb(s, verbLookup), - ...parseVP(s, lookup, verbLookup, participleLookup), + ...parseVP(s, lookup), ]; const success = res.map((x) => x.body); diff --git a/src/lib/src/parsing/parse-possesor.test.ts b/src/lib/src/parsing/parse-possesor.test.ts index 64291de..b0b644c 100644 --- a/src/lib/src/parsing/parse-possesor.test.ts +++ b/src/lib/src/parsing/parse-possesor.test.ts @@ -5,7 +5,7 @@ import { makeNounSelection, makePronounSelection, } from "../phrase-building/make-selections"; -import { lookup, participleLookup, wordQuery } from "./lookup"; +import { lookup, wordQuery } from "./lookup"; import { parsePossesor } from "./parse-possesor"; import { tokenizer } from "./tokenizer"; import { isCompleteResult } from "./utils"; @@ -110,12 +110,12 @@ const tests: { test("parse possesor", () => { tests.forEach(({ input, output }) => { const tokens = tokenizer(input); - const parsed = parsePossesor(tokens, lookup, participleLookup, undefined); + const parsed = parsePossesor(tokens, lookup, undefined); if (output === "error") { expect(parsed.some((x) => x.errors.length)).toBe(true); } else { expect( - parsePossesor(tokens, lookup, participleLookup, undefined) + parsePossesor(tokens, lookup, undefined) .filter(isCompleteResult) .map((x) => x.body.np.selection) ).toEqual(output); diff --git a/src/lib/src/parsing/parse-possesor.ts b/src/lib/src/parsing/parse-possesor.ts index c873d19..794b4f0 100644 --- a/src/lib/src/parsing/parse-possesor.ts +++ b/src/lib/src/parsing/parse-possesor.ts @@ -1,4 +1,5 @@ import * as T from "../../../types"; +import { LookupFunction } from "./lookup"; import { parseNP } from "./parse-np"; import { bindParseResult } from "./utils"; // TODO: maybe contractions should just be male to cut down on the @@ -18,8 +19,7 @@ const contractions: [string[], T.Person[]][] = [ export function parsePossesor( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], - participleLookup: (s: string) => T.VerbEntry[], + lookup: LookupFunction, prevPossesor: T.PossesorSelection | undefined ): T.ParseResult[] { if (tokens.length === 0) { @@ -43,14 +43,14 @@ export function parsePossesor( ? [{ message: "a pronoun cannot have a possesor" }] : []; return contractions - .flatMap((p) => parsePossesor(rest, lookup, participleLookup, p)) + .flatMap((p) => parsePossesor(rest, lookup, p)) .map((x) => ({ ...x, errors: [...errors, ...x.errors], })); } if (first.s === "د") { - const np = parseNP(rest, lookup, participleLookup); + const np = parseNP(rest, lookup); return bindParseResult(np, (tokens, body) => { const possesor: T.PossesorSelection = { shrunken: false, @@ -63,12 +63,7 @@ export function parsePossesor( [{ message: `possesor should be inflected` }] : [], // add and check error - can't add possesor to pronoun - next: parsePossesor( - tokens, - lookup, - participleLookup, - addPoss(prevPossesor, possesor) - ), + next: parsePossesor(tokens, lookup, addPoss(prevPossesor, possesor)), }; }); } diff --git a/src/lib/src/parsing/parse-verb.test.ts b/src/lib/src/parsing/parse-verb.test.ts index 2281631..c3a2dea 100644 --- a/src/lib/src/parsing/parse-verb.test.ts +++ b/src/lib/src/parsing/parse-verb.test.ts @@ -8,10 +8,10 @@ import { wartlul, raatlul, } from "./irreg-verbs"; -import { verbLookup, wordQuery } from "./lookup"; +import { lookup, wordQuery } from "./lookup"; import { parseVerb } from "./parse-verb"; import { tokenizer } from "./tokenizer"; -import { removeKeys } from "./utils"; +import { getPeople, removeKeys } from "./utils"; const wahul = wordQuery("وهل", "verb"); const leekul = wordQuery("لیکل", "verb"); @@ -615,6 +615,18 @@ const tests: { }, ], }, + { + input: "لووت", + output: [ + { + root: { + persons: [T.Person.ThirdSingMale], + aspects: ["perfective"], + }, + verb: alwatul, + }, + ], + }, { input: "سم", output: [ @@ -627,6 +639,53 @@ const tests: { }, ], }, + { + input: "ړلم", + output: [ + { + root: { + persons: getPeople(1, "sing"), + aspects: ["perfective"], + }, + verb: wurul, + }, + { + root: { + persons: getPeople(1, "sing"), + aspects: ["perfective"], + }, + verb: tlul, + }, + ], + }, + { + input: "ړ", + output: [ + { + root: { + persons: [T.Person.ThirdSingMale], + aspects: ["perfective"], + }, + verb: wurul, + }, + { + root: { + persons: [T.Person.ThirdSingMale], + aspects: ["perfective"], + }, + verb: tlul, + }, + ], + }, + // should not match with the prefix for perfective + { + input: "یوړله", + output: [], + }, + { + input: "یوړ", + output: [], + }, ], }, { @@ -930,7 +989,7 @@ tests.forEach(({ label, cases }) => { test(label, () => { cases.forEach(({ input, output }) => { const tokens = tokenizer(input); - const vbs = parseVerb(tokens, verbLookup).map((r) => r.body); + const vbs = parseVerb(tokens, lookup).map((r) => r.body); const madeVbsS = output.reduce((acc, o) => { return [ ...acc, diff --git a/src/lib/src/parsing/parse-verb.ts b/src/lib/src/parsing/parse-verb.ts index 28d02a3..7417ab0 100644 --- a/src/lib/src/parsing/parse-verb.ts +++ b/src/lib/src/parsing/parse-verb.ts @@ -9,6 +9,7 @@ import { tlul, wartlul, } from "./irreg-verbs"; +import { LookupFunction } from "./lookup"; import { shortVerbEndConsonant } from "./misc"; // big problem ما سړی یوړ crashes it !! @@ -20,9 +21,11 @@ import { shortVerbEndConsonant } from "./misc"; // check څاته // laaRa shum etc +// TODO: هغه لاړ + export function parseVerb( tokens: Readonly, - verbLookup: (s: string) => T.VerbEntry[] + lookup: LookupFunction ): T.ParseResult[] { if (tokens.length === 0) { return []; @@ -39,7 +42,7 @@ export function parseVerb( const people = getVerbEnding(first.s); // First do rough verb lookup, grab wide pool of possible verbs (low searching complexity for fast lookup) // TODO: can optimize this to not have to look for possible stems/roots if none - const verbs = verbLookup(first.s); + const verbs = lookup(first.s, "verb"); // if (first.s === "سم") { // console.log({ verbs: JSON.stringify(verbs) }); // } @@ -197,15 +200,26 @@ function matchVerbs( const oEnd = s.at(-1) === "و"; const abruptEnd = shortVerbEndConsonant.includes(s.slice(-1)); const tppMatches = { - imperfective: entries.filter( - ({ entry: e }) => - !e.c.includes("comp") && - (isInVarients(e.tppp, s) || - (oEnd && [e.p, e.p.slice(0, -1)].includes(base)) || - (lastVowelNotA(e.g.slice(0, -2)) && - (hamzaEnd ? base : abruptEnd ? s : "") === e.p.slice(0, -1))) + imperfective: entries.reduce((acc, entry) => { + const e = entry.entry; + if (e.c.includes("comp")) { + return acc; + } + if (!e.prp && isInVarients(e.tppp, s)) { + return [...acc, entry]; + } + if (oEnd && matchShortOrLong(base, e.p)) { + return [...acc, entry]; + } + if ( + lastVowelNotA(e.g.slice(0, -2)) && + (hamzaEnd ? base : abruptEnd ? s : "XX") === e.p.slice(0, -1) + ) { + return [...acc, entry]; + } // TODO: if check for modified aaXu thing! - ), + return acc; + }, []), perfective: entries.reduce((acc, entry) => { const e = entry.entry; if (e.c.includes("comp")) { @@ -243,10 +257,12 @@ function matchVerbs( } } } - if (isInVarients(e.tppp, s)) { - return [...acc, entry]; - } else if (isInVarients(e.tppp, "ا" + s)) { - return [...acc, entry]; + if (!e.separationAtP) { + if (isInVarients(e.tppp, s)) { + return [...acc, entry]; + } else if (isInVarients(e.tppp, "ا" + s)) { + return [...acc, entry]; + } } return acc; }, []), diff --git a/src/lib/src/parsing/parse-vp.test.ts b/src/lib/src/parsing/parse-vp.test.ts index 954b6cd..e92a61f 100644 --- a/src/lib/src/parsing/parse-vp.test.ts +++ b/src/lib/src/parsing/parse-vp.test.ts @@ -9,7 +9,7 @@ import { makeNounSelection, makePronounSelection, } from "../phrase-building/make-selections"; -import { lookup, participleLookup, verbLookup, wordQuery } from "./lookup"; +import { lookup, wordQuery } from "./lookup"; import { parseVP } from "./parse-vp"; import { tokenizer } from "./tokenizer"; import { tlul } from "./irreg-verbs"; @@ -1382,7 +1382,7 @@ tests.forEach(({ label, cases }) => { test(label, () => { cases.forEach(({ input, output, error }) => { const tokens = tokenizer(input); - const parsed = parseVP(tokens, lookup, verbLookup, participleLookup); + const parsed = parseVP(tokens, lookup); if (error) { expect(parsed.filter((x) => x.errors.length).length).toBeTruthy(); } else { diff --git a/src/lib/src/parsing/parse-vp.ts b/src/lib/src/parsing/parse-vp.ts index 3b4987f..741e893 100644 --- a/src/lib/src/parsing/parse-vp.ts +++ b/src/lib/src/parsing/parse-vp.ts @@ -12,6 +12,7 @@ import { import { parseBlocks } from "./parse-blocks"; import { makePronounSelection } from "../phrase-building/make-selections"; import { isFirstOrSecondPersPronoun } from "../phrase-building/render-vp"; +import { LookupFunction } from "./lookup"; // to hide equatives type-doubling issue // this should also conjugate to @@ -30,21 +31,12 @@ import { isFirstOrSecondPersPronoun } from "../phrase-building/render-vp"; export function parseVP( tokens: Readonly, - lookup: (s: Partial) => T.DictionaryEntry[], - verbLookup: (s: string) => T.VerbEntry[], - participleLookup: (s: string) => T.VerbEntry[] + lookup: LookupFunction ): T.ParseResult[] { if (tokens.length === 0) { return []; } - const blocks = parseBlocks( - tokens, - lookup, - verbLookup, - participleLookup, - [], - [] - ); + const blocks = parseBlocks(tokens, lookup, [], []); return bindParseResult(blocks, (tokens, { blocks, kids }) => { const phIndex = blocks.findIndex((x) => x.type === "PH"); const vbeIndex = blocks.findIndex((x) => x.type === "VB"); diff --git a/src/lib/src/phrase-building/render-np.ts b/src/lib/src/phrase-building/render-np.ts index c05e769..2641a6d 100644 --- a/src/lib/src/phrase-building/render-np.ts +++ b/src/lib/src/phrase-building/render-np.ts @@ -13,7 +13,7 @@ import { } from "../type-predicates"; import { shortVerbEndConsonant } from "../parsing/misc"; import { removeL } from "../new-verb-engine/rs-helpers"; -import { applySingleOrLengthOpts, fmapSingleOrLengthOpts } from "../fp-ps"; +import { applySingleOrLengthOpts } from "../fp-ps"; import { accentOnNFromEnd } from "../accent-helpers"; // TODO: can have subject and objects in possesors!! diff --git a/src/types.ts b/src/types.ts index 2ed64f1..9aed801 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1031,7 +1031,9 @@ export type Rendered< type: "undefined"; ps: PsString; } - : ReplaceKey< + : // TODO: this will be a problem (removing the change gender etc) + // if we want to make the sentence diagram interactive + ReplaceKey< Omit< T, | "changeGender" @@ -1043,7 +1045,7 @@ export type Rendered< "e", string > & { - ps: PsString[]; + ps: SingleOrLengthOpts; e?: string; inflected: boolean; person: Person;