aboutsummaryrefslogtreecommitdiff
path: root/Documentation/wmap-spec.ebnf
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-07-09 01:55:50 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2025-07-09 01:55:50 +0200
commit6926feead1a7fadb7f5f974996bef8c30b3bfdbe (patch)
tree5a16e64f70bea3b9f33220cce5ca524e686dbedf /Documentation/wmap-spec.ebnf
parentc21a68c807dcb84b4ce910ee0f73238a8019ffe9 (diff)
Use AST based text editor
Diffstat (limited to 'Documentation/wmap-spec.ebnf')
-rw-r--r--Documentation/wmap-spec.ebnf47
1 files changed, 47 insertions, 0 deletions
diff --git a/Documentation/wmap-spec.ebnf b/Documentation/wmap-spec.ebnf
new file mode 100644
index 0000000..d3c5ad7
--- /dev/null
+++ b/Documentation/wmap-spec.ebnf
@@ -0,0 +1,47 @@
+(* wmap Language Specification *)
+
+(* Top-level structure *)
+program = { line } ;
+line = ( entity newline ) | ( ignored_line newline ) | newline ;
+
+entity = vertex | edge | note | stage | group | inertia | evolution ;
+ignored_line = ? any sequence of tokens that doesn't match entity grammar ? ;
+
+(* Entities *)
+vertex = vertex_label position [ shape ] ;
+edge = vertex_label edge_type vertex_label ;
+note = case_insensitive("[Note]") position text ;
+stage = "[" stage_number "]" real_number ;
+group = case_insensitive("[Group]") vertex_label { "," vertex_label } ;
+inertia = case_insensitive("[Inertia]") vertex_label ;
+evolution = case_insensitive("[Evolution]") vertex_label sign real_number ;
+
+(* Component definitions *)
+position = "(" real_number "," real_number ")" ;
+shape = "[" shape_label "]" ;
+edge_type = "--" | "->" ;
+sign = "+" | "-" ;
+
+(* Terminal symbols *)
+vertex_label = preserved_case( { character - ( "-" | "+" | "," | "[" | "]" | "(" | ")" | newline ) } ) ;
+text = preserved_case( { character - newline } ) ;
+real_number = [ digit ] { digit } [ "." { digit } ] | "." digit { digit } ;
+stage_number = case_insensitive( "i" | "ii" | "iii" | "iv" ) ;
+shape_label = case_insensitive( "x" | "square" | "triangle" | "circle" ) ;
+
+(* Lexical elements *)
+character = ? any Unicode character ? ;
+digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
+newline = ? newline character ? ;
+
+(* Lexical rules *)
+case_insensitive(x) = ? case-insensitive match of x ? ;
+preserved_case(x) = ? case-insensitive match of x, preserving original case for display ? ;
+
+(* Notes *)
+(* - Keywords and shape labels are case-insensitive *)
+(* - Vertex labels are case-insensitive for matching but preserve original case *)
+(* - Text content preserves original case *)
+(* - Whitespace (except newlines) may appear between any tokens *)
+(* - Each line contains exactly one entity *)
+(* - Invalid lines should be ignored. *)