1 //deno-lint-ignore-file no-unused-vars
2 // ♓️🪡 सूत्र ∷ xsd/productions.js
3 // ====================================================================
5 // Copyright © 2023 Lady [@ Lady’s Computer].
7 // This Source Code Form is subject to the terms of the Mozilla Public
8 // License, v. 2.0. If a copy of the MPL was not distributed with this
9 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
19 const dayOfMonthValuesConstraint
= (day
, month
, year
= "1972") => {
23 return m
=== 4 || m
=== 6 || m
=== 9 || m
=== 11
25 : m
=== 2 && (y
% 4 || !(y
% 100) && y
% 400)
27 : m
=== 2 && (!(y
% 400) || !(y
% 4) && y
% 100)
33 /** `[1] stringRep ::= Char*` */
36 /** `[2] booleanRep ::= 'true' | 'false' | '1' | '0'` */
39 /** `[3] decimalLexicalRep ::= decimalPtNumeral | noDecimalPtNumeral` */
42 /** `[4] floatRep ::= noDecimalPtNumeral | decimalPtNumeral | scientificNotationNumeral | numericalSpecialRep` */
45 /** `[5] doubleRep ::= noDecimalPtNumeral | decimalPtNumeral | scientificNotationNumeral | numericalSpecialRep` */
48 /** `[6] duYearFrag ::= unsignedNoDecimalPtNumeral 'Y'` */
51 /** `[7] duMonthFrag ::= unsignedNoDecimalPtNumeral 'M'` */
54 /** `[8] duDayFrag ::= unsignedNoDecimalPtNumeral 'D'` */
57 /** `[9] duHourFrag ::= unsignedNoDecimalPtNumeral 'H'` */
60 /** `[10] duMinuteFrag ::= unsignedNoDecimalPtNumeral 'M'` */
64 * `[11] duSecondFrag ::= (unsignedNoDecimalPtNumeral | unsignedFullDecimalPtNumeral) 'S'`
66 * ※ The X·S·D specification specifies unsignedDecimalPtNumeral, not
67 * unsignedFullDecimalPtNumeral, but the specification text and
68 * provided regular expressions imply that the latter was intended.
72 /** `[12] duYearMonthFrag ::= (duYearFrag duMonthFrag?) | duMonthFrag` */
75 /** `[13] duTimeFrag ::= 'T' ((duHourFrag duMinuteFrag? duSecondFrag?) | (duMinuteFrag duSecondFrag?) | duSecondFrag)` */
78 /** `[14] duDayTimeFrag ::= (duDayFrag duTimeFrag?) | duTimeFrag` */
81 /** `[15] durationLexicalRep ::= '-'? 'P' ((duYearMonthFrag duDayTimeFrag?) | duDayTimeFrag)` */
85 * `[16] dateTimeLexicalRep ::= yearFrag '-' monthFrag '-' dayFrag 'T' ((hourFrag ':' minuteFrag ':' secondFrag) | endOfDayFrag) timezoneFrag?`
87 * **Constraint: Day-of-month Values**
89 * The ·day· value must be no more than 30 if ·month· is one of 4, 6,
90 * 9, or 11; no more than 28 if ·month· is 2 and ·year· is not
91 * divisible by 4, or is divisible by 100 but not by 400; and no more
92 * than 29 if ·month· is 2 and ·year· is divisible by 400, or by 4
95 * **Constraint: Day-of-month Representations**
97 * Within a dateTimeLexicalRep, a dayFrag must not begin with the
98 * digit '3' or be '29' unless the value to which it would map would
99 * satisfy the value constraint on ·day· values ("Constraint:
100 * Day-of-month Values") given above.
104 /** `[17] timeLexicalRep ::= ((hourFrag ':' minuteFrag ':' secondFrag) | endOfDayFrag) timezoneFrag?` */
108 * `[18] dateLexicalRep ::= yearFrag '-' monthFrag '-' dayFrag timezoneFrag?`
110 * **Constraint: Day-of-month Values**
112 * The ·day· value must be no more than 30 if ·month· is one of 4, 6,
113 * 9, or 11; no more than 28 if ·month· is 2 and ·year· is not
114 * divisible by 4, or is divisible by 100 but not by 400; and no more
115 * than 29 if ·month· is 2 and ·year· is divisible by 400, or by 4
118 * **Constraint: Day-of-month Representations**
120 * Within a dateLexicalRep, a dayFrag must not begin with the digit
121 * '3' or be '29' unless the value to which it would map would
122 * satisfy the value constraint on ·day· values ("Constraint:
123 * Day-of-month Values") given above.
127 /** `[19] gYearMonthLexicalRep ::= yearFrag '-' monthFrag timezoneFrag?` */
128 gYearMonthLexicalRep
,
130 /** `[20] gYearLexicalRep ::= yearFrag timezoneFrag?` */
134 * `[21] gMonthDayLexicalRep ::= '--' monthFrag '-' dayFrag timezoneFrag?`
136 * **Constraint: Day-of-month Values**
138 * The ·day· value must be no more than 30 if ·month· is one of 4, 6,
139 * 9, or 11, and no more than 29 if ·month· is 2.
141 * **Constraint: Day-of-month Representations**
143 * Within a gMonthDayLexicalRep, a dayFrag must not begin with the
144 * digit '3' or be '29' unless the value to which it would map would
145 * satisfy the value constraint on ·day· values ("Constraint:
146 * Day-of-month Values") given above.
150 /** `[22] gDayLexicalRep ::= '---' dayFrag timezoneFrag?` */
153 /** `[23] gMonthLexicalRep ::= '--' monthFrag timezoneFrag?` */
156 /** `[24] hexDigit ::= [0-9a-fA-F]` */
159 /** `[25] hexOctet ::= hexDigit hexDigit` */
162 /** `[26] hexBinary ::= hexOctet*` */
165 /** `[27] Base64Binary ::= (B64quad* B64final)?` */
168 /** `[28] B64quad ::= (B64 B64 B64 B64)` */
171 /** `[29] B64final ::= B64finalquad | Padded16 | Padded8` */
174 /** `[30] B64finalquad ::= (B64 B64 B64 B64char)` */
177 /** `[31] Padded16 ::= B64 B64 B16 '='` */
180 /** `[32] Padded8 ::= B64 B04 '=' #x20? '='` */
183 /** `[33] B64 ::= B64char #x20?` */
186 /** `[34] B64char ::= [A-Za-z0-9+/]` */
189 /** `[35] B16 ::= B16char #x20?` */
192 /** `[36] B16char ::= [AEIMQUYcgkosw048]` */
195 /** `[37] B04 ::= B04char #x20?` */
198 /** `[38] B04char ::= [AQgw]` */
201 /** `[39] Canonical-base64Binary ::= CanonicalQuad* CanonicalPadded?` */
202 Canonical
·base64Binary
,
204 /** `[40] CanonicalQuad ::= B64char B64char B64char B64char` */
207 /** `[41] CanonicalPadded ::= B64char B64char B16char '=' | B64char B04char '=='` */
210 /** `[42] yearMonthDurationLexicalRep ::= '-'? 'P' duYearMonthFrag` */
211 yearMonthDurationLexicalRep
,
213 /** `[43] dayTimeDurationLexicalRep ::= '-'? 'P' duDayTimeFrag` */
214 dayTimeDurationLexicalRep
,
217 * `[44] dateTimeStampLexicalRep ::= yearFrag '-' monthFrag '-' dayFrag 'T' ((hourFrag ':' minuteFrag ':' secondFrag) | endOfDayFrag) timezoneFrag`
219 * **Constraint: Day-of-month Values**
221 * The ·day· value must be no more than 30 if ·month· is one of 4, 6,
222 * 9, or 11; no more than 28 if ·month· is 2 and ·year· is not
223 * divisible by 4, or is divisible by 100 but not by 400; and no more
224 * than 29 if ·month· is 2 and ·year· is divisible by 400, or by 4
227 * **Constraint: Day-of-month Representations**
229 * Within a dateTimeStampLexicalRep, a dayFrag must not begin with
230 * the digit '3' or be '29' unless the value to which it would map
231 * would satisfy the value constraint on ·day· values ("Constraint:
232 * Day-of-month Values") given above.
234 dateTimeStampLexicalRep
,
236 /** `[45] digit ::= [0-9]` */
239 /** `[46] unsignedNoDecimalPtNumeral ::= digit+` */
240 unsignedNoDecimalPtNumeral
,
242 /** `[47] noDecimalPtNumeral ::= ('+' | '-')? unsignedNoDecimalPtNumeral` */
245 /** `[48] fracFrag ::= digit+` */
248 /** `[49] unsignedDecimalPtNumeral ::= (unsignedNoDecimalPtNumeral '.' fracFrag?) | ('.' fracFrag)` */
249 unsignedDecimalPtNumeral
,
251 /** `[50] unsignedFullDecimalPtNumeral ::= unsignedNoDecimalPtNumeral '.' fracFrag` */
252 unsignedFullDecimalPtNumeral
,
254 /** `[51] decimalPtNumeral ::= ('+' | '-')? unsignedDecimalPtNumeral` */
257 /** `[52] unsignedScientificNotationNumeral ::= (unsignedNoDecimalPtNumeral | unsignedDecimalPtNumeral) ('e' | 'E') noDecimalPtNumeral` */
258 unsignedScientificNotationNumeral
,
260 /** `[53] scientificNotationNumeral ::= ('+' | '-')? unsignedScientificNotationNumeral` */
261 scientificNotationNumeral
,
263 /** `[54] minimalNumericalSpecialRep ::= 'INF' | '-INF' | 'NaN'` */
264 minimalNumericalSpecialRep
,
266 /** `[55] numericalSpecialRep ::= ('+' | '-')? unsignedScientificNotationNumeral` */
269 /** `[56] yearFrag ::= '-'? (([1-9] digit digit digit+)) | ('0' digit digit digit))` */
272 /** `[57] monthFrag ::= ('0' [1-9]) | ('1' [0-2])` */
275 /** `[58] dayFrag ::= ('0' [1-9]) | ([12] digit) | ('3' [01])` */
278 /** `[59] hourFrag ::= ([01] digit) | ('2' [0-3])` */
281 /** `[60] minuteFrag ::= [0-5] digit` */
284 /** `[61] secondFrag ::= ([0-5] digit) ('.' digit+)?` */
287 /** `[62] endOfDayFrag ::= '24:00:00' ('.' '0'+)?` */
290 /** `[63] timezoneFrag ::= 'Z' | ('+' | '-') (('0' digit | '1' [0-3]) ':' minuteFrag | '14:00')` */
293 const matchers
= objectCreate(null);
295 (name
, constraint
= null) => (strings
, ...substitutions
) => {
296 const source
= `(?:${rawString(strings, ...substitutions)})`;
297 matchers
[name
] = new Matcher(`^${source}$`, name
, constraint
);
301 const stringRep
= match(
303 )`[^\u{0}\u{D800}-\u{DFFF}\u{FFFE}\u{FFFF}]*`;
304 const booleanRep
= match("booleanRep")`true|false|1|0`;
305 const digit
= match("digit")`[0-9]`;
306 const unsignedNoDecimalPtNumeral
= match(
307 "unsignedNoDecimalPtNumeral",
309 const noDecimalPtNumeral
= match(
310 "noDecimalPtNumeral",
311 )`[+-]?${unsignedNoDecimalPtNumeral}`;
312 const fracFrag
= match("fracFrag")`${digit}+`;
313 const unsignedDecimalPtNumeral
= match(
314 "unsignedDecimalPtNumeral",
315 )`${unsignedNoDecimalPtNumeral}\.${fracFrag}?|\.${fracFrag}`;
316 const unsignedFullDecimalPtNumeral
= match(
317 "unsignedFullDecimalPtNumeral",
318 )`${unsignedNoDecimalPtNumeral}\.${fracFrag}`;
319 const decimalPtNumeral
= match(
321 )`[+-]?${unsignedDecimalPtNumeral}`;
322 const unsignedScientificNotationNumeral
= match(
323 "unsignedScientificNotationNumeral",
324 )`(?:${unsignedNoDecimalPtNumeral}|${unsignedDecimalPtNumeral})[eE]${noDecimalPtNumeral}`;
325 const scientificNotationNumeral
= match(
326 "scientificNotationNumeral",
327 )`[+-]?${unsignedScientificNotationNumeral}`;
328 const minimalNumericalSpecialRep
= match(
329 "minimalNumericalSpecialRep",
331 const numericalSpecialRep
= match(
332 "numericalSpecialRep",
333 )`\+INF|${minimalNumericalSpecialRep}`;
334 const decimalLexicalRep
= match(
336 )`${decimalPtNumeral}|${noDecimalPtNumeral}`;
337 const floatRep
= match(
339 )`${noDecimalPtNumeral}|${decimalPtNumeral}|${scientificNotationNumeral}|${numericalSpecialRep}`;
340 const doubleRep
= match(
342 )`${noDecimalPtNumeral}|${decimalPtNumeral}|${scientificNotationNumeral}|${numericalSpecialRep}`;
343 const duYearFrag
= match(
345 )`${unsignedNoDecimalPtNumeral}Y`;
346 const duMonthFrag
= match(
348 )`${unsignedNoDecimalPtNumeral}M`;
349 const duDayFrag
= match("duDayFrag")`${unsignedNoDecimalPtNumeral}D`;
350 const duHourFrag
= match(
352 )`${unsignedNoDecimalPtNumeral}H`;
353 const duMinuteFrag
= match(
355 )`${unsignedNoDecimalPtNumeral}M`;
356 const duSecondFrag
= match(
358 )`(?:${unsignedNoDecimalPtNumeral}|${unsignedFullDecimalPtNumeral})S`;
359 const duYearMonthFrag
= match(
361 )`${duYearFrag}${duMonthFrag}?|${duMonthFrag}`;
362 const duTimeFrag
= match(
364 )`T(?:${duHourFrag}${duMinuteFrag}?${duSecondFrag}?|${duMinuteFrag}${duSecondFrag}?|${duSecondFrag})`;
365 const duDayTimeFrag
= match(
367 )`${duDayFrag}${duTimeFrag}?|${duTimeFrag}`;
368 const durationLexicalRep
= match(
369 "durationLexicalRep",
370 )`-?P(?:${duYearMonthFrag}${duDayTimeFrag}?|${duDayTimeFrag})`;
371 const yearFrag
= match(
373 )`-?(?:[1-9]${digit}{3,}|0${digit}{3})`;
374 const monthFrag
= match("monthFrag")`0[1-9]|1[0-2]`;
375 const dayFrag
= match("dayFrag")`0[1-9]|[12]${digit}|3[01]`;
376 const hourFrag
= match("hourFrag")`[01]${digit}|2[0-3]`;
377 const minuteFrag
= match("minuteFrag")`[0-5]${digit}`;
378 const secondFrag
= match(
380 )`[0-5]${digit}(?:\.${digit}+)?`;
381 const endOfDayFrag
= match("endOfDayFrag")`24:00:00(?:\.0+)?`;
382 const timezoneFrag
= match(
384 )`Z|[+-](?:(?:0${digit}|1[0-3]):${minuteFrag}|14:00)`;
385 const dateTimeLexicalRep
= match("dateTimeLexicalRep", ($) => {
386 const components
= stringSplit($, "-");
387 return components
[0] === ""
388 ? dayOfMonthValuesConstraint(
389 substring(components
[3], 0, 2),
393 : dayOfMonthValuesConstraint(
394 substring(components
[2], 0, 2),
398 })`${yearFrag}-${monthFrag}-${dayFrag}T(?:${hourFrag}:${minuteFrag}:${secondFrag}|${endOfDayFrag})${timezoneFrag}?`;
399 const timeLexicalRep
= match(
401 )`(?:${hourFrag}:${minuteFrag}:${secondFrag}|${endOfDayFrag})${timezoneFrag}?`;
402 const dateLexicalRep
= match("dateLexicalRep", ($) => {
403 const components
= stringSplit($, "-");
404 return components
[0] === ""
405 ? dayOfMonthValuesConstraint(
406 substring(components
[3], 0, 2),
410 : dayOfMonthValuesConstraint(
411 substring(components
[2], 0, 2),
415 })`${yearFrag}-${monthFrag}-${dayFrag}${timezoneFrag}?`;
416 const gYearMonthLexicalRep
= match(
417 "gYearMonthLexicalRep",
418 )`${yearFrag}-${monthFrag}${timezoneFrag}?`;
419 const gYearLexicalRep
= match(
421 )`${yearFrag}${timezoneFrag}?`;
422 const gMonthDayLexicalRep
= match("gMonthDayLexicalRep", ($) => {
423 const components
= stringSplit(substring($, 2), "-");
424 return dayOfMonthValuesConstraint(
425 substring(components
[1], 0, 2),
428 })`--${monthFrag}-${dayFrag}${timezoneFrag}?`;
429 const gDayLexicalRep
= match(
431 )`---${dayFrag}${timezoneFrag}?`;
432 const gMonthLexicalRep
= match(
434 )`--${monthFrag}${timezoneFrag}?`;
435 const hexDigit
= match("hexDigit")`[0-9a-fA-F]`;
436 const hexOctet
= match("hexOctet")`${hexDigit}{2}`;
437 const hexBinary
= match("hexBinary")`${hexOctet}*`;
438 const B04char
= match("B04char")`[AQgw]`;
439 const B04
= match("B04")`${B04char}\u{20}?`;
440 const B16char
= match("B16char")`[AEIMQUYcgkosw048]`;
441 const B16
= match("B16")`${B16char}\u{20}?`;
442 const B64char
= match("B64char")`[A-Za-z0-9+/]`;
443 const B64
= match("B64")`${B64char}\u{20}?`;
444 const Padded8
= match("Padded8")`${B64}${B04}=\u{20}?=`;
445 const Padded16
= match("Padded16")`${B64}{2}${B16}=`;
446 const B64finalquad
= match("B64finalquad")`${B64}{3}${B64char}`;
447 const B64final
= match(
449 )`${B64finalquad}|${Padded16}|${Padded8}`;
450 const B64quad
= match("B64quad")`${B64}{4}`;
451 const Base64Binary
= match(
453 )`(?:${B64quad}*${B64final})?`;
454 const CanonicalPadded
= match(
456 )`${B64char}{2}${B16char}=|${B64char}${B04char}==`;
457 const CanonicalQuad
= match("CanonicalQuad")`${B64char}{4}`;
458 const Canonical
·base64Binary
= match(
459 "Canonical·base64Binary",
460 )`${CanonicalQuad}*${CanonicalPadded}?`;
461 const yearMonthDurationLexicalRep
= match(
462 "yearMonthDurationLexicalRep",
463 )`-?P${duYearMonthFrag}`;
464 const dayTimeDurationLexicalRep
= match(
465 "dayTimeDurationLexicalRep",
466 )`-?P${duDayTimeFrag}`;
467 const dateTimeStampLexicalRep
= match(
468 "dateTimeStampLexicalRep",
470 const components
= stringSplit($, "-");
471 return components
[0] === ""
472 ? dayOfMonthValuesConstraint(
473 substring(components
[3], 0, 2),
477 : dayOfMonthValuesConstraint(
478 substring(components
[2], 0, 2),
483 )`${yearFrag}-${monthFrag}-${dayFrag}T(?:${hourFrag}:${minuteFrag}:${secondFrag}|${endOfDayFrag})${timezoneFrag}`;