@lokascript/semantic 1.0.0 → 1.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/dist/browser-ar.ar.global.js +2 -2
- package/dist/browser-core.core.global.js +2 -2
- package/dist/browser-de.de.global.js +2 -2
- package/dist/browser-east-asian.east-asian.global.js +2 -2
- package/dist/browser-en-tr.en-tr.global.js +2 -2
- package/dist/browser-en.en.global.js +2 -2
- package/dist/browser-es-en.es-en.global.js +2 -2
- package/dist/browser-es.es.global.js +2 -2
- package/dist/browser-fr.fr.global.js +2 -2
- package/dist/browser-id.id.global.js +2 -2
- package/dist/browser-ja.ja.global.js +2 -2
- package/dist/browser-ko.ko.global.js +2 -2
- package/dist/browser-lazy.lazy.global.js +2 -2
- package/dist/browser-priority.priority.global.js +2 -2
- package/dist/browser-pt.pt.global.js +2 -2
- package/dist/browser-qu.qu.global.js +2 -2
- package/dist/browser-sw.sw.global.js +2 -2
- package/dist/browser-tr.tr.global.js +2 -2
- package/dist/browser-western.western.global.js +2 -2
- package/dist/browser-zh.zh.global.js +2 -2
- package/dist/browser.global.js +2 -2
- package/dist/browser.global.js.map +1 -1
- package/dist/index.cjs +13042 -17462
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -5
- package/dist/index.d.ts +49 -5
- package/dist/index.js +14044 -18464
- package/dist/index.js.map +1 -1
- package/dist/languages/ar.d.ts +1 -1
- package/dist/languages/ar.js +31 -44
- package/dist/languages/ar.js.map +1 -1
- package/dist/languages/de.d.ts +1 -1
- package/dist/languages/de.js +14 -2
- package/dist/languages/de.js.map +1 -1
- package/dist/languages/en.d.ts +1 -1
- package/dist/languages/en.js +558 -12
- package/dist/languages/en.js.map +1 -1
- package/dist/languages/es.d.ts +1 -1
- package/dist/languages/es.js +16 -0
- package/dist/languages/es.js.map +1 -1
- package/dist/languages/fr.d.ts +1 -1
- package/dist/languages/fr.js +14 -2
- package/dist/languages/fr.js.map +1 -1
- package/dist/languages/id.d.ts +1 -1
- package/dist/languages/id.js +14 -2
- package/dist/languages/id.js.map +1 -1
- package/dist/languages/ja.d.ts +1 -1
- package/dist/languages/ja.js +18 -3
- package/dist/languages/ja.js.map +1 -1
- package/dist/languages/ko.d.ts +8 -1
- package/dist/languages/ko.js +75 -43
- package/dist/languages/ko.js.map +1 -1
- package/dist/languages/pt.d.ts +1 -1
- package/dist/languages/pt.js +17 -0
- package/dist/languages/pt.js.map +1 -1
- package/dist/languages/qu.d.ts +12 -1
- package/dist/languages/qu.js +77 -2
- package/dist/languages/qu.js.map +1 -1
- package/dist/languages/sw.d.ts +1 -1
- package/dist/languages/sw.js.map +1 -1
- package/dist/languages/tr.d.ts +9 -1
- package/dist/languages/tr.js +96 -72
- package/dist/languages/tr.js.map +1 -1
- package/dist/languages/zh.d.ts +1 -1
- package/dist/languages/zh.js +16 -0
- package/dist/languages/zh.js.map +1 -1
- package/dist/{types-C4dcj53L.d.ts → types-BY3Id07j.d.ts} +20 -5
- package/package.json +20 -29
- package/src/generators/command-schemas.ts +21 -10
- package/src/generators/event-handler-generator.ts +50 -44
- package/src/generators/language-profiles.ts +6 -0
- package/src/generators/pattern-generator.ts +883 -1
- package/src/generators/profiles/arabic.ts +19 -3
- package/src/generators/profiles/bengali.ts +12 -1
- package/src/generators/profiles/chinese.ts +15 -0
- package/src/generators/profiles/french.ts +12 -1
- package/src/generators/profiles/german.ts +12 -1
- package/src/generators/profiles/hebrew.ts +148 -0
- package/src/generators/profiles/hindi.ts +12 -1
- package/src/generators/profiles/index.ts +2 -0
- package/src/generators/profiles/indonesian.ts +12 -1
- package/src/generators/profiles/italian.ts +16 -0
- package/src/generators/profiles/japanese.ts +11 -2
- package/src/generators/profiles/korean.ts +15 -1
- package/src/generators/profiles/polish.ts +12 -0
- package/src/generators/profiles/portuguese.ts +16 -0
- package/src/generators/profiles/russian.ts +11 -0
- package/src/generators/profiles/spanish.ts +15 -0
- package/src/generators/profiles/spanishMexico.ts +176 -0
- package/src/generators/profiles/thai.ts +11 -0
- package/src/generators/profiles/turkish.ts +49 -7
- package/src/generators/profiles/types.ts +21 -5
- package/src/generators/profiles/ukrainian.ts +11 -0
- package/src/generators/profiles/vietnamese.ts +11 -0
- package/src/language-building-schema.ts +111 -0
- package/src/languages/_all.ts +5 -1
- package/src/languages/es-MX.ts +32 -0
- package/src/languages/he.ts +15 -0
- package/src/parser/pattern-matcher.ts +10 -1
- package/src/parser/semantic-parser.ts +3 -0
- package/src/patterns/add/ar.ts +3 -59
- package/src/patterns/add/index.ts +5 -1
- package/src/patterns/add/ja.ts +3 -81
- package/src/patterns/add/ko.ts +3 -62
- package/src/patterns/add/qu.ts +69 -0
- package/src/patterns/add/tr.ts +3 -59
- package/src/patterns/builders.ts +1 -0
- package/src/patterns/decrement/tr.ts +3 -36
- package/src/patterns/event-handler/ar.ts +3 -139
- package/src/patterns/event-handler/he.ts +15 -0
- package/src/patterns/event-handler/index.ts +5 -1
- package/src/patterns/event-handler/ja.ts +3 -106
- package/src/patterns/event-handler/ko.ts +3 -121
- package/src/patterns/event-handler/ms.ts +45 -20
- package/src/patterns/event-handler/tr.ts +3 -158
- package/src/patterns/get/ar.ts +3 -37
- package/src/patterns/get/ja.ts +3 -41
- package/src/patterns/get/ko.ts +3 -41
- package/src/patterns/grammar-transformed/ja.ts +3 -1701
- package/src/patterns/grammar-transformed/ko.ts +3 -1299
- package/src/patterns/grammar-transformed/tr.ts +3 -1055
- package/src/patterns/hide/ar.ts +3 -55
- package/src/patterns/hide/ja.ts +3 -57
- package/src/patterns/hide/ko.ts +3 -57
- package/src/patterns/hide/tr.ts +3 -53
- package/src/patterns/increment/tr.ts +3 -40
- package/src/patterns/put/ar.ts +3 -62
- package/src/patterns/put/ja.ts +3 -63
- package/src/patterns/put/ko.ts +3 -55
- package/src/patterns/put/tr.ts +3 -55
- package/src/patterns/remove/ar.ts +3 -59
- package/src/patterns/remove/index.ts +5 -1
- package/src/patterns/remove/ja.ts +3 -62
- package/src/patterns/remove/ko.ts +3 -66
- package/src/patterns/remove/qu.ts +69 -0
- package/src/patterns/remove/tr.ts +3 -66
- package/src/patterns/set/ar.ts +3 -72
- package/src/patterns/set/ja.ts +3 -74
- package/src/patterns/set/ko.ts +3 -73
- package/src/patterns/set/tr.ts +3 -95
- package/src/patterns/show/ar.ts +3 -55
- package/src/patterns/show/ja.ts +3 -57
- package/src/patterns/show/ko.ts +3 -61
- package/src/patterns/show/tr.ts +3 -53
- package/src/patterns/take/ar.ts +3 -39
- package/src/patterns/toggle/ar.ts +3 -49
- package/src/patterns/toggle/index.ts +5 -1
- package/src/patterns/toggle/ja.ts +3 -144
- package/src/patterns/toggle/ko.ts +3 -101
- package/src/patterns/toggle/qu.ts +90 -0
- package/src/patterns/toggle/tr.ts +3 -76
- package/src/registry.ts +179 -15
- package/src/tokenizers/arabic.ts +13 -46
- package/src/tokenizers/bengali.ts +2 -16
- package/src/tokenizers/he.ts +542 -0
- package/src/tokenizers/index.ts +1 -0
- package/src/tokenizers/japanese.ts +3 -1
- package/src/tokenizers/korean.ts +104 -48
- package/src/tokenizers/ms.ts +3 -0
- package/src/tokenizers/quechua.ts +101 -2
- package/src/tokenizers/turkish.ts +64 -69
- package/src/types.ts +13 -0
package/dist/languages/en.js
CHANGED
|
@@ -1644,7 +1644,8 @@ var putSchema = {
|
|
|
1644
1644
|
required: true,
|
|
1645
1645
|
expectedTypes: ["literal", "selector", "reference", "expression"],
|
|
1646
1646
|
svoPosition: 1,
|
|
1647
|
-
sovPosition:
|
|
1647
|
+
sovPosition: 1
|
|
1648
|
+
// SOV: patient comes first (を marker)
|
|
1648
1649
|
},
|
|
1649
1650
|
{
|
|
1650
1651
|
role: "destination",
|
|
@@ -1652,7 +1653,8 @@ var putSchema = {
|
|
|
1652
1653
|
required: true,
|
|
1653
1654
|
expectedTypes: ["selector", "reference"],
|
|
1654
1655
|
svoPosition: 2,
|
|
1655
|
-
sovPosition:
|
|
1656
|
+
sovPosition: 2
|
|
1657
|
+
// SOV: destination comes second (に/에/a marker)
|
|
1656
1658
|
}
|
|
1657
1659
|
],
|
|
1658
1660
|
// Runtime error documentation
|
|
@@ -1700,14 +1702,23 @@ var setSchema = {
|
|
|
1700
1702
|
role: "destination",
|
|
1701
1703
|
description: "The property or variable to set",
|
|
1702
1704
|
required: true,
|
|
1703
|
-
expectedTypes: ["selector", "reference"],
|
|
1705
|
+
expectedTypes: ["selector", "reference", "expression"],
|
|
1704
1706
|
svoPosition: 1,
|
|
1705
1707
|
sovPosition: 1,
|
|
1706
1708
|
// Override destination marker for English (remove 'on', use no marker)
|
|
1707
|
-
//
|
|
1709
|
+
// SOV languages swap markers: variable gets patient marker (を/를/i)
|
|
1710
|
+
// Arabic (VSO): no marker before variable
|
|
1708
1711
|
markerOverride: {
|
|
1709
|
-
en: ""
|
|
1712
|
+
en: "",
|
|
1710
1713
|
// No marker before destination in English: "set :x to 5"
|
|
1714
|
+
ja: "\u3092",
|
|
1715
|
+
// "x を 10 に 設定" - variable gets object marker
|
|
1716
|
+
ko: "\uB97C",
|
|
1717
|
+
// "x 를 10 으로 설정" - variable gets object marker
|
|
1718
|
+
tr: "i",
|
|
1719
|
+
// "x i 10 e ayarla" - variable gets accusative marker
|
|
1720
|
+
ar: ""
|
|
1721
|
+
// "عيّن x إلى 10" - no marker before variable
|
|
1711
1722
|
}
|
|
1712
1723
|
},
|
|
1713
1724
|
{
|
|
@@ -1718,7 +1729,8 @@ var setSchema = {
|
|
|
1718
1729
|
svoPosition: 2,
|
|
1719
1730
|
sovPosition: 2,
|
|
1720
1731
|
// Override patient marker for SVO languages with their native prepositions
|
|
1721
|
-
// SOV languages
|
|
1732
|
+
// SOV languages swap markers: value gets destination marker (に/으로/e)
|
|
1733
|
+
// Arabic (VSO): إلى preposition before value
|
|
1722
1734
|
markerOverride: {
|
|
1723
1735
|
en: "to",
|
|
1724
1736
|
// "set :x to 5"
|
|
@@ -1730,8 +1742,16 @@ var setSchema = {
|
|
|
1730
1742
|
// "définir x à 10"
|
|
1731
1743
|
de: "auf",
|
|
1732
1744
|
// "setze x auf 10"
|
|
1733
|
-
id: "ke"
|
|
1745
|
+
id: "ke",
|
|
1734
1746
|
// "atur x ke 10"
|
|
1747
|
+
ja: "\u306B",
|
|
1748
|
+
// "x を 10 に 設定" - value gets destination marker
|
|
1749
|
+
ko: "\uC73C\uB85C",
|
|
1750
|
+
// "x 를 10 으로 설정" - value gets manner/instrument marker
|
|
1751
|
+
tr: "e",
|
|
1752
|
+
// "x i 10 e ayarla" - value gets dative marker
|
|
1753
|
+
ar: "\u0625\u0644\u0649"
|
|
1754
|
+
// "عيّن x إلى 10" - value gets preposition "to"
|
|
1735
1755
|
}
|
|
1736
1756
|
}
|
|
1737
1757
|
],
|
|
@@ -2049,18 +2069,23 @@ var getCommandSchema = {
|
|
|
2049
2069
|
expectedTypes: ["selector", "reference", "expression"],
|
|
2050
2070
|
svoPosition: 1,
|
|
2051
2071
|
sovPosition: 2,
|
|
2052
|
-
//
|
|
2072
|
+
// Marker overrides for GET pattern
|
|
2073
|
+
// SOV languages use object markers, SVO languages have no marker
|
|
2053
2074
|
markerOverride: {
|
|
2054
2075
|
en: "",
|
|
2055
2076
|
es: "",
|
|
2056
2077
|
pt: "",
|
|
2057
2078
|
fr: "",
|
|
2058
2079
|
de: "",
|
|
2059
|
-
ja: "",
|
|
2080
|
+
ja: "\u3092",
|
|
2081
|
+
// Japanese object marker: #element を 取得
|
|
2060
2082
|
zh: "",
|
|
2061
|
-
ko: "",
|
|
2062
|
-
|
|
2063
|
-
|
|
2083
|
+
ko: "\uB97C",
|
|
2084
|
+
// Korean object marker: #element 를 가져오기
|
|
2085
|
+
ar: "\u0639\u0644\u0649",
|
|
2086
|
+
// Arabic preposition: احصل على #element
|
|
2087
|
+
tr: "i",
|
|
2088
|
+
// Turkish accusative: #element i al
|
|
2064
2089
|
id: ""
|
|
2065
2090
|
}
|
|
2066
2091
|
},
|
|
@@ -2881,9 +2906,530 @@ function generatePatternsForLanguage(profile, config = defaultConfig) {
|
|
|
2881
2906
|
}
|
|
2882
2907
|
const variants = generatePatternVariants(schema, profile, config);
|
|
2883
2908
|
patterns.push(...variants);
|
|
2909
|
+
if (profile.eventHandler?.eventMarker) {
|
|
2910
|
+
const eventHandlerPatterns = generateEventHandlerPatterns(schema, profile, config);
|
|
2911
|
+
patterns.push(...eventHandlerPatterns);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
return patterns;
|
|
2915
|
+
}
|
|
2916
|
+
function generateEventHandlerPatterns(commandSchema, profile, config = defaultConfig) {
|
|
2917
|
+
if (!profile.eventHandler || !profile.eventHandler.eventMarker) {
|
|
2918
|
+
return [];
|
|
2919
|
+
}
|
|
2920
|
+
const patterns = [];
|
|
2921
|
+
const eventMarker = profile.eventHandler.eventMarker;
|
|
2922
|
+
const keyword = profile.keywords[commandSchema.action];
|
|
2923
|
+
if (!keyword) {
|
|
2924
|
+
return [];
|
|
2925
|
+
}
|
|
2926
|
+
const requiredRoles = commandSchema.roles.filter((r) => r.required);
|
|
2927
|
+
const hasTwoRequiredRoles = requiredRoles.length === 2;
|
|
2928
|
+
if (profile.wordOrder === "SOV") {
|
|
2929
|
+
if (hasTwoRequiredRoles) {
|
|
2930
|
+
patterns.push(
|
|
2931
|
+
generateSOVTwoRoleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2932
|
+
);
|
|
2933
|
+
} else {
|
|
2934
|
+
patterns.push(
|
|
2935
|
+
generateSOVEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2936
|
+
);
|
|
2937
|
+
const markerWords = eventMarker.primary.split(/\s+/);
|
|
2938
|
+
const hasNoSpaceAlternative = eventMarker.alternatives?.some(
|
|
2939
|
+
(alt) => !alt.includes(" ") && alt.length > 1
|
|
2940
|
+
);
|
|
2941
|
+
if (markerWords.length > 1 && hasNoSpaceAlternative) {
|
|
2942
|
+
patterns.push(
|
|
2943
|
+
generateSOVCompactEventHandlerPattern(
|
|
2944
|
+
commandSchema,
|
|
2945
|
+
profile,
|
|
2946
|
+
keyword,
|
|
2947
|
+
eventMarker,
|
|
2948
|
+
config
|
|
2949
|
+
)
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2952
|
+
patterns.push(
|
|
2953
|
+
generateSOVSimpleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2954
|
+
);
|
|
2955
|
+
const temporalPattern = generateSOVTemporalEventHandlerPattern(
|
|
2956
|
+
commandSchema,
|
|
2957
|
+
profile,
|
|
2958
|
+
keyword,
|
|
2959
|
+
config
|
|
2960
|
+
);
|
|
2961
|
+
if (temporalPattern) {
|
|
2962
|
+
patterns.push(temporalPattern);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
} else if (profile.wordOrder === "VSO") {
|
|
2966
|
+
if (hasTwoRequiredRoles) {
|
|
2967
|
+
patterns.push(
|
|
2968
|
+
generateVSOTwoRoleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2969
|
+
);
|
|
2970
|
+
} else {
|
|
2971
|
+
patterns.push(
|
|
2972
|
+
generateVSOEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2973
|
+
);
|
|
2974
|
+
if (profile.eventHandler?.negationMarker) {
|
|
2975
|
+
patterns.push(
|
|
2976
|
+
generateVSONegatedEventHandlerPattern(
|
|
2977
|
+
commandSchema,
|
|
2978
|
+
profile,
|
|
2979
|
+
keyword,
|
|
2980
|
+
eventMarker,
|
|
2981
|
+
config
|
|
2982
|
+
)
|
|
2983
|
+
);
|
|
2984
|
+
}
|
|
2985
|
+
if (profile.tokenization?.prefixes) {
|
|
2986
|
+
patterns.push(
|
|
2987
|
+
generateVSOProcliticEventHandlerPattern(commandSchema, profile, keyword, config)
|
|
2988
|
+
);
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
} else {
|
|
2992
|
+
if (hasTwoRequiredRoles) {
|
|
2993
|
+
patterns.push(
|
|
2994
|
+
generateVSOTwoRoleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2995
|
+
);
|
|
2996
|
+
} else {
|
|
2997
|
+
patterns.push(
|
|
2998
|
+
generateVSOEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config)
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
2884
3001
|
}
|
|
2885
3002
|
return patterns;
|
|
2886
3003
|
}
|
|
3004
|
+
function generateSOVEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3005
|
+
const tokens = [];
|
|
3006
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3007
|
+
if (eventMarker.position === "after") {
|
|
3008
|
+
const markerWords = eventMarker.primary.split(/\s+/);
|
|
3009
|
+
if (markerWords.length > 1) {
|
|
3010
|
+
for (const word of markerWords) {
|
|
3011
|
+
tokens.push({ type: "literal", value: word });
|
|
3012
|
+
}
|
|
3013
|
+
} else {
|
|
3014
|
+
const markerToken = eventMarker.alternatives ? { type: "literal", value: eventMarker.primary, alternatives: eventMarker.alternatives } : { type: "literal", value: eventMarker.primary };
|
|
3015
|
+
tokens.push(markerToken);
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
const destMarker = profile.roleMarkers.destination;
|
|
3019
|
+
if (destMarker) {
|
|
3020
|
+
tokens.push({
|
|
3021
|
+
type: "group",
|
|
3022
|
+
optional: true,
|
|
3023
|
+
tokens: [
|
|
3024
|
+
{ type: "role", role: "destination", optional: true },
|
|
3025
|
+
destMarker.alternatives ? { type: "literal", value: destMarker.primary, alternatives: destMarker.alternatives } : { type: "literal", value: destMarker.primary }
|
|
3026
|
+
]
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3029
|
+
tokens.push({ type: "role", role: "patient", optional: false });
|
|
3030
|
+
const patientMarker = profile.roleMarkers.patient;
|
|
3031
|
+
if (patientMarker) {
|
|
3032
|
+
const patMarkerToken = patientMarker.alternatives ? { type: "literal", value: patientMarker.primary, alternatives: patientMarker.alternatives } : { type: "literal", value: patientMarker.primary };
|
|
3033
|
+
tokens.push(patMarkerToken);
|
|
3034
|
+
}
|
|
3035
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3036
|
+
tokens.push(verbToken);
|
|
3037
|
+
return {
|
|
3038
|
+
id: `${commandSchema.action}-event-${profile.code}-sov`,
|
|
3039
|
+
language: profile.code,
|
|
3040
|
+
command: "on",
|
|
3041
|
+
// This is an event handler pattern
|
|
3042
|
+
priority: (config.basePriority ?? 100) + 50,
|
|
3043
|
+
// Higher priority than simple commands
|
|
3044
|
+
template: {
|
|
3045
|
+
format: `{event} ${eventMarker.primary} {destination?} {patient} ${patientMarker?.primary || ""} ${keyword.primary}`,
|
|
3046
|
+
tokens
|
|
3047
|
+
},
|
|
3048
|
+
extraction: {
|
|
3049
|
+
action: { value: commandSchema.action },
|
|
3050
|
+
// Extract the wrapped command
|
|
3051
|
+
event: { fromRole: "event" },
|
|
3052
|
+
patient: { fromRole: "patient" },
|
|
3053
|
+
destination: { fromRole: "destination", default: { type: "reference", value: "me" } }
|
|
3054
|
+
}
|
|
3055
|
+
};
|
|
3056
|
+
}
|
|
3057
|
+
function generateSOVCompactEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3058
|
+
const tokens = [];
|
|
3059
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3060
|
+
const noSpaceAlternatives = eventMarker.alternatives?.filter((alt) => !alt.includes(" ") && alt.length > 1) || [];
|
|
3061
|
+
if (noSpaceAlternatives.length > 0) {
|
|
3062
|
+
tokens.push({
|
|
3063
|
+
type: "literal",
|
|
3064
|
+
value: noSpaceAlternatives[0],
|
|
3065
|
+
alternatives: noSpaceAlternatives.slice(1)
|
|
3066
|
+
});
|
|
3067
|
+
}
|
|
3068
|
+
const destMarker = profile.roleMarkers.destination;
|
|
3069
|
+
if (destMarker) {
|
|
3070
|
+
tokens.push({
|
|
3071
|
+
type: "group",
|
|
3072
|
+
optional: true,
|
|
3073
|
+
tokens: [
|
|
3074
|
+
{ type: "role", role: "destination", optional: true },
|
|
3075
|
+
destMarker.alternatives ? { type: "literal", value: destMarker.primary, alternatives: destMarker.alternatives } : { type: "literal", value: destMarker.primary }
|
|
3076
|
+
]
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
tokens.push({ type: "role", role: "patient", optional: false });
|
|
3080
|
+
const patientMarker = profile.roleMarkers.patient;
|
|
3081
|
+
if (patientMarker) {
|
|
3082
|
+
const patMarkerToken = patientMarker.alternatives ? { type: "literal", value: patientMarker.primary, alternatives: patientMarker.alternatives } : { type: "literal", value: patientMarker.primary };
|
|
3083
|
+
tokens.push(patMarkerToken);
|
|
3084
|
+
}
|
|
3085
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3086
|
+
tokens.push(verbToken);
|
|
3087
|
+
return {
|
|
3088
|
+
id: `${commandSchema.action}-event-${profile.code}-sov-compact`,
|
|
3089
|
+
language: profile.code,
|
|
3090
|
+
command: "on",
|
|
3091
|
+
// This is an event handler pattern
|
|
3092
|
+
priority: (config.basePriority ?? 100) + 52,
|
|
3093
|
+
// Slightly higher priority for compact forms
|
|
3094
|
+
template: {
|
|
3095
|
+
format: `{event}${noSpaceAlternatives[0] || ""} {patient} ${keyword.primary}`,
|
|
3096
|
+
tokens
|
|
3097
|
+
},
|
|
3098
|
+
extraction: {
|
|
3099
|
+
action: { value: commandSchema.action },
|
|
3100
|
+
// Extract the wrapped command
|
|
3101
|
+
event: { fromRole: "event" },
|
|
3102
|
+
patient: { fromRole: "patient" },
|
|
3103
|
+
destination: { fromRole: "destination", default: { type: "reference", value: "me" } }
|
|
3104
|
+
}
|
|
3105
|
+
};
|
|
3106
|
+
}
|
|
3107
|
+
function generateSOVSimpleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3108
|
+
const tokens = [];
|
|
3109
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3110
|
+
if (eventMarker.position === "after") {
|
|
3111
|
+
const markerWords = eventMarker.primary.split(/\s+/);
|
|
3112
|
+
if (markerWords.length > 1) {
|
|
3113
|
+
for (const word of markerWords) {
|
|
3114
|
+
tokens.push({ type: "literal", value: word });
|
|
3115
|
+
}
|
|
3116
|
+
} else {
|
|
3117
|
+
const markerToken = eventMarker.alternatives ? { type: "literal", value: eventMarker.primary, alternatives: eventMarker.alternatives } : { type: "literal", value: eventMarker.primary };
|
|
3118
|
+
tokens.push(markerToken);
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3122
|
+
tokens.push(verbToken);
|
|
3123
|
+
return {
|
|
3124
|
+
id: `${commandSchema.action}-event-${profile.code}-sov-simple`,
|
|
3125
|
+
language: profile.code,
|
|
3126
|
+
command: "on",
|
|
3127
|
+
priority: (config.basePriority ?? 100) + 48,
|
|
3128
|
+
// Lower than full pattern (50) but higher than base
|
|
3129
|
+
template: {
|
|
3130
|
+
format: `{event} ${eventMarker.primary} ${keyword.primary}`,
|
|
3131
|
+
tokens
|
|
3132
|
+
},
|
|
3133
|
+
extraction: {
|
|
3134
|
+
action: { value: commandSchema.action },
|
|
3135
|
+
event: { fromRole: "event" },
|
|
3136
|
+
patient: { default: { type: "reference", value: "me" } }
|
|
3137
|
+
// Default to 'me'
|
|
3138
|
+
}
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3141
|
+
function generateSOVTemporalEventHandlerPattern(commandSchema, profile, keyword, config) {
|
|
3142
|
+
const temporalMarkers = profile.eventHandler?.temporalMarkers;
|
|
3143
|
+
if (!temporalMarkers || temporalMarkers.length === 0) return null;
|
|
3144
|
+
const tokens = [];
|
|
3145
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3146
|
+
if (profile.possessive?.marker) {
|
|
3147
|
+
tokens.push({
|
|
3148
|
+
type: "group",
|
|
3149
|
+
optional: true,
|
|
3150
|
+
tokens: [{ type: "literal", value: profile.possessive.marker }]
|
|
3151
|
+
});
|
|
3152
|
+
}
|
|
3153
|
+
tokens.push({
|
|
3154
|
+
type: "literal",
|
|
3155
|
+
value: temporalMarkers[0],
|
|
3156
|
+
alternatives: temporalMarkers.slice(1)
|
|
3157
|
+
});
|
|
3158
|
+
tokens.push({ type: "role", role: "patient", optional: false });
|
|
3159
|
+
const patientMarker = profile.roleMarkers.patient;
|
|
3160
|
+
if (patientMarker?.primary) {
|
|
3161
|
+
const patMarkerToken = patientMarker.alternatives ? { type: "literal", value: patientMarker.primary, alternatives: patientMarker.alternatives } : { type: "literal", value: patientMarker.primary };
|
|
3162
|
+
tokens.push(patMarkerToken);
|
|
3163
|
+
}
|
|
3164
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3165
|
+
tokens.push(verbToken);
|
|
3166
|
+
return {
|
|
3167
|
+
id: `${commandSchema.action}-event-${profile.code}-sov-temporal`,
|
|
3168
|
+
language: profile.code,
|
|
3169
|
+
command: "on",
|
|
3170
|
+
priority: (config.basePriority ?? 100) + 49,
|
|
3171
|
+
// Between simple and full pattern
|
|
3172
|
+
template: {
|
|
3173
|
+
format: `{event} ${temporalMarkers[0]} {patient} ${keyword.primary}`,
|
|
3174
|
+
tokens
|
|
3175
|
+
},
|
|
3176
|
+
extraction: {
|
|
3177
|
+
action: { value: commandSchema.action },
|
|
3178
|
+
event: { fromRole: "event" },
|
|
3179
|
+
patient: { fromRole: "patient" }
|
|
3180
|
+
}
|
|
3181
|
+
};
|
|
3182
|
+
}
|
|
3183
|
+
function generateVSOEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3184
|
+
const tokens = [];
|
|
3185
|
+
if (eventMarker.position === "before") {
|
|
3186
|
+
const markerToken = eventMarker.alternatives ? { type: "literal", value: eventMarker.primary, alternatives: eventMarker.alternatives } : { type: "literal", value: eventMarker.primary };
|
|
3187
|
+
tokens.push(markerToken);
|
|
3188
|
+
}
|
|
3189
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3190
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3191
|
+
tokens.push(verbToken);
|
|
3192
|
+
tokens.push({ type: "role", role: "patient", optional: false });
|
|
3193
|
+
const destMarker = profile.roleMarkers.destination;
|
|
3194
|
+
if (destMarker) {
|
|
3195
|
+
tokens.push({
|
|
3196
|
+
type: "group",
|
|
3197
|
+
optional: true,
|
|
3198
|
+
tokens: [
|
|
3199
|
+
destMarker.alternatives ? { type: "literal", value: destMarker.primary, alternatives: destMarker.alternatives } : { type: "literal", value: destMarker.primary },
|
|
3200
|
+
{ type: "role", role: "destination", optional: true }
|
|
3201
|
+
]
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
return {
|
|
3205
|
+
id: `${commandSchema.action}-event-${profile.code}-vso`,
|
|
3206
|
+
language: profile.code,
|
|
3207
|
+
command: "on",
|
|
3208
|
+
// This is an event handler pattern
|
|
3209
|
+
priority: (config.basePriority ?? 100) + 50,
|
|
3210
|
+
// Higher priority than simple commands
|
|
3211
|
+
template: {
|
|
3212
|
+
format: `${eventMarker.primary} {event} ${keyword.primary} {patient} ${destMarker?.primary || ""} {destination?}`,
|
|
3213
|
+
tokens
|
|
3214
|
+
},
|
|
3215
|
+
extraction: {
|
|
3216
|
+
action: { value: commandSchema.action },
|
|
3217
|
+
// Extract the wrapped command
|
|
3218
|
+
event: { fromRole: "event" },
|
|
3219
|
+
patient: { fromRole: "patient" },
|
|
3220
|
+
destination: { fromRole: "destination", default: { type: "reference", value: "me" } }
|
|
3221
|
+
}
|
|
3222
|
+
};
|
|
3223
|
+
}
|
|
3224
|
+
function generateSOVTwoRoleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3225
|
+
const tokens = [];
|
|
3226
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3227
|
+
if (eventMarker.position === "after") {
|
|
3228
|
+
const markerWords = eventMarker.primary.split(/\s+/);
|
|
3229
|
+
if (markerWords.length > 1) {
|
|
3230
|
+
for (const word of markerWords) {
|
|
3231
|
+
tokens.push({ type: "literal", value: word });
|
|
3232
|
+
}
|
|
3233
|
+
} else {
|
|
3234
|
+
const markerToken = eventMarker.alternatives ? { type: "literal", value: eventMarker.primary, alternatives: eventMarker.alternatives } : { type: "literal", value: eventMarker.primary };
|
|
3235
|
+
tokens.push(markerToken);
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
const requiredRoles = commandSchema.roles.filter((r) => r.required);
|
|
3239
|
+
const sortedRoles = [...requiredRoles].sort((a, b) => {
|
|
3240
|
+
const aPos = a.sovPosition ?? 999;
|
|
3241
|
+
const bPos = b.sovPosition ?? 999;
|
|
3242
|
+
return aPos - bPos;
|
|
3243
|
+
});
|
|
3244
|
+
for (const roleSpec of sortedRoles) {
|
|
3245
|
+
tokens.push({ type: "role", role: roleSpec.role, optional: false });
|
|
3246
|
+
let marker;
|
|
3247
|
+
let markerAlternatives;
|
|
3248
|
+
if (roleSpec.markerOverride && roleSpec.markerOverride[profile.code]) {
|
|
3249
|
+
marker = roleSpec.markerOverride[profile.code];
|
|
3250
|
+
} else {
|
|
3251
|
+
const roleMarker = profile.roleMarkers[roleSpec.role];
|
|
3252
|
+
if (roleMarker) {
|
|
3253
|
+
marker = roleMarker.primary;
|
|
3254
|
+
markerAlternatives = roleMarker.alternatives;
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
if (marker) {
|
|
3258
|
+
const markerToken = markerAlternatives ? { type: "literal", value: marker, alternatives: markerAlternatives } : { type: "literal", value: marker };
|
|
3259
|
+
tokens.push(markerToken);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3263
|
+
tokens.push(verbToken);
|
|
3264
|
+
const roleNames = sortedRoles.map((r) => `{${r.role}}`).join(" ");
|
|
3265
|
+
return {
|
|
3266
|
+
id: `${commandSchema.action}-event-${profile.code}-sov-2role`,
|
|
3267
|
+
language: profile.code,
|
|
3268
|
+
command: "on",
|
|
3269
|
+
// This is an event handler pattern
|
|
3270
|
+
priority: (config.basePriority ?? 100) + 55,
|
|
3271
|
+
// Higher priority than single-role patterns
|
|
3272
|
+
template: {
|
|
3273
|
+
format: `{event} ${eventMarker.primary} ${roleNames} ${keyword.primary}`,
|
|
3274
|
+
tokens
|
|
3275
|
+
},
|
|
3276
|
+
extraction: {
|
|
3277
|
+
action: { value: commandSchema.action },
|
|
3278
|
+
// Extract the wrapped command
|
|
3279
|
+
event: { fromRole: "event" },
|
|
3280
|
+
patient: { fromRole: "patient" },
|
|
3281
|
+
destination: { fromRole: "destination" }
|
|
3282
|
+
}
|
|
3283
|
+
};
|
|
3284
|
+
}
|
|
3285
|
+
function generateVSOTwoRoleEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3286
|
+
const tokens = [];
|
|
3287
|
+
if (eventMarker.position === "before") {
|
|
3288
|
+
const markerToken = eventMarker.alternatives ? { type: "literal", value: eventMarker.primary, alternatives: eventMarker.alternatives } : { type: "literal", value: eventMarker.primary };
|
|
3289
|
+
tokens.push(markerToken);
|
|
3290
|
+
}
|
|
3291
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3292
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3293
|
+
tokens.push(verbToken);
|
|
3294
|
+
const requiredRoles = commandSchema.roles.filter((r) => r.required);
|
|
3295
|
+
const sortedRoles = [...requiredRoles].sort((a, b) => {
|
|
3296
|
+
const aPos = a.svoPosition ?? 999;
|
|
3297
|
+
const bPos = b.svoPosition ?? 999;
|
|
3298
|
+
return aPos - bPos;
|
|
3299
|
+
});
|
|
3300
|
+
for (const roleSpec of sortedRoles) {
|
|
3301
|
+
let marker;
|
|
3302
|
+
let markerAlternatives;
|
|
3303
|
+
if (roleSpec.markerOverride && roleSpec.markerOverride[profile.code]) {
|
|
3304
|
+
marker = roleSpec.markerOverride[profile.code];
|
|
3305
|
+
} else {
|
|
3306
|
+
const roleMarker = profile.roleMarkers[roleSpec.role];
|
|
3307
|
+
if (roleMarker) {
|
|
3308
|
+
marker = roleMarker.primary;
|
|
3309
|
+
markerAlternatives = roleMarker.alternatives;
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
if (marker) {
|
|
3313
|
+
const markerToken = markerAlternatives ? { type: "literal", value: marker, alternatives: markerAlternatives } : { type: "literal", value: marker };
|
|
3314
|
+
tokens.push(markerToken);
|
|
3315
|
+
}
|
|
3316
|
+
tokens.push({ type: "role", role: roleSpec.role, optional: false });
|
|
3317
|
+
}
|
|
3318
|
+
const roleNames = sortedRoles.map((r) => `{${r.role}}`).join(" ");
|
|
3319
|
+
return {
|
|
3320
|
+
id: `${commandSchema.action}-event-${profile.code}-vso-2role`,
|
|
3321
|
+
language: profile.code,
|
|
3322
|
+
command: "on",
|
|
3323
|
+
// This is an event handler pattern
|
|
3324
|
+
priority: (config.basePriority ?? 100) + 55,
|
|
3325
|
+
// Higher priority than single-role patterns
|
|
3326
|
+
template: {
|
|
3327
|
+
format: `${eventMarker.primary} {event} ${keyword.primary} ${roleNames}`,
|
|
3328
|
+
tokens
|
|
3329
|
+
},
|
|
3330
|
+
extraction: {
|
|
3331
|
+
action: { value: commandSchema.action },
|
|
3332
|
+
// Extract the wrapped command
|
|
3333
|
+
event: { fromRole: "event" },
|
|
3334
|
+
patient: { fromRole: "patient" },
|
|
3335
|
+
destination: { fromRole: "destination" }
|
|
3336
|
+
}
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
function generateVSONegatedEventHandlerPattern(commandSchema, profile, keyword, eventMarker, config) {
|
|
3340
|
+
const tokens = [];
|
|
3341
|
+
const negationMarker = profile.eventHandler?.negationMarker;
|
|
3342
|
+
if (eventMarker.position === "before") {
|
|
3343
|
+
const markerToken = eventMarker.alternatives ? { type: "literal", value: eventMarker.primary, alternatives: eventMarker.alternatives } : { type: "literal", value: eventMarker.primary };
|
|
3344
|
+
tokens.push(markerToken);
|
|
3345
|
+
}
|
|
3346
|
+
if (negationMarker) {
|
|
3347
|
+
const negToken = negationMarker.alternatives ? {
|
|
3348
|
+
type: "literal",
|
|
3349
|
+
value: negationMarker.primary,
|
|
3350
|
+
alternatives: negationMarker.alternatives
|
|
3351
|
+
} : { type: "literal", value: negationMarker.primary };
|
|
3352
|
+
tokens.push(negToken);
|
|
3353
|
+
}
|
|
3354
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3355
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3356
|
+
tokens.push(verbToken);
|
|
3357
|
+
tokens.push({ type: "role", role: "patient", optional: false });
|
|
3358
|
+
const destMarker = profile.roleMarkers.destination;
|
|
3359
|
+
if (destMarker) {
|
|
3360
|
+
tokens.push({
|
|
3361
|
+
type: "group",
|
|
3362
|
+
optional: true,
|
|
3363
|
+
tokens: [
|
|
3364
|
+
destMarker.alternatives ? { type: "literal", value: destMarker.primary, alternatives: destMarker.alternatives } : { type: "literal", value: destMarker.primary },
|
|
3365
|
+
{ type: "role", role: "destination", optional: true }
|
|
3366
|
+
]
|
|
3367
|
+
});
|
|
3368
|
+
}
|
|
3369
|
+
return {
|
|
3370
|
+
id: `${commandSchema.action}-event-${profile.code}-vso-negated`,
|
|
3371
|
+
language: profile.code,
|
|
3372
|
+
command: "on",
|
|
3373
|
+
// This is an event handler pattern
|
|
3374
|
+
priority: (config.basePriority ?? 100) + 48,
|
|
3375
|
+
// Slightly lower priority than standard patterns
|
|
3376
|
+
template: {
|
|
3377
|
+
format: `${eventMarker.primary} ${negationMarker?.primary || ""} {event} ${keyword.primary} {patient} ${destMarker?.primary || ""} {destination?}`,
|
|
3378
|
+
tokens
|
|
3379
|
+
},
|
|
3380
|
+
extraction: {
|
|
3381
|
+
action: { value: commandSchema.action },
|
|
3382
|
+
// Extract the wrapped command
|
|
3383
|
+
event: { fromRole: "event" },
|
|
3384
|
+
patient: { fromRole: "patient" },
|
|
3385
|
+
destination: { fromRole: "destination", default: { type: "reference", value: "me" } }
|
|
3386
|
+
}
|
|
3387
|
+
};
|
|
3388
|
+
}
|
|
3389
|
+
function generateVSOProcliticEventHandlerPattern(commandSchema, profile, keyword, config) {
|
|
3390
|
+
const tokens = [];
|
|
3391
|
+
tokens.push({
|
|
3392
|
+
type: "literal",
|
|
3393
|
+
value: "and",
|
|
3394
|
+
// Matches normalized 'and' (Arabic: و)
|
|
3395
|
+
alternatives: ["then"]
|
|
3396
|
+
// Also matches normalized 'then' (Arabic: ف)
|
|
3397
|
+
});
|
|
3398
|
+
tokens.push({ type: "role", role: "event", optional: false });
|
|
3399
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
3400
|
+
tokens.push(verbToken);
|
|
3401
|
+
tokens.push({ type: "role", role: "patient", optional: false });
|
|
3402
|
+
const destMarker = profile.roleMarkers.destination;
|
|
3403
|
+
if (destMarker) {
|
|
3404
|
+
tokens.push({
|
|
3405
|
+
type: "group",
|
|
3406
|
+
optional: true,
|
|
3407
|
+
tokens: [
|
|
3408
|
+
destMarker.alternatives ? { type: "literal", value: destMarker.primary, alternatives: destMarker.alternatives } : { type: "literal", value: destMarker.primary },
|
|
3409
|
+
{ type: "role", role: "destination", optional: true }
|
|
3410
|
+
]
|
|
3411
|
+
});
|
|
3412
|
+
}
|
|
3413
|
+
return {
|
|
3414
|
+
id: `${commandSchema.action}-event-${profile.code}-vso-proclitic`,
|
|
3415
|
+
language: profile.code,
|
|
3416
|
+
command: "on",
|
|
3417
|
+
// This is an event handler pattern
|
|
3418
|
+
priority: (config.basePriority ?? 100) + 45,
|
|
3419
|
+
// Lower priority than standard patterns
|
|
3420
|
+
template: {
|
|
3421
|
+
format: `[proclitic?] {event} ${keyword.primary} {patient} ${destMarker?.primary || ""} {destination?}`,
|
|
3422
|
+
tokens
|
|
3423
|
+
},
|
|
3424
|
+
extraction: {
|
|
3425
|
+
action: { value: commandSchema.action },
|
|
3426
|
+
// Extract the wrapped command
|
|
3427
|
+
event: { fromRole: "event" },
|
|
3428
|
+
patient: { fromRole: "patient" },
|
|
3429
|
+
destination: { fromRole: "destination", default: { type: "reference", value: "me" } }
|
|
3430
|
+
}
|
|
3431
|
+
};
|
|
3432
|
+
}
|
|
2887
3433
|
function buildTokens(schema, profile, keyword) {
|
|
2888
3434
|
const tokens = [];
|
|
2889
3435
|
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|