Skip to content

Commit

Permalink
feat: extend support for irregular inflections of suru-verbs
Browse files Browse the repository at this point in the history
This adds support for irregular inflections of する-verbs
by introducing a new inflection reason: 'irregular'.
This is used to handle cases where the verbs deviate from the
standard する conjugation pattern.

The following irregular forms are now supported:
- ⚪︎せさせる, ⚪︎せられる (irregular causative and passive forms)
- ⚪︎しさせる, ⚪︎しられる (alternative causative and passive forms)
- 五段化-verbs (する-verbs inflected as す-Godan verbs)
- ずる-verbs
  • Loading branch information
enellis committed Oct 10, 2024
1 parent 874c189 commit 001270c
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 11 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
<img src="https://raw.githubusercontent.com/birchill/10ten-ja-reader/main/docs/jou-conversion-cropped.png" alt="Screenshot showing translation of 四畳半 into 7.29 square meters" title="Area translation" width="640">

- Recognition of a wide range of grammatical forms
(e.g. irregular verbs like いらっしゃいます,
(e.g. irregular inflections of する-verbs like 罰せられる,
irregular verbs like いらっしゃいます,
continuous forms like 食べてた,
ん as a negative form like 分からん、知らん,
words with ー like じーちゃん、頑張ろー、そーゆー,
Expand Down
3 changes: 3 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@
"deinflect_imperative_negative": {
"message": "imperative negative"
},
"deinflect_irregular": {
"message": "irregular"
},
"deinflect_ki": {
"message": "-ki"
},
Expand Down
3 changes: 3 additions & 0 deletions _locales/ja/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@
"deinflect_imperative_negative": {
"message": "否定命令形"
},
"deinflect_irregular": {
"message": "不規則"
},
"deinflect_ki": {
"message": "連体形"
},
Expand Down
3 changes: 3 additions & 0 deletions _locales/zh_hans/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@
"deinflect_imperative_negative": {
"message": "否定命令形"
},
"deinflect_irregular": {
"message": ""
},
"deinflect_ki": {
"message": "连体形"
},
Expand Down
62 changes: 60 additions & 2 deletions src/background/deinflect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,64 @@ describe('deinflect', () => {
});
});

it('deinflects all forms of する', () => {
const cases = [
['した', [Reason.Past]],
['しよう', [Reason.Volitional]],
['しない', [Reason.Negative]],
['せぬ', [Reason.Negative]],
['せん', [Reason.Negative]],
['せず', [Reason.Zu]],
['される', [Reason.Passive]],
['させる', [Reason.Causative]],
['しろ', [Reason.Imperative]],
['せよ', [Reason.Imperative]],
['すれば', [Reason.Ba]],
['できる', [Reason.Potential]],
];

for (const [inflected, reasons] of cases) {
const result = deinflect(inflected as string);
const match = result.find(
(candidate) =>
candidate.word == 'する' && candidate.type & WordType.SuruVerb
);
expect(match).toBeDefined();
expect(match!.reasonChains).toEqual([reasons]);
}
});

it('deinflects additional forms of special class suru-verbs', () => {
const cases = [
['発する', '発せさせる', [Reason.Irregular, Reason.Causative]],
['発する', '発せられる', [Reason.Irregular, Reason.PotentialOrPassive]],
['発する', '発しさせる', [Reason.Irregular, Reason.Causative]],
['発する', '発しられる', [Reason.Irregular, Reason.PotentialOrPassive]],
// 五段化
['発する', '発さない', [Reason.Irregular, Reason.Negative]],
['発する', '発さず', [Reason.Irregular, Reason.Zu]],
['発する', '発そう', [Reason.Irregular, Reason.Volitional]],
['愛する', '愛せる', [Reason.Irregular, Reason.Potential]],
['愛する', '愛せば', [Reason.Irregular, Reason.Ba]],
['愛する', '愛せ', [Reason.Irregular, Reason.Imperative]],
// ずる
['信ずる', '信ぜぬ', [Reason.Irregular, Reason.Negative]],
['信ずる', '信ぜず', [Reason.Irregular, Reason.Zu]],
['信ずる', '信ぜさせる', [Reason.Irregular, Reason.Causative]],
['信ずる', '信ぜられる', [Reason.Irregular, Reason.PotentialOrPassive]],
['信ずる', '信ずれば', [Reason.Irregular, Reason.Ba]],
['信ずる', '信ぜよ', [Reason.Irregular, Reason.Imperative]],
];

for (const [plain, inflected, reasons] of cases) {
const result = deinflect(inflected as string);
const match = result.find((candidate) => candidate.word == plain);
expect(match).toBeDefined();
expect(match!.type).toEqual(WordType.SpecialSuruVerb);
expect(match!.reasonChains).toEqual([reasons]);
}
});

