// Root for the rules ?root: sequence sequence: (pc | dur_change | oct_mod | oct_change | WS | chord | cycle | random_integer | random_pitch | random_percent | range | list | lisp_operation | list_op | subdivision | eval | euclid)* // Pitch classes pc: prefix* pitch prefix: (octave | duration_chars | escaped_decimal | escaped_octave) pitch: /-?[0-9TE]/ escaped_decimal: "<" decimal ">" escaped_octave: /<-?[0-9]>/ octave: /[_^]+/ // Chords chord: pc pc+ // Valid as integer ?number: SIGNED_NUMBER | random_integer // List list: prefix* "(" sequence ")" // Right recursive list operation list_op: list (operator (list | number))+ operator: /([\+\-\*\/%]|<<|>>)/ euclid: list euclid_operator list? ?euclid_operator: /<[0-9]+,[0-9]+(,[0-9])?>/ // TODO: Support randomization etc. //euclid_operator: (">" | "<") number "," number ["," number] (">" | "<") // Lisp like list operation lisp_operation: "(" operator WS sequence ")" // Durations duration_chars: dotted_dur+ dotted_dur: dchar dot* decimal: /-?[0-9]+\.[0-9]+/ dchar: /[mklpdcwyhnqaefsxtgujzo]/ dot: "." // Subdivision subdivision: "[" subitems "]" subitems: (pc | WS | chord | cycle | subdivision)* // Control characters modifying future events oct_mod: octave WS oct_change: escaped_octave WS dur_change: (duration_chars | decimal) WS // Generative rules random_integer: /\(-?[0-9]+,-?[0-9]+\)/ range: /-?[0-9]\.\.-?[0-9]/ cycle: "<" sequence ">" random_pitch: "?" random_percent: "%" // Rules for evaluating clauses inside {} // TODO: Support for parenthesis? eval: "{" operation "}" operation: atom (operator atom)+ atom: (number | DECIMAL) %import common.NUMBER %import common.SIGNED_NUMBER %import common.DECIMAL %import common.WS