@lokascript/framework 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/languages/ar.cjs +7 -0
- package/dist/languages/ar.cjs.map +1 -0
- package/dist/languages/ar.d.ts +49 -0
- package/dist/languages/ar.d.ts.map +1 -0
- package/dist/languages/ar.js +7 -0
- package/dist/languages/ar.js.map +1 -0
- package/dist/languages/bn.cjs +7 -0
- package/dist/languages/bn.cjs.map +1 -0
- package/dist/languages/bn.d.ts +58 -0
- package/dist/languages/bn.d.ts.map +1 -0
- package/dist/languages/bn.js +7 -0
- package/dist/languages/bn.js.map +1 -0
- package/dist/languages/chunks/chunk-2Y3XXFQO.cjs +47 -0
- package/dist/languages/chunks/chunk-2Y3XXFQO.cjs.map +1 -0
- package/dist/languages/chunks/chunk-7JFC6YCG.cjs +38 -0
- package/dist/languages/chunks/chunk-7JFC6YCG.cjs.map +1 -0
- package/dist/languages/chunks/chunk-7M7D3AZV.js +36 -0
- package/dist/languages/chunks/chunk-7M7D3AZV.js.map +1 -0
- package/dist/languages/chunks/chunk-BLWOTGS4.cjs +33 -0
- package/dist/languages/chunks/chunk-BLWOTGS4.cjs.map +1 -0
- package/dist/languages/chunks/chunk-BNU64ZWY.cjs +33 -0
- package/dist/languages/chunks/chunk-BNU64ZWY.cjs.map +1 -0
- package/dist/languages/chunks/chunk-CCC73SLG.js +33 -0
- package/dist/languages/chunks/chunk-CCC73SLG.js.map +1 -0
- package/dist/languages/chunks/chunk-CEZSJJBE.js +35 -0
- package/dist/languages/chunks/chunk-CEZSJJBE.js.map +1 -0
- package/dist/languages/chunks/chunk-CJPWN3UM.cjs +33 -0
- package/dist/languages/chunks/chunk-CJPWN3UM.cjs.map +1 -0
- package/dist/languages/chunks/chunk-CZUFBVAP.cjs +36 -0
- package/dist/languages/chunks/chunk-CZUFBVAP.cjs.map +1 -0
- package/dist/languages/chunks/chunk-DFQ7CZ43.js +32 -0
- package/dist/languages/chunks/chunk-DFQ7CZ43.js.map +1 -0
- package/dist/languages/chunks/chunk-DZIG3L3C.js +33 -0
- package/dist/languages/chunks/chunk-DZIG3L3C.js.map +1 -0
- package/dist/languages/chunks/chunk-EEEJDKZH.cjs +41 -0
- package/dist/languages/chunks/chunk-EEEJDKZH.cjs.map +1 -0
- package/dist/languages/chunks/chunk-EH3CS6QF.cjs +39 -0
- package/dist/languages/chunks/chunk-EH3CS6QF.cjs.map +1 -0
- package/dist/languages/chunks/chunk-EQVZR5WU.js +36 -0
- package/dist/languages/chunks/chunk-EQVZR5WU.js.map +1 -0
- package/dist/languages/chunks/chunk-EY2I2PZI.cjs +42 -0
- package/dist/languages/chunks/chunk-EY2I2PZI.cjs.map +1 -0
- package/dist/languages/chunks/chunk-FDD6SCYE.js +38 -0
- package/dist/languages/chunks/chunk-FDD6SCYE.js.map +1 -0
- package/dist/languages/chunks/chunk-FDL3DCUR.cjs +38 -0
- package/dist/languages/chunks/chunk-FDL3DCUR.cjs.map +1 -0
- package/dist/languages/chunks/chunk-FQZEBNEC.js +32 -0
- package/dist/languages/chunks/chunk-FQZEBNEC.js.map +1 -0
- package/dist/languages/chunks/chunk-FXKGDEEF.js +32 -0
- package/dist/languages/chunks/chunk-FXKGDEEF.js.map +1 -0
- package/dist/languages/chunks/chunk-G727KC5F.js +34 -0
- package/dist/languages/chunks/chunk-G727KC5F.js.map +1 -0
- package/dist/languages/chunks/chunk-HRTBXKAS.js +34 -0
- package/dist/languages/chunks/chunk-HRTBXKAS.js.map +1 -0
- package/dist/languages/chunks/chunk-HTWLJAXE.cjs +34 -0
- package/dist/languages/chunks/chunk-HTWLJAXE.cjs.map +1 -0
- package/dist/languages/chunks/chunk-IG2BHTIU.js +50 -0
- package/dist/languages/chunks/chunk-IG2BHTIU.js.map +1 -0
- package/dist/languages/chunks/chunk-JJGECSB7.js +44 -0
- package/dist/languages/chunks/chunk-JJGECSB7.js.map +1 -0
- package/dist/languages/chunks/chunk-KPGJSWSP.js +32 -0
- package/dist/languages/chunks/chunk-KPGJSWSP.js.map +1 -0
- package/dist/languages/chunks/chunk-LGZCHKVL.cjs +50 -0
- package/dist/languages/chunks/chunk-LGZCHKVL.cjs.map +1 -0
- package/dist/languages/chunks/chunk-LMRNA2XQ.cjs +35 -0
- package/dist/languages/chunks/chunk-LMRNA2XQ.cjs.map +1 -0
- package/dist/languages/chunks/chunk-NS4L6RCJ.js +42 -0
- package/dist/languages/chunks/chunk-NS4L6RCJ.js.map +1 -0
- package/dist/languages/chunks/chunk-OGVDC4MV.js +33 -0
- package/dist/languages/chunks/chunk-OGVDC4MV.js.map +1 -0
- package/dist/languages/chunks/chunk-OOI6MH2H.js +47 -0
- package/dist/languages/chunks/chunk-OOI6MH2H.js.map +1 -0
- package/dist/languages/chunks/chunk-OSHTQPFA.js +35 -0
- package/dist/languages/chunks/chunk-OSHTQPFA.js.map +1 -0
- package/dist/languages/chunks/chunk-P2ONCOPE.js +33 -0
- package/dist/languages/chunks/chunk-P2ONCOPE.js.map +1 -0
- package/dist/languages/chunks/chunk-PC4BLDMN.js +41 -0
- package/dist/languages/chunks/chunk-PC4BLDMN.js.map +1 -0
- package/dist/languages/chunks/chunk-Q7Z57FEP.js +39 -0
- package/dist/languages/chunks/chunk-Q7Z57FEP.js.map +1 -0
- package/dist/languages/chunks/chunk-SFDLZDQC.cjs +36 -0
- package/dist/languages/chunks/chunk-SFDLZDQC.cjs.map +1 -0
- package/dist/languages/chunks/chunk-SLSZETLO.js +39 -0
- package/dist/languages/chunks/chunk-SLSZETLO.js.map +1 -0
- package/dist/languages/chunks/chunk-T5QEXBP6.cjs +39 -0
- package/dist/languages/chunks/chunk-T5QEXBP6.cjs.map +1 -0
- package/dist/languages/chunks/chunk-TM54B2L7.cjs +34 -0
- package/dist/languages/chunks/chunk-TM54B2L7.cjs.map +1 -0
- package/dist/languages/chunks/chunk-UYYD7BWL.cjs +32 -0
- package/dist/languages/chunks/chunk-UYYD7BWL.cjs.map +1 -0
- package/dist/languages/chunks/chunk-V3EPOWJS.cjs +32 -0
- package/dist/languages/chunks/chunk-V3EPOWJS.cjs.map +1 -0
- package/dist/languages/chunks/chunk-W4Y2BHDV.cjs +33 -0
- package/dist/languages/chunks/chunk-W4Y2BHDV.cjs.map +1 -0
- package/dist/languages/chunks/chunk-W7UIUU64.cjs +32 -0
- package/dist/languages/chunks/chunk-W7UIUU64.cjs.map +1 -0
- package/dist/languages/chunks/chunk-WOTY3GYE.cjs +44 -0
- package/dist/languages/chunks/chunk-WOTY3GYE.cjs.map +1 -0
- package/dist/languages/chunks/chunk-WYH4M6NK.js +78 -0
- package/dist/languages/chunks/chunk-WYH4M6NK.js.map +1 -0
- package/dist/languages/chunks/chunk-XFSNOEMB.cjs +32 -0
- package/dist/languages/chunks/chunk-XFSNOEMB.cjs.map +1 -0
- package/dist/languages/chunks/chunk-XHHTLZRZ.cjs +78 -0
- package/dist/languages/chunks/chunk-XHHTLZRZ.cjs.map +1 -0
- package/dist/languages/chunks/chunk-YTZILXWL.cjs +35 -0
- package/dist/languages/chunks/chunk-YTZILXWL.cjs.map +1 -0
- package/dist/languages/chunks/chunk-ZLMXABY7.js +38 -0
- package/dist/languages/chunks/chunk-ZLMXABY7.js.map +1 -0
- package/dist/languages/de.cjs +7 -0
- package/dist/languages/de.cjs.map +1 -0
- package/dist/languages/de.d.ts +47 -0
- package/dist/languages/de.d.ts.map +1 -0
- package/dist/languages/de.js +7 -0
- package/dist/languages/de.js.map +1 -0
- package/dist/languages/en.cjs +7 -0
- package/dist/languages/en.cjs.map +1 -0
- package/dist/languages/en.d.ts +54 -0
- package/dist/languages/en.d.ts.map +1 -0
- package/dist/languages/en.js +7 -0
- package/dist/languages/en.js.map +1 -0
- package/dist/languages/es.cjs +7 -0
- package/dist/languages/es.cjs.map +1 -0
- package/dist/languages/es.d.ts +47 -0
- package/dist/languages/es.d.ts.map +1 -0
- package/dist/languages/es.js +7 -0
- package/dist/languages/es.js.map +1 -0
- package/dist/languages/fr.cjs +7 -0
- package/dist/languages/fr.cjs.map +1 -0
- package/dist/languages/fr.d.ts +47 -0
- package/dist/languages/fr.d.ts.map +1 -0
- package/dist/languages/fr.js +7 -0
- package/dist/languages/fr.js.map +1 -0
- package/dist/languages/he.cjs +7 -0
- package/dist/languages/he.cjs.map +1 -0
- package/dist/languages/he.d.ts +51 -0
- package/dist/languages/he.d.ts.map +1 -0
- package/dist/languages/he.js +7 -0
- package/dist/languages/he.js.map +1 -0
- package/dist/languages/hi.cjs +7 -0
- package/dist/languages/hi.cjs.map +1 -0
- package/dist/languages/hi.d.ts +54 -0
- package/dist/languages/hi.d.ts.map +1 -0
- package/dist/languages/hi.js +7 -0
- package/dist/languages/hi.js.map +1 -0
- package/dist/languages/id.cjs +7 -0
- package/dist/languages/id.cjs.map +1 -0
- package/dist/languages/id.d.ts +45 -0
- package/dist/languages/id.d.ts.map +1 -0
- package/dist/languages/id.js +7 -0
- package/dist/languages/id.js.map +1 -0
- package/dist/languages/index.cjs +99 -0
- package/dist/languages/index.cjs.map +1 -0
- package/dist/languages/index.d.ts +30 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +99 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/it.cjs +7 -0
- package/dist/languages/it.cjs.map +1 -0
- package/dist/languages/it.d.ts +48 -0
- package/dist/languages/it.d.ts.map +1 -0
- package/dist/languages/it.js +7 -0
- package/dist/languages/it.js.map +1 -0
- package/dist/languages/ja.cjs +7 -0
- package/dist/languages/ja.cjs.map +1 -0
- package/dist/languages/ja.d.ts +58 -0
- package/dist/languages/ja.d.ts.map +1 -0
- package/dist/languages/ja.js +7 -0
- package/dist/languages/ja.js.map +1 -0
- package/dist/languages/ko.cjs +7 -0
- package/dist/languages/ko.cjs.map +1 -0
- package/dist/languages/ko.d.ts +61 -0
- package/dist/languages/ko.d.ts.map +1 -0
- package/dist/languages/ko.js +7 -0
- package/dist/languages/ko.js.map +1 -0
- package/dist/languages/ms.cjs +7 -0
- package/dist/languages/ms.cjs.map +1 -0
- package/dist/languages/ms.d.ts +44 -0
- package/dist/languages/ms.d.ts.map +1 -0
- package/dist/languages/ms.js +7 -0
- package/dist/languages/ms.js.map +1 -0
- package/dist/languages/pl.cjs +7 -0
- package/dist/languages/pl.cjs.map +1 -0
- package/dist/languages/pl.d.ts +50 -0
- package/dist/languages/pl.d.ts.map +1 -0
- package/dist/languages/pl.js +7 -0
- package/dist/languages/pl.js.map +1 -0
- package/dist/languages/pt.cjs +7 -0
- package/dist/languages/pt.cjs.map +1 -0
- package/dist/languages/pt.d.ts +46 -0
- package/dist/languages/pt.d.ts.map +1 -0
- package/dist/languages/pt.js +7 -0
- package/dist/languages/pt.js.map +1 -0
- package/dist/languages/qu.cjs +7 -0
- package/dist/languages/qu.cjs.map +1 -0
- package/dist/languages/qu.d.ts +48 -0
- package/dist/languages/qu.d.ts.map +1 -0
- package/dist/languages/qu.js +7 -0
- package/dist/languages/qu.js.map +1 -0
- package/dist/languages/ru.cjs +7 -0
- package/dist/languages/ru.cjs.map +1 -0
- package/dist/languages/ru.d.ts +50 -0
- package/dist/languages/ru.d.ts.map +1 -0
- package/dist/languages/ru.js +7 -0
- package/dist/languages/ru.js.map +1 -0
- package/dist/languages/sw.cjs +7 -0
- package/dist/languages/sw.cjs.map +1 -0
- package/dist/languages/sw.d.ts +45 -0
- package/dist/languages/sw.d.ts.map +1 -0
- package/dist/languages/sw.js +7 -0
- package/dist/languages/sw.js.map +1 -0
- package/dist/languages/th.cjs +7 -0
- package/dist/languages/th.cjs.map +1 -0
- package/dist/languages/th.d.ts +48 -0
- package/dist/languages/th.d.ts.map +1 -0
- package/dist/languages/th.js +7 -0
- package/dist/languages/th.js.map +1 -0
- package/dist/languages/tl.cjs +7 -0
- package/dist/languages/tl.cjs.map +1 -0
- package/dist/languages/tl.d.ts +44 -0
- package/dist/languages/tl.d.ts.map +1 -0
- package/dist/languages/tl.js +7 -0
- package/dist/languages/tl.js.map +1 -0
- package/dist/languages/tr.cjs +7 -0
- package/dist/languages/tr.cjs.map +1 -0
- package/dist/languages/tr.d.ts +57 -0
- package/dist/languages/tr.d.ts.map +1 -0
- package/dist/languages/tr.js +7 -0
- package/dist/languages/tr.js.map +1 -0
- package/dist/languages/types.d.ts +137 -0
- package/dist/languages/types.d.ts.map +1 -0
- package/dist/languages/uk.cjs +7 -0
- package/dist/languages/uk.cjs.map +1 -0
- package/dist/languages/uk.d.ts +50 -0
- package/dist/languages/uk.d.ts.map +1 -0
- package/dist/languages/uk.js +7 -0
- package/dist/languages/uk.js.map +1 -0
- package/dist/languages/vi.cjs +7 -0
- package/dist/languages/vi.cjs.map +1 -0
- package/dist/languages/vi.d.ts +47 -0
- package/dist/languages/vi.d.ts.map +1 -0
- package/dist/languages/vi.js +7 -0
- package/dist/languages/vi.js.map +1 -0
- package/dist/languages/zh.cjs +7 -0
- package/dist/languages/zh.cjs.map +1 -0
- package/dist/languages/zh.d.ts +49 -0
- package/dist/languages/zh.d.ts.map +1 -0
- package/dist/languages/zh.js +7 -0
- package/dist/languages/zh.js.map +1 -0
- package/dist/testing/index.js +1416 -930
- package/dist/testing/index.js.map +1 -1
- package/package.json +130 -5
- package/src/index.ts +2 -0
- package/src/languages/ar.ts +41 -0
- package/src/languages/bn.ts +45 -0
- package/src/languages/de.ts +37 -0
- package/src/languages/en.ts +36 -0
- package/src/languages/es.ts +40 -0
- package/src/languages/fr.ts +36 -0
- package/src/languages/he.ts +38 -0
- package/src/languages/hi.ts +44 -0
- package/src/languages/id.ts +34 -0
- package/src/languages/index.ts +42 -0
- package/src/languages/it.ts +38 -0
- package/src/languages/ja.ts +49 -0
- package/src/languages/ko.ts +50 -0
- package/src/languages/languages.test.ts +57 -0
- package/src/languages/ms.ts +33 -0
- package/src/languages/pl.ts +39 -0
- package/src/languages/pt.ts +34 -0
- package/src/languages/qu.ts +34 -0
- package/src/languages/ru.ts +37 -0
- package/src/languages/sw.ts +34 -0
- package/src/languages/th.ts +44 -0
- package/src/languages/tl.ts +37 -0
- package/src/languages/tr.ts +76 -0
- package/src/languages/types.ts +145 -0
- package/src/languages/uk.ts +37 -0
- package/src/languages/vi.ts +36 -0
- package/src/languages/zh.ts +36 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Korean Grammar
|
|
3
|
+
*
|
|
4
|
+
* SOV word order, particles (을/를, 에, 에서, etc.), space-separated between words.
|
|
5
|
+
* Agglutinative language with particles attaching to words.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { GrammarProfile } from './types';
|
|
9
|
+
|
|
10
|
+
export const koreanGrammar = {
|
|
11
|
+
code: 'ko',
|
|
12
|
+
name: 'Korean',
|
|
13
|
+
nativeName: '한국어',
|
|
14
|
+
direction: 'ltr',
|
|
15
|
+
script: 'hangul',
|
|
16
|
+
wordOrder: 'SOV',
|
|
17
|
+
markingStrategy: 'particle',
|
|
18
|
+
usesSpaces: true, // Korean uses spaces between words, but particles attach
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'end',
|
|
21
|
+
suffixes: ['다', '요', '니다', '세요'],
|
|
22
|
+
subjectDrop: true,
|
|
23
|
+
},
|
|
24
|
+
possessive: {
|
|
25
|
+
marker: '의', // Possessive particle
|
|
26
|
+
markerPosition: 'between',
|
|
27
|
+
},
|
|
28
|
+
roleMarkers: {
|
|
29
|
+
patient: { primary: '을', alternatives: ['를'], position: 'after' },
|
|
30
|
+
// 에서 is deliberately NOT a destination alternative: it is the SOURCE
|
|
31
|
+
// primary ("at/from"), and listing it here let an unconsumed wait-line
|
|
32
|
+
// tail (`문서 에서` — from document) satisfy the next SOV clause's
|
|
33
|
+
// optional destination group (behavior-draggable's add captured
|
|
34
|
+
// destination=문서 instead of the schema `me` default). A real Korean
|
|
35
|
+
// destination renders 에/으로/로/의.
|
|
36
|
+
destination: { primary: '에', alternatives: ['으로', '로', '의'], position: 'after' },
|
|
37
|
+
source: { primary: '에서', alternatives: ['부터'], position: 'after' },
|
|
38
|
+
style: { primary: '로', alternatives: ['으로'], position: 'after' },
|
|
39
|
+
event: { primary: '을', alternatives: ['를'], position: 'after' }, // Event as object marker
|
|
40
|
+
},
|
|
41
|
+
tokenization: {
|
|
42
|
+
particles: ['을', '를', '이', '가', '은', '는', '에', '에서', '으로', '로', '와', '과', '도'],
|
|
43
|
+
boundaryStrategy: 'space',
|
|
44
|
+
},
|
|
45
|
+
// Korean writes a particle onto its noun (`#out에`, `나를`; M2 N5).
|
|
46
|
+
attachedMarkers: {
|
|
47
|
+
markers: ['을', '를', '에', '으로', '로', '의', '에서', '부터', '에게'],
|
|
48
|
+
afterWords: 'all',
|
|
49
|
+
},
|
|
50
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The language grammars: one data module per language, each reachable three
|
|
3
|
+
* ways that must agree — its file, the `languages` barrel, and a package
|
|
4
|
+
* export (`@lokascript/framework/languages/<code>`). tsup builds whatever the
|
|
5
|
+
* directory holds, so a module missing from package.json builds and ships
|
|
6
|
+
* unimportable; a barrel entry missing hides it from tooling.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from 'vitest';
|
|
9
|
+
import { readdirSync, readFileSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import * as languages from './index';
|
|
12
|
+
import type { GrammarProfile } from './types';
|
|
13
|
+
import type { GrammarProfileSlice } from '../multilingual';
|
|
14
|
+
import { buildLanguageConfig } from '../multilingual';
|
|
15
|
+
|
|
16
|
+
const DIR = __dirname;
|
|
17
|
+
const codes = readdirSync(DIR)
|
|
18
|
+
.filter(
|
|
19
|
+
f => f.endsWith('.ts') && !f.endsWith('.test.ts') && !['index.ts', 'types.ts'].includes(f)
|
|
20
|
+
)
|
|
21
|
+
.map(f => f.slice(0, -3))
|
|
22
|
+
.sort();
|
|
23
|
+
const grammars = Object.values(languages) as GrammarProfile[];
|
|
24
|
+
|
|
25
|
+
describe('language grammars', () => {
|
|
26
|
+
it('exports each module from the barrel, under its own code', () => {
|
|
27
|
+
expect(grammars.map(g => g.code).sort()).toEqual(codes);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('exports each module from the package, and nothing else under ./languages/', () => {
|
|
31
|
+
const pkg = JSON.parse(readFileSync(join(DIR, '../../package.json'), 'utf8'));
|
|
32
|
+
const exported = Object.keys(pkg.exports)
|
|
33
|
+
.filter(k => k.startsWith('./languages/'))
|
|
34
|
+
.map(k => k.slice('./languages/'.length))
|
|
35
|
+
.sort();
|
|
36
|
+
expect(exported).toEqual(codes);
|
|
37
|
+
// `require` too: semantic's dist/index.cjs requires each module.
|
|
38
|
+
for (const key of ['./languages', ...exported.map(code => `./languages/${code}`)]) {
|
|
39
|
+
expect(Object.keys(pkg.exports[key]), key).toEqual(['types', 'import', 'require']);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it.each(codes)('%s: is data (no imports but types)', code => {
|
|
44
|
+
const source = readFileSync(join(DIR, `${code}.ts`), 'utf8');
|
|
45
|
+
const imports = source.match(/^import .*$/gm) ?? [];
|
|
46
|
+
expect(imports).toEqual(["import type { GrammarProfile } from './types';"]);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('injects into the bridge as a slice', () => {
|
|
50
|
+
for (const grammar of grammars) {
|
|
51
|
+
const slice: GrammarProfileSlice = grammar;
|
|
52
|
+
const config = buildLanguageConfig(slice, { keywords: { go: { primary: 'go' } } });
|
|
53
|
+
expect(config.code).toBe(grammar.code);
|
|
54
|
+
expect(config.patternProfile.wordOrder).toBe(grammar.wordOrder);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Malay Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, space-separated.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { GrammarProfile } from './types';
|
|
8
|
+
|
|
9
|
+
export const malayGrammar = {
|
|
10
|
+
code: 'ms',
|
|
11
|
+
name: 'Malay',
|
|
12
|
+
nativeName: 'Melayu',
|
|
13
|
+
direction: 'ltr',
|
|
14
|
+
script: 'latin',
|
|
15
|
+
wordOrder: 'SVO',
|
|
16
|
+
markingStrategy: 'preposition',
|
|
17
|
+
usesSpaces: true,
|
|
18
|
+
defaultVerbForm: 'base',
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'start',
|
|
21
|
+
subjectDrop: true,
|
|
22
|
+
},
|
|
23
|
+
possessive: {
|
|
24
|
+
marker: '', // Malay often uses suffix or juxtaposition
|
|
25
|
+
markerPosition: 'after-object',
|
|
26
|
+
},
|
|
27
|
+
roleMarkers: {
|
|
28
|
+
destination: { primary: 'ke', alternatives: ['pada'], position: 'before' },
|
|
29
|
+
source: { primary: 'dari', position: 'before' },
|
|
30
|
+
patient: { primary: '', position: 'before' },
|
|
31
|
+
style: { primary: 'dengan', position: 'before' },
|
|
32
|
+
},
|
|
33
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polish Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, space-separated.
|
|
5
|
+
* Polish is a fusional language with rich verb conjugation.
|
|
6
|
+
* Unlike most languages, Polish software UI uses IMPERATIVE form.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { GrammarProfile } from './types';
|
|
10
|
+
|
|
11
|
+
export const polishGrammar = {
|
|
12
|
+
code: 'pl',
|
|
13
|
+
name: 'Polish',
|
|
14
|
+
nativeName: 'Polski',
|
|
15
|
+
direction: 'ltr',
|
|
16
|
+
script: 'latin',
|
|
17
|
+
wordOrder: 'SVO',
|
|
18
|
+
markingStrategy: 'preposition',
|
|
19
|
+
usesSpaces: true,
|
|
20
|
+
// Polish uses imperative form for commands in software UI
|
|
21
|
+
// (unlike most languages that use infinitive)
|
|
22
|
+
defaultVerbForm: 'imperative',
|
|
23
|
+
verb: {
|
|
24
|
+
position: 'start',
|
|
25
|
+
subjectDrop: true,
|
|
26
|
+
suffixes: ['ać', 'eć', 'ić', 'yć', 'ąć', 'ować'],
|
|
27
|
+
},
|
|
28
|
+
possessive: {
|
|
29
|
+
marker: '', // Polish uses genitive case, not a marker
|
|
30
|
+
markerPosition: 'after-object',
|
|
31
|
+
usePossessiveAdjectives: true,
|
|
32
|
+
},
|
|
33
|
+
roleMarkers: {
|
|
34
|
+
destination: { primary: 'do', alternatives: ['w', 'na', 'we'], position: 'before' },
|
|
35
|
+
source: { primary: 'z', alternatives: ['od', 'ze'], position: 'before' },
|
|
36
|
+
patient: { primary: '', position: 'before' },
|
|
37
|
+
style: { primary: 'z', alternatives: ['ze'], position: 'before' },
|
|
38
|
+
},
|
|
39
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portuguese Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, space-separated.
|
|
5
|
+
* Features rich verb conjugation with pro-drop (subject omission).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { GrammarProfile } from './types';
|
|
9
|
+
|
|
10
|
+
export const portugueseGrammar = {
|
|
11
|
+
code: 'pt',
|
|
12
|
+
name: 'Portuguese',
|
|
13
|
+
nativeName: 'Português',
|
|
14
|
+
direction: 'ltr',
|
|
15
|
+
script: 'latin',
|
|
16
|
+
wordOrder: 'SVO',
|
|
17
|
+
markingStrategy: 'preposition',
|
|
18
|
+
usesSpaces: true,
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'start',
|
|
21
|
+
subjectDrop: true,
|
|
22
|
+
},
|
|
23
|
+
possessive: {
|
|
24
|
+
marker: 'de', // Uses "de" for general possession
|
|
25
|
+
markerPosition: 'before-property',
|
|
26
|
+
usePossessiveAdjectives: true,
|
|
27
|
+
},
|
|
28
|
+
roleMarkers: {
|
|
29
|
+
destination: { primary: 'em', alternatives: ['para', 'a'], position: 'before' },
|
|
30
|
+
source: { primary: 'de', alternatives: ['desde'], position: 'before' },
|
|
31
|
+
patient: { primary: '', position: 'before' },
|
|
32
|
+
style: { primary: 'com', position: 'before' },
|
|
33
|
+
},
|
|
34
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quechua Grammar
|
|
3
|
+
*
|
|
4
|
+
* SOV word order, postpositions (suffixes), polysynthetic/agglutinative.
|
|
5
|
+
* Indigenous language of the Andean region with rich morphology.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { GrammarProfile } from './types';
|
|
9
|
+
|
|
10
|
+
export const quechuaGrammar = {
|
|
11
|
+
code: 'qu',
|
|
12
|
+
name: 'Quechua',
|
|
13
|
+
nativeName: 'Runasimi',
|
|
14
|
+
direction: 'ltr',
|
|
15
|
+
script: 'latin',
|
|
16
|
+
wordOrder: 'SOV',
|
|
17
|
+
markingStrategy: 'postposition',
|
|
18
|
+
usesSpaces: true,
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'end',
|
|
21
|
+
subjectDrop: true,
|
|
22
|
+
},
|
|
23
|
+
possessive: {
|
|
24
|
+
marker: '-pa', // Genitive suffix
|
|
25
|
+
markerPosition: 'after-object',
|
|
26
|
+
},
|
|
27
|
+
roleMarkers: {
|
|
28
|
+
patient: { primary: 'ta', position: 'after' },
|
|
29
|
+
destination: { primary: 'man', alternatives: ['pa'], position: 'after' },
|
|
30
|
+
source: { primary: 'manta', position: 'after' },
|
|
31
|
+
style: { primary: 'wan', position: 'after' },
|
|
32
|
+
event: { primary: 'pi', position: 'after' }, // Locative: event occurs "at" (pi)
|
|
33
|
+
},
|
|
34
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Russian Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, space-separated.
|
|
5
|
+
* Russian is a fusional language with rich verb conjugation.
|
|
6
|
+
* Uses infinitive form in software UI (industry standard).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { GrammarProfile } from './types';
|
|
10
|
+
|
|
11
|
+
export const russianGrammar = {
|
|
12
|
+
code: 'ru',
|
|
13
|
+
name: 'Russian',
|
|
14
|
+
nativeName: 'Русский',
|
|
15
|
+
direction: 'ltr',
|
|
16
|
+
script: 'cyrillic',
|
|
17
|
+
wordOrder: 'SVO',
|
|
18
|
+
markingStrategy: 'preposition',
|
|
19
|
+
usesSpaces: true,
|
|
20
|
+
defaultVerbForm: 'infinitive',
|
|
21
|
+
verb: {
|
|
22
|
+
position: 'start',
|
|
23
|
+
subjectDrop: true,
|
|
24
|
+
suffixes: ['ть', 'ться', 'ить', 'иться', 'ать', 'аться', 'еть', 'еться'],
|
|
25
|
+
},
|
|
26
|
+
possessive: {
|
|
27
|
+
marker: '',
|
|
28
|
+
markerPosition: 'after-object',
|
|
29
|
+
usePossessiveAdjectives: true,
|
|
30
|
+
},
|
|
31
|
+
roleMarkers: {
|
|
32
|
+
destination: { primary: 'в', alternatives: ['на', 'к', 'во', 'ко'], position: 'before' },
|
|
33
|
+
source: { primary: 'из', alternatives: ['от', 'с'], position: 'before' },
|
|
34
|
+
patient: { primary: '', position: 'before' },
|
|
35
|
+
style: { primary: 'с', alternatives: ['со'], position: 'before' },
|
|
36
|
+
},
|
|
37
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swahili Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, space-separated, agglutinative.
|
|
5
|
+
* Features noun class system (18 classes) and verb agreement prefixes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { GrammarProfile } from './types';
|
|
9
|
+
|
|
10
|
+
export const swahiliGrammar = {
|
|
11
|
+
code: 'sw',
|
|
12
|
+
name: 'Swahili',
|
|
13
|
+
nativeName: 'Kiswahili',
|
|
14
|
+
direction: 'ltr',
|
|
15
|
+
script: 'latin',
|
|
16
|
+
wordOrder: 'SVO',
|
|
17
|
+
markingStrategy: 'preposition',
|
|
18
|
+
usesSpaces: true,
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'start',
|
|
21
|
+
subjectDrop: true,
|
|
22
|
+
},
|
|
23
|
+
possessive: {
|
|
24
|
+
marker: '', // Swahili uses possessive pronouns
|
|
25
|
+
markerPosition: 'after-object',
|
|
26
|
+
usePossessiveAdjectives: true,
|
|
27
|
+
},
|
|
28
|
+
roleMarkers: {
|
|
29
|
+
destination: { primary: 'kwenye', alternatives: ['kwa'], position: 'before' },
|
|
30
|
+
source: { primary: 'kutoka', position: 'before' },
|
|
31
|
+
patient: { primary: '', position: 'before' },
|
|
32
|
+
style: { primary: 'na', position: 'before' },
|
|
33
|
+
},
|
|
34
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thai Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, Thai script.
|
|
5
|
+
* Isolating language (like Chinese) with no inflection.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { GrammarProfile } from './types';
|
|
9
|
+
|
|
10
|
+
export const thaiGrammar = {
|
|
11
|
+
code: 'th',
|
|
12
|
+
name: 'Thai',
|
|
13
|
+
nativeName: 'ไทย',
|
|
14
|
+
direction: 'ltr',
|
|
15
|
+
script: 'thai',
|
|
16
|
+
wordOrder: 'SVO',
|
|
17
|
+
markingStrategy: 'preposition',
|
|
18
|
+
usesSpaces: false, // Thai doesn't use spaces between words
|
|
19
|
+
defaultVerbForm: 'base',
|
|
20
|
+
verb: {
|
|
21
|
+
position: 'second',
|
|
22
|
+
subjectDrop: true,
|
|
23
|
+
},
|
|
24
|
+
possessive: {
|
|
25
|
+
marker: 'ของ',
|
|
26
|
+
markerPosition: 'between',
|
|
27
|
+
},
|
|
28
|
+
roleMarkers: {
|
|
29
|
+
patient: { primary: '', position: 'before' }, // Thai is isolating - no case markers
|
|
30
|
+
destination: { primary: 'ใน', alternatives: ['ไปยัง'], position: 'before' },
|
|
31
|
+
source: { primary: 'จาก', position: 'before' },
|
|
32
|
+
style: { primary: 'ด้วย', position: 'before' },
|
|
33
|
+
// No `event` role marker: a command's event argument (`trigger foo` /
|
|
34
|
+
// `send foo`) is an UNMARKED object in Thai, like every other SVO profile
|
|
35
|
+
// (es/zh/id/…). `เมื่อ` is the temporal "when/on" marker and belongs only on
|
|
36
|
+
// the event-HANDLER head — which uses `eventHandler.eventMarker` (below),
|
|
37
|
+
// not this role marker. Carrying it here generated `ทริกเกอร์ เมื่อ {event}`,
|
|
38
|
+
// which never matched the transformer's `ทริกเกอร์ {event}` → trigger/send
|
|
39
|
+
// dropped (th behavior-draggable/removable/resizable/sortable lossy).
|
|
40
|
+
},
|
|
41
|
+
tokenization: {
|
|
42
|
+
boundaryStrategy: 'character', // Character-based like Chinese/Japanese
|
|
43
|
+
},
|
|
44
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tagalog Grammar
|
|
3
|
+
*
|
|
4
|
+
* VSO word order, prepositions, space-separated.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { GrammarProfile } from './types';
|
|
8
|
+
|
|
9
|
+
export const tagalogGrammar = {
|
|
10
|
+
code: 'tl',
|
|
11
|
+
name: 'Tagalog',
|
|
12
|
+
nativeName: 'Tagalog',
|
|
13
|
+
direction: 'ltr',
|
|
14
|
+
script: 'latin',
|
|
15
|
+
wordOrder: 'VSO',
|
|
16
|
+
markingStrategy: 'preposition',
|
|
17
|
+
usesSpaces: true,
|
|
18
|
+
defaultVerbForm: 'base',
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'start',
|
|
21
|
+
subjectDrop: true,
|
|
22
|
+
},
|
|
23
|
+
possessive: {
|
|
24
|
+
marker: 'ng', // Linker used in possessive constructions
|
|
25
|
+
markerPosition: 'between',
|
|
26
|
+
},
|
|
27
|
+
roleMarkers: {
|
|
28
|
+
// `bago` (before) / `matapos` (after) are positional destination markers for
|
|
29
|
+
// `put X before/after Y`, mirroring how Arabic lists قبل/بعد as destination
|
|
30
|
+
// alternatives. Without them the generated put pattern can't match a
|
|
31
|
+
// before/after target.
|
|
32
|
+
destination: { primary: 'sa', alternatives: ['bago', 'matapos'], position: 'before' }, // "to/into"
|
|
33
|
+
source: { primary: 'mula_sa', position: 'before' }, // "from"
|
|
34
|
+
patient: { primary: '', position: 'before' },
|
|
35
|
+
style: { primary: 'nang', position: 'before' }, // manner marker
|
|
36
|
+
},
|
|
37
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turkish Grammar
|
|
3
|
+
*
|
|
4
|
+
* SOV word order, case suffixes (agglutinative), space-separated.
|
|
5
|
+
* Features vowel harmony and extensive suffixation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { GrammarProfile } from './types';
|
|
9
|
+
|
|
10
|
+
export const turkishGrammar = {
|
|
11
|
+
code: 'tr',
|
|
12
|
+
name: 'Turkish',
|
|
13
|
+
nativeName: 'Türkçe',
|
|
14
|
+
direction: 'ltr',
|
|
15
|
+
script: 'latin',
|
|
16
|
+
wordOrder: 'SOV',
|
|
17
|
+
markingStrategy: 'case-suffix',
|
|
18
|
+
usesSpaces: true,
|
|
19
|
+
verb: {
|
|
20
|
+
position: 'end',
|
|
21
|
+
suffixes: ['mek', 'mak', 'yor', 'di', 'miş'],
|
|
22
|
+
subjectDrop: true,
|
|
23
|
+
},
|
|
24
|
+
// The locative written onto a Turkish word, in the form its harmony gives
|
|
25
|
+
// (`tıklamada`, `değişiklikte`; M2 N4). Code keeps its suffix apart
|
|
26
|
+
// (`keyup da`) until a reviewer picks a code word's harmony (FUSED_FORMS.md
|
|
27
|
+
// Q2); the other case suffixes stay apart on code for the same reason.
|
|
28
|
+
attachedMarkers: { markers: ['da', 'de', 'ta', 'te'] },
|
|
29
|
+
possessive: {
|
|
30
|
+
// Genitive suffix, spaced for tokenization like Turkish's other case
|
|
31
|
+
// markers (i/e/de). i18n renders `#picker ın değer`; the parser matches
|
|
32
|
+
// `ın` as the possessive marker. Vowel-harmony variants (in/un/ün) are not
|
|
33
|
+
// distinguished — the generator emits the `ın` form for all owners.
|
|
34
|
+
marker: 'ın',
|
|
35
|
+
markerPosition: 'after-object',
|
|
36
|
+
usePossessiveAdjectives: true,
|
|
37
|
+
},
|
|
38
|
+
roleMarkers: {
|
|
39
|
+
patient: {
|
|
40
|
+
primary: 'i',
|
|
41
|
+
alternatives: ['ı', 'u', 'ü', 'yi', 'yı', 'yu', 'yü', 'ni', 'nı', 'nu', 'nü'],
|
|
42
|
+
position: 'after',
|
|
43
|
+
}, // Accusative (with buffer consonants y/n)
|
|
44
|
+
destination: {
|
|
45
|
+
primary: 'e',
|
|
46
|
+
// Include both dative (e/a) and genitive (ın/in/un/ün) for possessive patterns
|
|
47
|
+
// Genitive is used in "X's Y" patterns: #button ın .active = "#button's .active"
|
|
48
|
+
alternatives: [
|
|
49
|
+
'a',
|
|
50
|
+
'ye',
|
|
51
|
+
'ya',
|
|
52
|
+
'ne',
|
|
53
|
+
'na',
|
|
54
|
+
'de',
|
|
55
|
+
'da',
|
|
56
|
+
'te',
|
|
57
|
+
'ta',
|
|
58
|
+
'ın',
|
|
59
|
+
'in',
|
|
60
|
+
'un',
|
|
61
|
+
'ün',
|
|
62
|
+
'nın',
|
|
63
|
+
'nin',
|
|
64
|
+
'nun',
|
|
65
|
+
'nün',
|
|
66
|
+
],
|
|
67
|
+
position: 'after',
|
|
68
|
+
}, // Dative/Locative + Genitive (with buffer consonants)
|
|
69
|
+
source: { primary: 'den', alternatives: ['dan', 'ten', 'tan'], position: 'after' }, // Ablative
|
|
70
|
+
// `ile` is the free-standing instrumental the transformer actually emits
|
|
71
|
+
// for with-phrases (`getir method:"POST" body:form ile`); the suffix
|
|
72
|
+
// forms cover hand-written agglutinated variants.
|
|
73
|
+
style: { primary: 'le', alternatives: ['la', 'yle', 'yla', 'ile'], position: 'after' }, // Instrumental
|
|
74
|
+
event: { primary: 'i', alternatives: ['ı', 'u', 'ü'], position: 'after' }, // Event as accusative
|
|
75
|
+
},
|
|
76
|
+
} satisfies GrammarProfile;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A language's grammar: the facts that hold for it whatever a DSL says in it.
|
|
3
|
+
*
|
|
4
|
+
* `@lokascript/semantic`'s `LanguageProfile` spreads one of these and adds
|
|
5
|
+
* hyperscript's vocabulary (keywords, references, event-handler words); a
|
|
6
|
+
* domain injects one into the bridge builders (`./multilingual`) with its own
|
|
7
|
+
* vocabulary. Each `languages/<code>` module exports one, as data: no
|
|
8
|
+
* registration, no side effects.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Word order in a language (for declarative statements).
|
|
13
|
+
*/
|
|
14
|
+
export type WordOrder = 'SVO' | 'SOV' | 'VSO' | 'VOS' | 'OSV' | 'OVS';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* How grammatical relationships are marked.
|
|
18
|
+
*/
|
|
19
|
+
export type MarkingStrategy = 'preposition' | 'postposition' | 'particle' | 'case-suffix';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Writing system used by a language.
|
|
23
|
+
* Non-latin scripts require AsciiIdentifierExtractor in their tokenizer
|
|
24
|
+
* to handle mixed-script input (e.g., Arabic verb + CSS property name).
|
|
25
|
+
*/
|
|
26
|
+
export type ScriptType =
|
|
27
|
+
'latin' | 'cyrillic' | 'arabic' | 'cjk' | 'devanagari' | 'hangul' | 'bengali' | 'thai' | 'hebrew';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A grammatical marker (preposition, particle, etc.) for a semantic role.
|
|
31
|
+
*/
|
|
32
|
+
export interface RoleMarker {
|
|
33
|
+
/** Primary marker for this role */
|
|
34
|
+
readonly primary: string;
|
|
35
|
+
/** Alternative markers that also work */
|
|
36
|
+
readonly alternatives?: string[];
|
|
37
|
+
/** Position relative to the role value */
|
|
38
|
+
readonly position: 'before' | 'after';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Verb form configuration for a language.
|
|
43
|
+
*/
|
|
44
|
+
export interface VerbConfig {
|
|
45
|
+
/** Position of verb in the sentence */
|
|
46
|
+
readonly position: 'start' | 'end' | 'second';
|
|
47
|
+
/** Common verb suffixes/conjugations to recognize */
|
|
48
|
+
readonly suffixes?: string[];
|
|
49
|
+
/** Whether the language commonly drops subjects */
|
|
50
|
+
readonly subjectDrop?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Verb form used for command keywords.
|
|
55
|
+
*
|
|
56
|
+
* Based on software localization research:
|
|
57
|
+
* - 'infinitive': Standard for most languages (Spanish, French, German, Russian)
|
|
58
|
+
* Example: "Guardar", "Enregistrer", "Speichern"
|
|
59
|
+
* - 'imperative': Used by some languages (Polish)
|
|
60
|
+
* Example: "Zapisz", "Otwórz"
|
|
61
|
+
* - 'base': For languages where forms are identical (English, Japanese, Korean)
|
|
62
|
+
* or where the distinction doesn't apply
|
|
63
|
+
*/
|
|
64
|
+
export type VerbForm = 'infinitive' | 'imperative' | 'base';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Special tokenization configuration.
|
|
68
|
+
*/
|
|
69
|
+
export interface TokenizationConfig {
|
|
70
|
+
/** Particles to recognize (for particle languages) */
|
|
71
|
+
readonly particles?: string[];
|
|
72
|
+
/** Prefixes to recognize (for prefixing languages) */
|
|
73
|
+
readonly prefixes?: string[];
|
|
74
|
+
/** Word boundary detection strategy */
|
|
75
|
+
readonly boundaryStrategy?: 'space' | 'particle' | 'character';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* How "X's Y" is built in a language. The possessive WORDS (my, your, its)
|
|
80
|
+
* are vocabulary, and stay with the DSL that names the references.
|
|
81
|
+
*/
|
|
82
|
+
export interface PossessiveGrammar {
|
|
83
|
+
/** Possessive marker (e.g., "'s" in English, "の" in Japanese) */
|
|
84
|
+
readonly marker: string;
|
|
85
|
+
/** Position of marker: 'after-object' (X's Y), 'between' (X の Y), 'before-property' */
|
|
86
|
+
readonly markerPosition: 'after-object' | 'between' | 'before-property';
|
|
87
|
+
/** Whether to use possessive adjectives instead of marker (e.g., Spanish mi/tu/su) */
|
|
88
|
+
readonly usePossessiveAdjectives?: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Role markers written onto the word before them, as the language writes its
|
|
93
|
+
* case particles (M2 N5): ko `#out에`, ja `#outに`, bn `#outকে`. `markers`
|
|
94
|
+
* attach after code (a selector, a variable, a string); `afterWords` also
|
|
95
|
+
* after a word of the language, where its spelling does not change the
|
|
96
|
+
* marker (`'all'`; bn lists `কে`, and its locative takes the word's form by
|
|
97
|
+
* its own rule: `ক্লিকে`, `জমাতে`). ko picks each particle's form by the
|
|
98
|
+
* word's final consonant (`나를`).
|
|
99
|
+
*/
|
|
100
|
+
export interface AttachedMarkers {
|
|
101
|
+
readonly markers: readonly string[];
|
|
102
|
+
readonly afterWords?: 'all' | readonly string[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* One language's grammar. A structural superset of the bridge's
|
|
107
|
+
* `GrammarProfileSlice`, so it injects into the builders as is.
|
|
108
|
+
*/
|
|
109
|
+
export interface GrammarProfile {
|
|
110
|
+
/** ISO 639-1 or BCP 47 language code (e.g., 'es' or 'en-US') */
|
|
111
|
+
readonly code: string;
|
|
112
|
+
/** Human-readable language name */
|
|
113
|
+
readonly name: string;
|
|
114
|
+
/** Native name */
|
|
115
|
+
readonly nativeName: string;
|
|
116
|
+
/** Text direction */
|
|
117
|
+
readonly direction: 'ltr' | 'rtl';
|
|
118
|
+
/** Writing system — non-latin scripts require AsciiIdentifierExtractor in their tokenizer */
|
|
119
|
+
readonly script: ScriptType;
|
|
120
|
+
/** Primary word order */
|
|
121
|
+
readonly wordOrder: WordOrder;
|
|
122
|
+
/** How this language marks grammatical roles */
|
|
123
|
+
readonly markingStrategy: MarkingStrategy;
|
|
124
|
+
/** Whether the language uses spaces between words */
|
|
125
|
+
readonly usesSpaces: boolean;
|
|
126
|
+
/** Markers for each semantic role */
|
|
127
|
+
readonly roleMarkers: { readonly [role: string]: RoleMarker | undefined };
|
|
128
|
+
/** Verb configuration */
|
|
129
|
+
readonly verb: VerbConfig;
|
|
130
|
+
/** Special tokenization notes */
|
|
131
|
+
readonly tokenization?: TokenizationConfig;
|
|
132
|
+
/**
|
|
133
|
+
* Default verb form for command keywords. Defaults to 'infinitive'.
|
|
134
|
+
*
|
|
135
|
+
* Based on software UI localization research:
|
|
136
|
+
* - 'infinitive': Spanish, French, German, Portuguese, Russian (industry standard)
|
|
137
|
+
* - 'imperative': Polish
|
|
138
|
+
* - 'base': English, Japanese, Korean (no distinction or same form)
|
|
139
|
+
*/
|
|
140
|
+
readonly defaultVerbForm?: VerbForm;
|
|
141
|
+
/** Role markers the language writes onto the word before them */
|
|
142
|
+
readonly attachedMarkers?: AttachedMarkers;
|
|
143
|
+
/** How the language builds "X's Y" */
|
|
144
|
+
readonly possessive?: PossessiveGrammar;
|
|
145
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ukrainian Grammar
|
|
3
|
+
*
|
|
4
|
+
* SVO word order, prepositions, space-separated.
|
|
5
|
+
* Ukrainian is a fusional language with rich verb conjugation.
|
|
6
|
+
* Uses infinitive form in software UI (industry standard).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { GrammarProfile } from './types';
|
|
10
|
+
|
|
11
|
+
export const ukrainianGrammar = {
|
|
12
|
+
code: 'uk',
|
|
13
|
+
name: 'Ukrainian',
|
|
14
|
+
nativeName: 'Українська',
|
|
15
|
+
direction: 'ltr',
|
|
16
|
+
script: 'cyrillic',
|
|
17
|
+
wordOrder: 'SVO',
|
|
18
|
+
markingStrategy: 'preposition',
|
|
19
|
+
usesSpaces: true,
|
|
20
|
+
defaultVerbForm: 'infinitive',
|
|
21
|
+
verb: {
|
|
22
|
+
position: 'start',
|
|
23
|
+
subjectDrop: true,
|
|
24
|
+
suffixes: ['ти', 'тися', 'ити', 'итися', 'ати', 'атися', 'іти', 'ітися'],
|
|
25
|
+
},
|
|
26
|
+
possessive: {
|
|
27
|
+
marker: '',
|
|
28
|
+
markerPosition: 'after-object',
|
|
29
|
+
usePossessiveAdjectives: true,
|
|
30
|
+
},
|
|
31
|
+
roleMarkers: {
|
|
32
|
+
destination: { primary: 'в', alternatives: ['на', 'до'], position: 'before' },
|
|
33
|
+
source: { primary: 'з', alternatives: ['від', 'із'], position: 'before' },
|
|
34
|
+
patient: { primary: '', position: 'before' },
|
|
35
|
+
style: { primary: 'з', alternatives: ['із'], position: 'before' },
|
|
36
|
+
},
|
|
37
|
+
} satisfies GrammarProfile;
|