it('deinflects irregular forms of 行く', () => {
const cases = [
['行った', '行く', Reason.Past, 2],
Expand Down Expand Up @@ -300,8 +358,8 @@ describe('deinflect', () => {
['歩いてる', '歩く', 2, undefined],
['泳いでいる', '泳ぐ', 2, undefined],
['泳いでる', '泳ぐ', 2, undefined],
['話している', '話す', 18, undefined],
['話してる', '話す', 18, undefined],
['話している', '話す', 2, undefined],
['話してる', '話す', 2, undefined],
['死んでいる', '死ぬ', 2, undefined],
['死んでる', '死ぬ', 2, undefined],
['飼っている', '飼う', 2, undefined],
Expand Down
39 changes: 32 additions & 7 deletions src/background/deinflect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const enum Reason {
SuruNoun,
ZaruWoEnai,
NegativeTe,
Irregular,
}

export const deinflectL10NKeys: { [key: number]: string } = {
Expand Down Expand Up @@ -76,6 +77,7 @@ export const deinflectL10NKeys: { [key: number]: string } = {
[Reason.SuruNoun]: 'deinflect_suru_noun',
[Reason.ZaruWoEnai]: 'deinflect_zaru_wo_enai',
[Reason.NegativeTe]: 'deinflect_negative_te',
[Reason.Irregular]: 'deinflect_irregular',
};

const enum Type {
Expand All @@ -85,14 +87,21 @@ const enum Type {
IAdj = 1 << 2,
KuruVerb = 1 << 3,
SuruVerb = 1 << 4,
NounVS = 1 << 5,
All = IchidanVerb | GodanVerb | IAdj | KuruVerb | SuruVerb | NounVS,
SpecialSuruVerb = 1 << 5,
NounVS = 1 << 6,
All = IchidanVerb |
GodanVerb |
IAdj |
KuruVerb |
SuruVerb |
SpecialSuruVerb |
NounVS,
// Intermediate types
Initial = 1 << 6, // original word before any deinflection (from-type only)
TaTeStem = 1 << 7,
DaDeStem = 1 << 8,
MasuStem = 1 << 9,
IrrealisStem = 1 << 10,
Initial = 1 << 7, // original word before any deinflection (from-type only)
TaTeStem = 1 << 8,
DaDeStem = 1 << 9,
MasuStem = 1 << 10,
IrrealisStem = 1 << 11,
}

export { Type as WordType };
Expand Down Expand Up @@ -169,6 +178,12 @@ const deinflectRuleData: Array<
['ざるえぬ', '', Type.IAdj, Type.IrrealisStem, [Reason.ZaruWoEnai]],
['ざる得ぬ', '', Type.IAdj, Type.IrrealisStem, [Reason.ZaruWoEnai]],
['しないで', 'する', Type.Initial, Type.SuruVerb, [Reason.NegativeTe]],
['しさせる', 'する', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Causative]],
['しられる', 'する', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.PotentialOrPassive]],
['せさせる', 'する', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Causative]],
['せられる', 'する', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.PotentialOrPassive]],
['ぜさせる', 'ずる', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Causative]],
['ぜられる', 'ずる', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.PotentialOrPassive]],
['たゆたう', 'たゆたう', Type.TaTeStem, Type.GodanVerb, []],
['たゆとう', 'たゆとう', Type.TaTeStem, Type.GodanVerb, []],
['のたまう', 'のたまう', Type.TaTeStem, Type.GodanVerb, []],
Expand All @@ -193,6 +208,7 @@ const deinflectRuleData: Array<
['御座い', '御座る', Type.MasuStem, Type.GodanVerb, [Reason.MasuStem]],
['させる', 'る', Type.IchidanVerb, Type.IchidanVerb | Type.KuruVerb, [Reason.Causative]],
['させる', 'する', Type.IchidanVerb, Type.SuruVerb, [Reason.Causative]],
['さない', 'する', Type.IAdj, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Negative]],
['される', '', Type.IchidanVerb, Type.IrrealisStem, [Reason.CausativePassive]],
['される', 'する', Type.IchidanVerb, Type.SuruVerb, [Reason.Passive]],
['しない', 'する', Type.IAdj, Type.SuruVerb, [Reason.Negative]],
Expand All @@ -202,6 +218,7 @@ const deinflectRuleData: Array<
['すぎる', '', Type.IchidanVerb, Type.MasuStem, [Reason.Sugiru]],
['過ぎる', 'い', Type.IchidanVerb, Type.IAdj, [Reason.Sugiru]],
['過ぎる', '', Type.IchidanVerb, Type.MasuStem, [Reason.Sugiru]],
['ずれば', 'ずる', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Ba]],
['たまう', 'たまう', Type.TaTeStem, Type.GodanVerb, []],
['たもう', 'たもう', Type.TaTeStem, Type.GodanVerb, []],
['揺蕩う', '揺蕩う', Type.TaTeStem, Type.GodanVerb, []],
Expand Down Expand Up @@ -240,6 +257,7 @@ const deinflectRuleData: Array<
['こう', 'く', Type.Initial, Type.GodanVerb, [Reason.Volitional]],
['ごう', 'ぐ', Type.Initial, Type.GodanVerb, [Reason.Volitional]],
['しろ', 'する', Type.Initial, Type.SuruVerb, [Reason.Imperative]],
['さず', 'する', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Zu]],
['すぎ', 'い', Type.Initial, Type.IAdj, [Reason.Sugiru]],
['すぎ', '', Type.Initial, Type.MasuStem, [Reason.Sugiru]],
['過ぎ', 'い', Type.Initial, Type.IAdj, [Reason.Sugiru]],
Expand All @@ -249,12 +267,18 @@ const deinflectRuleData: Array<
['せぬ', 'する', Type.Initial, Type.SuruVerb, [Reason.Negative]],
['せん', 'する', Type.Initial, Type.SuruVerb, [Reason.Negative]],
['せば', 'す', Type.Initial, Type.GodanVerb, [Reason.Ba]],
['せば', 'する', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Ba]],
['せる', 'する', Type.IchidanVerb, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Potential]],
['せよ', 'する', Type.Initial, Type.SuruVerb, [Reason.Imperative]],
['せる', 'す', Type.IchidanVerb, Type.GodanVerb, [Reason.Potential]],
['せる', '', Type.IchidanVerb, Type.IrrealisStem, [Reason.Causative]],
['ぜず', 'ずる', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Zu]],
['ぜぬ', 'ずる', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Negative]],
['ぜよ', 'ずる', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Imperative]],
['そう', '', Type.Initial, Type.MasuStem, [Reason.Sou]],
['そう', 'い', Type.Initial, Type.IAdj, [Reason.Sou]],
['そう', 'す', Type.Initial, Type.GodanVerb, [Reason.Volitional]],
['そう', 'する', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Volitional]],
['たい', '', Type.IAdj, Type.MasuStem, [Reason.Tai]],
['たら', '', Type.Initial, Type.TaTeStem, [Reason.Tara]],
['だら', '', Type.Initial, Type.DaDeStem, [Reason.Tara]],
Expand Down Expand Up @@ -333,6 +357,7 @@ const deinflectRuleData: Array<
['し', 'する', Type.TaTeStem, Type.SuruVerb, []],
['ず', '', Type.Initial, Type.IrrealisStem, [Reason.Zu]],
['せ', 'す', Type.Initial, Type.GodanVerb, [Reason.Imperative]],
['せ', 'する', Type.Initial, Type.SpecialSuruVerb, [Reason.Irregular, Reason.Imperative]],
['た', 'つ', Type.IrrealisStem, Type.GodanVerb, []],
['た', '', Type.Initial, Type.TaTeStem, [Reason.Past]],
['だ', '', Type.Initial, Type.DaDeStem, [Reason.Past]],
Expand Down
9 changes: 8 additions & 1 deletion src/background/word-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,14 @@ function entryMatchesType(entry: DictionaryWordResult, type: number): boolean {

if (
type & WordType.SuruVerb &&
hasMatchingSense((pos) => pos.startsWith('vs-'))
hasMatchingSense((pos) => pos === 'vs-i' || pos === 'vs-s')
) {
return true;
}

if (
type & WordType.SpecialSuruVerb &&
hasMatchingSense((pos) => pos === 'vs-s' || pos === 'vz')
) {
return true;
}
Expand Down

0 comments on commit 001270c

Please sign in to comment.