From 41f8d3025f041aaab98fcc3511cb6ec2198f76a7 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Sun, 14 Jun 2026 01:49:48 +0300 Subject: init: vibed --- spec/grammar/UGI_GRAMMAR_v0.abnf | 148 ++++++++++++++++++++++++++++++++++ spec/grammar/UGI_GRAMMAR_v0.ebnf | 167 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 spec/grammar/UGI_GRAMMAR_v0.abnf create mode 100644 spec/grammar/UGI_GRAMMAR_v0.ebnf (limited to 'spec/grammar') 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 diff --git a/spec/grammar/UGI_GRAMMAR_v0.ebnf b/spec/grammar/UGI_GRAMMAR_v0.ebnf new file mode 100644 index 0000000..e37f87f --- /dev/null +++ b/spec/grammar/UGI_GRAMMAR_v0.ebnf @@ -0,0 +1,167 @@ +/* UGI Grammar v0 — W3C EBNF */ +/* Generated from ugi_registry_v0.json */ +/* Compatible with bottlecaps.de/rr/ui */ + +/* === Top-level === */ + +ugi_string ::= 'ugi:' version '@' handle ':' field_list + +version ::= digit+ ( '/' digit+ )? + +/* handle: alphanumeric, hyphens, underscores, dots */ +handle ::= ( alpha | digit | '-' | '_' | '.' )+ + +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 ::= [0-7] + +paid ::= '$' + +aspire ::= '+' odigit + +paid_aspire ::= paid aspire? + +modifier ::= paid_aspire | aspire + +alternative ::= '/' odigit + +/* custom sub-ID: ~ followed by 2+ alpha chars */ +custom_sub ::= '~' alpha alpha alpha* + +/* sub-ID: 1-4 alpha chars */ +sub_id ::= alpha alpha? alpha? alpha? + +/* === Per-field rules === */ + +/* a — Age (direct) */ +field_a ::= 'a' odigit + +/* b — Build (special) */ +field_b ::= 'b' odigit aspire? '/' odigit aspire? + +/* c — Clothing (direct) */ +field_c ::= 'c' odigit ( alternative | aspire )? + +/* d — Editor / IDE (multi) */ +field_d_entry ::= ( sub_id | custom_sub ) odigit ( aspire )? +field_d ::= 'd' field_d_entry+ + +/* e — Education (direct) */ +field_e ::= 'e' odigit ( aspire )? + +/* f — Food / Cooking (direct) */ +field_f ::= 'f' odigit ( modifier )? + +/* g — Geek Specialization (special) */ +g_domain ::= alpha alpha alpha? alpha? paid? +g_custom ::= '~' alpha alpha alpha* +field_g ::= 'g' ( g_domain | g_custom ) ( '/' ( g_domain | g_custom ) )* + +/* h — Hair (multi) */ +field_h_entry ::= ( sub_id | custom_sub ) odigit ( aspire )? +field_h ::= 'h' field_h_entry+ + +/* i — AI Stance (direct) */ +field_i ::= 'i' odigit + +/* j — Gaming (multi) */ +field_j_entry ::= ( sub_id | custom_sub ) odigit ( modifier )? +field_j ::= 'j' field_j_entry+ + +/* k — Books (direct) */ +field_k ::= 'k' odigit ( aspire )? + +/* l — Spoken Languages (multi) */ +field_l_entry ::= alpha alpha odigit ( modifier )? +field_l ::= 'l' field_l_entry+ + +/* m — Music (multi) */ +field_m_entry ::= ( sub_id | custom_sub ) odigit +field_m ::= 'm' field_m_entry+ + +/* o — Operating System (multi) */ +field_o_entry ::= ( sub_id | custom_sub ) odigit ( modifier )? +field_o ::= 'o' field_o_entry+ + +/* p — Programming Languages (multi) */ +field_p_entry ::= ( sub_id | custom_sub ) odigit ( modifier )? +field_p ::= 'p' field_p_entry+ + +/* q — Security / Hacking (direct) */ +field_q ::= 'q' odigit ( alternative | modifier )? + +/* r — Religion (single) */ +field_r ::= 'r' ( sub_id | custom_sub ) odigit + +/* s — Sex / Relationships (direct) */ +field_s ::= 's' odigit ( alternative | aspire )? + +/* t — TV / Film (multi) */ +field_t_entry ::= ( sub_id | custom_sub ) odigit +field_t ::= 't' field_t_entry+ + +/* v — Politics (special) */ +field_v ::= 'v' odigit '/' odigit + +/* w — Hardware (direct) */ +field_w ::= 'w' odigit ( modifier )? + +/* x — Comics / Manga (multi) */ +field_x_entry ::= ( sub_id | custom_sub ) odigit +field_x ::= 'x' field_x_entry+ + +/* y — Fitness (direct) */ +field_y ::= 'y' odigit ( modifier )? + +/* z — Maker / DIY (direct) */ +field_z ::= 'z' odigit ( modifier )? + +/* === Block format === */ + +ugi_block ::= block_header newline block_first_line newline block_field_line+ block_footer + +block_header ::= '------- BEGIN UGI BLOCK -------' +block_footer ::= '-------- END UGI BLOCK --------' + +block_first_line ::= 'v:' version ' @' handle ( ' ' block_geek_field )? + +block_geek_field ::= 'G' ( g_domain | g_custom ) ( '/' ( g_domain | g_custom ) )* + +block_field_line ::= block_field ( ' ' block_field )* newline + +block_field ::= alpha ( alpha | digit | '$' | '+' | '/' | '~' )+ + +/* === Terminals === */ + +alpha ::= [a-zA-Z] +digit ::= [0-9] +newline ::= #xD #xA | #xA -- cgit v1.2.3