Added more rules and tests

This commit is contained in:
2023-02-01 21:15:09 +02:00
parent 6fea0c275d
commit 3add48c938
22 changed files with 86 additions and 47 deletions

View File

@ -5,11 +5,15 @@ class Meta:
text: str
@dataclass
class Duration(Meta):
class DurationChange(Meta):
dur: float
@dataclass
class Octave(Meta):
class OctaveChange(Meta):
oct: int
@dataclass
class OctaveMod(Meta):
oct: int
@dataclass
@ -25,7 +29,6 @@ class Pitch(Event):
@dataclass
class RandomPitch(Event):
pc: int = None
@dataclass
class Chord(Event):
@ -42,8 +45,10 @@ class Ziffers:
text: str = None
def __post_init__(self):
self.text = self.collect_text()
def collect_text(self):
def collect_text(self) -> str:
return "".join([val.text for val in self.values])
def pcs(self) -> list[int]:
return [val.pc for val in self.values if type(val) is Pitch]
@dataclass
class Sequence(Meta):

View File

@ -2,7 +2,6 @@ from lark import Transformer
from .classes import *
from .common import flatten
from .defaults import default_durs
from collections import Counter
class ZiffersTransformer(Transformer):
@ -28,11 +27,14 @@ class ZiffersTransformer(Transformer):
def pc(self, s):
if(len(s)>1):
counter = Counter()
for d in s:
counter.update(d)
result = dict(counter)
result["text"] = result["text"][::-1]
# Collect&sum prefixes from any order: _qee^s4 etc.
result = s[0]
for hash in s[1:]:
for key in hash.keys():
if key in result:
result[key] = result[key] + hash[key]
else:
result[key] = hash[key]
return Pitch(**result)
else:
val = s[0]
@ -46,7 +48,15 @@ class ZiffersTransformer(Transformer):
def oct_change(self,s):
octave = s[0]
return [Octave(oct=octave["oct"],text=octave["text"]),s[1]]
return [OctaveChange(oct=octave["oct"],text=octave["text"]),s[1]]
def oct_mod(self,s):
octave = s[0]
return [OctaveMod(oct=octave["oct"],text=octave["text"]),s[1]]
def escaped_octave(self,s):
value = s[0][1:-1]
return {"oct": int(value), "text":s[0].value}
def octave(self,s):
value = sum([1 if char=='^' else -1 for char in s[0].value])
@ -57,14 +67,19 @@ class ZiffersTransformer(Transformer):
def dur_change(self,s):
duration = s[0]
return [Duration(dur=duration["dur"], text=duration["text"]),s[1]]
return [DurationChange(dur=duration["dur"], text=duration["text"]),s[1]]
def duration(self,s):
def escaped_decimal(self,s):
val = s[0]
val["text"] = "<"+val["text"]+">"
return val
def duration_chars(self,s):
durations = [val[1] for val in s]
characters = "".join([val[0] for val in s])
return {"dur": sum(durations), "text":characters[::-1]}
return {"dur": sum(durations), "text":characters}
def dur(self,s):
def dotted_dur(self,s):
key = s[0]
val = default_durs[key]
dots = len(s)-1
@ -72,6 +87,10 @@ class ZiffersTransformer(Transformer):
val = val * (2.0-(1.0/(2*dots)))
return [key+"."*dots,val]
def decimal(self,s):
val = s[0]
return {"dur": float(val),"text": val.value}
def dot(self,s):
return "."

View File

@ -9,13 +9,4 @@ grammar = grammar_path / "ziffers.lark"
ziffers_parser = Lark.open(grammar, rel_to=__file__, start='value', parser='lalr', transformer=ZiffersTransformer())
def parse_expression(expr):
return ziffers_parser.parse(expr)
if __name__ == '__main__':
print(ziffers_parser.parse("[1 [2 3]]"))
#print(ziffers_parser.parse("(1 (1,3) 1..3)"))
#print(ziffers_parser.parse("_^ q _qe^3 qww_4 _123 <1 2>"))
#print(ziffers_parser.parse("q _2 _ 3 ^ 343"))
#print(ziffers_parser.parse("2 qe2 e4").values)
#print(ziffers_parser.parse("q 2 <3 343>"))
#print(ziffers_parser.parse("q (2 <3 343 (3 4)>)"))
return ziffers_parser.parse(expr)

View File

@ -1,19 +1,23 @@
?value: root
root: (pc | dur_change | oct_change | WS | chord | cycle | randompitch | range | list | subdivision)*
root: (pc | dur_change | oct_mod | oct_change | WS | chord | cycle | randompitch | range | list | subdivision)*
list: "(" root ")"
randompitch: /[\(][-?0-9][,][-?0-9][\)]/
range: /[-?0-9]\.\.[-?0-9]/
randompitch: /\(-?[0-9],-?[0-9]\)/
range: /-?[0-9]\.\.-?[0-9]/
cycle: "<" root ">"
pc: prefix* pitch
pitch: /[-?0-9TE]/
prefix: octave | duration
oct_change: octave WS
pitch: /-?[0-9TE]/
prefix: (octave | duration_chars | escaped_decimal | escaped_octave)
oct_change: escaped_octave WS
escaped_octave: /<-?[0-9]>/
oct_mod: octave WS
octave: /[_^]+/
chord: pc pc+
dur_change: duration WS
duration: dur+
dur: dchar dot*
escaped_decimal: "<" decimal ">"
dur_change: (duration_chars | decimal) WS
duration_chars: dotted_dur+
dotted_dur: dchar dot*
decimal: /-?[0-9]+\.[0-9]+/
dchar: /[mklpdcwyhnqaefsxtgujzo]/
dot: "."
subitems: (pc | WS | chord | cycle | subdivision)*