program = { expression, ws*, ";", { ws*, ";" }, ws* } ; block = "[", program, "]" ; (* At interpreter runtime it is determined which symbols pass as operators, and which not *) expression = value, ws*, operator, ws*, expression | operator, ws*, value | value ; value = note | chord | symbol | block | number | ( "(", expression, ")" ) ; symbol = ( valid-symbol-start-characters, { valid-symbol-characters } ) - note - chord; valid-symbol-start-characters = uniletter | "_" | "@" | "$" | "#" ; valid-symbol-characters = valid-symbol-start-characters | unidigit | "-" ; operator = operator-symbols, { operator-symbols } ; operator-symbols = "+" | "-" | "*" | "/" | "%" | "!" | "<" | ">" | "v" | "^" | "=" | ":" ; (********************************* Literały liczbowe *********************************) number = floating-point | fraction ; (* Dopuszcza następujące zapisy: 1/2, *) fraction = digits+, ws*, "/", ws*, digits+ ; (* Dopuszcza następujące zapisy: -123.456, 123.456, .456; Notacja naukowa nie jest wspierana *) floating-point = ( ["-"], digits+, [ ".", digits+ ] ) | ( ".", digits+ ); (********************************* Literały muzyczne *********************************) (* DSL do definiowania muzycznych wartości. Brakuje notacji dla akordów, przewrotów itd *) note = note-letter, ["#"], [ws*, octave] ; note-letter = "c" | "C" | "d" | "D" | "e" | "E" | "f" | "F" | "g" | "G" | "a" | "A" | "h" | "H" | "b" | "B" ; octave = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" ; chord = note-letter, ["#"], [ ("1" | "2" | "5" | "7" ), [ "," | "'" ] ]; (********************************* Definicje pomocnicze *********************************) (* Unicode helpers, based on Go's compiler source code *) uniletter = ? all characters that are considered letters in unicode ?; unidigit = ? all characters that are considered digits in unicode ?; digits+ = digit, { digits } ; digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; (* Whitespace helpers *) ws* = { ws } ; ws+ = ws, { ws } ; ws = ? all characters that are considered ascii whitespace ? ;