aboutsummaryrefslogtreecommitdiffstats
path: root/spec/grammar/UGI_GRAMMAR_v0.abnf
diff options
context:
space:
mode:
authorAhmed <git@gumx.cc>2026-06-14 01:49:48 +0300
committerAhmed <git@gumx.cc>2026-06-14 01:49:48 +0300
commit41f8d3025f041aaab98fcc3511cb6ec2198f76a7 (patch)
treec147d5a547c3e2d7b49546157f324cbd80e88c48 /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.abnf148
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