diff options
| author | Ahmed <git@gumx.cc> | 2026-06-14 01:49:48 +0300 |
|---|---|---|
| committer | Ahmed <git@gumx.cc> | 2026-06-14 01:49:48 +0300 |
| commit | 41f8d3025f041aaab98fcc3511cb6ec2198f76a7 (patch) | |
| tree | c147d5a547c3e2d7b49546157f324cbd80e88c48 /spec/grammar/UGI_GRAMMAR_v0.abnf | |
init: vibed
Diffstat (limited to 'spec/grammar/UGI_GRAMMAR_v0.abnf')
| -rw-r--r-- | spec/grammar/UGI_GRAMMAR_v0.abnf | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/spec/grammar/UGI_GRAMMAR_v0.abnf b/spec/grammar/UGI_GRAMMAR_v0.abnf new file mode 100644 index 0000000..d0f7da1 --- /dev/null +++ b/spec/grammar/UGI_GRAMMAR_v0.abnf @@ -0,0 +1,148 @@ +; UGI Grammar v0 — RFC 5234 ABNF +; Generated from ugi_registry_v0.json +; +; Compatible with abnf.dev/abnf2svg + +; === Top-level === + +ugi-string = "ugi:" version "@" handle ":" field-list + +version = 1*DIGIT ["/" 1*DIGIT] + +; handle: alphanumeric, hyphens, underscores, dots +handle = 1*(ALPHA / DIGIT / %x2D / %x5F / %x2E) + +field-list = field *("," field) + +; === Field dispatch === + +field = field-a / field-b / field-c / field-d / field-e / field-f / field-g / field-h / field-i / field-j / field-k / field-l / field-m / field-o / field-p / field-q / field-r / field-s / field-t / field-v / field-w / field-x / field-y / field-z + +; === Common rules === + +ODIGIT = %x30-37 + +paid = "$" + +aspire = "+" ODIGIT + +paid-aspire = paid [aspire] + +modifier = paid-aspire / aspire + +alternative = "/" ODIGIT + +; custom sub-ID: ~ followed by 2+ alpha chars +custom-sub = "~" 2*ALPHA + +; sub-ID: 1-4 alpha chars +sub-id = 1*4ALPHA + +; === Per-field rules === + +; a — Age (direct) +field-a = %x61 ODIGIT + +; b — Build (special) +field-b = %x62 ODIGIT [aspire] "/" ODIGIT [aspire] + +; c — Clothing (direct) +field-c = %x63 ODIGIT [alternative / aspire] + +; d — Editor / IDE (multi) +field-d-entry = (sub-id / custom-sub) ODIGIT [aspire] +field-d = %x64 1*field-d-entry + +; e — Education (direct) +field-e = %x65 ODIGIT [aspire] + +; f — Food / Cooking (direct) +field-f = %x66 ODIGIT [modifier] + +; g — Geek Specialization (special) +g-domain = 2*4ALPHA ["$"] +g-custom = "~" 2*ALPHA +field-g = %x67 (g-domain / g-custom) *("/" (g-domain / g-custom)) + +; h — Hair (multi) +field-h-entry = (sub-id / custom-sub) ODIGIT [aspire] +field-h = %x68 1*field-h-entry + +; i — AI Stance (direct) +field-i = %x69 ODIGIT + +; j — Gaming (multi) +field-j-entry = (sub-id / custom-sub) ODIGIT [modifier] +field-j = %x6A 1*field-j-entry + +; k — Books (direct) +field-k = %x6B ODIGIT [aspire] + +; l — Spoken Languages (multi) +field-l-entry = 2ALPHA ODIGIT [modifier] +field-l = %x6C 1*field-l-entry + +; m — Music (multi) +field-m-entry = (sub-id / custom-sub) ODIGIT +field-m = %x6D 1*field-m-entry + +; o — Operating System (multi) +field-o-entry = (sub-id / custom-sub) ODIGIT [modifier] +field-o = %x6F 1*field-o-entry + +; p — Programming Languages (multi) +field-p-entry = (sub-id / custom-sub) ODIGIT [modifier] +field-p = %x70 1*field-p-entry + +; q — Security / Hacking (direct) +field-q = %x71 ODIGIT [alternative / modifier] + +; r — Religion (single) +field-r = %x72 (sub-id / custom-sub) ODIGIT + +; s — Sex / Relationships (direct) +field-s = %x73 ODIGIT [alternative / aspire] + +; t — TV / Film (multi) +field-t-entry = (sub-id / custom-sub) ODIGIT +field-t = %x74 1*field-t-entry + +; v — Politics (special) +field-v = %x76 ODIGIT "/" ODIGIT + +; w — Hardware (direct) +field-w = %x77 ODIGIT [modifier] + +; x — Comics / Manga (multi) +field-x-entry = (sub-id / custom-sub) ODIGIT +field-x = %x78 1*field-x-entry + +; y — Fitness (direct) +field-y = %x79 ODIGIT [modifier] + +; z — Maker / DIY (direct) +field-z = %x7A ODIGIT [modifier] + +; === Block format === + +ugi-block = block-header CRLF block-first-line CRLF 1*(block-field-line CRLF) block-footer + +block-header = "------- BEGIN UGI BLOCK -------" +block-footer = "-------- END UGI BLOCK --------" + +block-first-line = "v:" version SP "@" handle [SP block-geek-field] + +; In block format, G field uses uppercase and appears on first line +block-geek-field = "G" (g-domain / g-custom) *("/" (g-domain / g-custom)) + +block-field-line = block-field *(SP block-field) + +; Block fields use uppercase code prefix repeated per sub-ID +block-field = ALPHA 1*(ALPHA / DIGIT / %x24 / %x2B / %x2F / %x7E) + +; === Core rules (RFC 5234) === + +ALPHA = %x41-5A / %x61-7A +DIGIT = %x30-39 +SP = %x20 +CRLF = %x0D.0A / %x0A |
