From 3add48c938499fb84fe75c9fae76229fdb961dd9 Mon Sep 17 00:00:00 2001 From: Miika Alonen Date: Wed, 1 Feb 2023 21:15:09 +0200 Subject: [PATCH] Added more rules and tests --- .gitignore | 8 +++- main.py | 11 ++--- tests/__pycache__/__init__.cpython-311.pyc | Bin 153 -> 0 bytes .../test_parser.cpython-311-pytest-7.2.1.pyc | Bin 1998 -> 0 bytes tests/test_parser.py | 27 +++++++++--- .../__pycache__/ZiffersData.cpython-311.pyc | Bin 4933 -> 0 bytes .../ZiffersTransformer.cpython-311.pyc | Bin 8279 -> 0 bytes ziffers/__pycache__/__init__.cpython-310.pyc | Bin 162 -> 0 bytes ziffers/__pycache__/__init__.cpython-311.pyc | Bin 301 -> 0 bytes ziffers/__pycache__/classes.cpython-311.pyc | Bin 4944 -> 0 bytes ziffers/__pycache__/common.cpython-311.pyc | Bin 592 -> 0 bytes ziffers/__pycache__/defaults.cpython-311.pyc | Bin 1264 -> 0 bytes ziffers/__pycache__/ebnf.cpython-310.pyc | Bin 856 -> 0 bytes ziffers/__pycache__/example.cpython-310.pyc | Bin 1361 -> 0 bytes ziffers/__pycache__/mapper.cpython-311.pyc | Bin 8229 -> 0 bytes ziffers/__pycache__/parser.cpython-310.pyc | Bin 2070 -> 0 bytes ziffers/__pycache__/parser.cpython-311.pyc | Bin 1016 -> 0 bytes .../__pycache__/transformer.cpython-311.pyc | Bin 8285 -> 0 bytes ziffers/classes.py | 13 ++++-- ziffers/mapper.py | 41 +++++++++++++----- ziffers/parser.py | 11 +---- ziffers/ziffers.lark | 22 ++++++---- 22 files changed, 86 insertions(+), 47 deletions(-) delete mode 100644 tests/__pycache__/__init__.cpython-311.pyc delete mode 100644 tests/__pycache__/test_parser.cpython-311-pytest-7.2.1.pyc delete mode 100644 ziffers/__pycache__/ZiffersData.cpython-311.pyc delete mode 100644 ziffers/__pycache__/ZiffersTransformer.cpython-311.pyc delete mode 100644 ziffers/__pycache__/__init__.cpython-310.pyc delete mode 100644 ziffers/__pycache__/__init__.cpython-311.pyc delete mode 100644 ziffers/__pycache__/classes.cpython-311.pyc delete mode 100644 ziffers/__pycache__/common.cpython-311.pyc delete mode 100644 ziffers/__pycache__/defaults.cpython-311.pyc delete mode 100644 ziffers/__pycache__/ebnf.cpython-310.pyc delete mode 100644 ziffers/__pycache__/example.cpython-310.pyc delete mode 100644 ziffers/__pycache__/mapper.cpython-311.pyc delete mode 100644 ziffers/__pycache__/parser.cpython-310.pyc delete mode 100644 ziffers/__pycache__/parser.cpython-311.pyc delete mode 100644 ziffers/__pycache__/transformer.cpython-311.pyc diff --git a/.gitignore b/.gitignore index b1cb160..1188230 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,11 @@ # Byte-compiled / optimized / DLL files -__pycache__/ +**/__pycache__/ *.py[cod] *$py.class +# Pytest +.pytest_cache + # C extensions *.so @@ -159,3 +162,6 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +# Debugging file +debug.py + diff --git a/main.py b/main.py index 5f305fa..fa9eba9 100644 --- a/main.py +++ b/main.py @@ -7,7 +7,7 @@ if __name__ == "__main__": 'Chords': "0 024 2 246", 'Note lengths': "w 0 h 1 q 2 e 3 s 4", 'Subdivision': "[1 2 [3 4]]", - 'Decimal durations': "0.25 0 1 [0.333]2 3", + 'Decimal durations': "0.25 0 1 <0.333>2 3", 'Octaves': "^ 0 ^ 1 _ 2 _ 3", 'Escaped octave': "<2> 1 <1>1<-2>3", 'Roman chords': "i ii iii+4 iv+5 v+8 vi+10 vii+20", @@ -32,8 +32,9 @@ if __name__ == "__main__": 'Functions': "(0 1 2 3){x%3==0?x-2:x+2}", 'Polynomials': "(-10..10){(x**3)*(x+1)%12}", } - for expression in expressions: - try: - parse_expression(expression) + for ex in expressions: + try: + print(f"Parsed: "+parse_expression(expressions[ex]).text) except Exception as e: - print(f"[red]Failed on {expression}[/red]: {str(e)[0:40]}...") + print(f"[red]Failed on {ex}[/red]") + #print(f"[red]Failed on {ex}[/red]: {str(e)[0:40]}...") diff --git a/tests/__pycache__/__init__.cpython-311.pyc b/tests/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index ce987795d8a997c6fe47be0454feb8ddc2071a04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmZ3^%ge<81V^XdOlAbqk3k$5011G=XEq=)ogsxGm_d`#ZzV$!6G#vw^GioRv^ce> zSU;&WDPO-TGc66s(JiPf$;i*sFG(#fDb|mV&&nx>^3CT%Lbs5rIP_)tPbBvK+FSxA&aQzfg7cau6=+v}MP zP8J&l)I&g#fKx$$RBW8V@4er= zeQWH^ES$Ipnj||~4 zT8tUo$4C+X@tlha$GA63-8lXtgB0L<{0D@8g4Q7DFI)@O7S}}Yqa~-sCy>MSTnxU+ z|A>C(p8@tf!a3x4QM#i!U~LIa?rBIrJmjy2Fc@d|?oH%)th!?gkxWZG$)G6?`kWj6 z)X4`>oR;{xxLXO<2G>BF!UNRc`Z92X8JtAO2chPGwIwwr`ofS5*%|7cT95AV48Z4+ z;ZsDfIit}Qt;a*%i8O@z^OJs$h|BpNRnCx&*#G2n`D{Le_ay!2A{K+^Aa|@UV(+BX ze=j5cli)&~TCy`9Rso?t->9NZx!<>c_a(drEy+O8>WQKfa}y7<_+bvKOH1xZI*ZfU z+p2=InT)Eq*R^F_$6DQ7R&l-2(DGQz=2SeB#kpB`1S~nMVHGc9HLtqy9Il%=Z06me zI?mx4)kA09u{utNJDgT=UYS+g%OB~4maA*n+_Z^FX}MOti|^laZ|jtr#KE`H_Li#9 zcKN%4Dln(k;r8fI231G@Y=k8hupTundiu zHqq9s+KO&zRlQ=eghusM(}UT_oPP}nJ5NZBurY15Mk>1FQLyx??j=-WY^cYG67L;g z$sWSw;9`t3*^oyoC`~Td1o84T23|NAucoIzf#T8Wm5r6!v|C;UGW0EA{-{=+_UKbz zYJM?D#@=Eh{-sKKwTrzD!MvX)`W^gOZKDn!ACo&M6x$zmE}_wj+aDZWne3pLbi)@r z$qp|kZXBg9wlBT?+iM_T?xzX|sX{wdI2yn8bbWt3doZ5exp$Zv`=u(J@lK*Y&|)MWeAdf5V;3H2?qr diff --git a/tests/test_parser.py b/tests/test_parser.py index 8f454a1..074a076 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,4 +1,5 @@ from ziffers import * +import pytest def test_can_parse(): expressions = [ @@ -24,10 +25,22 @@ def test_can_parse(): print(results) assert all(results) -#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)>)")) +@pytest.mark.parametrize( + "pattern", + [ + "1 2 3", + "q3 e4 s5", + ], +) +def test_parsing_text(pattern: str): + assert parse_expression(pattern).text == pattern + +@pytest.mark.parametrize( + "pattern,expected", + [ + ("1 2 3", [1,2,3]), + ("q2 eq3", [2,3]), + ], +) +def test_pcs(pattern: str, expected: list): + assert parse_expression(pattern).pcs == expected \ No newline at end of file diff --git a/ziffers/__pycache__/ZiffersData.cpython-311.pyc b/ziffers/__pycache__/ZiffersData.cpython-311.pyc deleted file mode 100644 index 95e428b8893defee120eb417289bfe1c1b7cdfc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4933 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 diff --git a/ziffers/__pycache__/__init__.cpython-310.pyc b/ziffers/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index f84025ede8d029fa3af714bffde1175d0f9f3bfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmd1j<>g`k0;Snq$znkIF^Gc(44TX@8G%BYjJFuI z{4^P(*a{Mhic^bLG88cbg~7xxJ^fIiP_ceeX;Qv^Rc2ZmkfU2rS(1^T2jl9;$7kkc cmc+;F6;$5hu*uC&Da}c>1DRY5vYLkh0AcwgumAu6 diff --git a/ziffers/__pycache__/__init__.cpython-311.pyc b/ziffers/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 542df8fc81b45e4205377aa8e5f0600bf090eca2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmZ3^%ge<81PMJilM8|LV-N=hn4pZ$dO*f>h7^Vr#vFza2+atknV>W?lx6|aOu-DA z%r6;%nlu@2F>3i~vfg4VNGvK&ExN^)n^;f)q}h{m5{rvdi*KQeEq7-v@{?`x1h2lBR>zu)sK(Q%*!l^kJl@x{Ka9D wo1apelWJGQ1Jn+(yx1K`d|+l|WW2#3dI5$|*YxN7@qa69e>6oaXx@Rp^$>x5|G*hpopp^v>~XbYKqias#a!q14fP=cGrAF zRN6=!tTs~VDLwSSi5AfxlT=7`_k`3_Z;8T*Q{QK1z1X`;jA$pjk7s9|cixYgd1vx# zE|+Fh+CTiI4JnNMjgL-Ac$J-%7-Q>9XS!5lOHx@{ij`v$Go%>%jOnraOqU-K;|aZ@ zJffc`oex%)J*Gm;xFJ81sh3_+0$j!8CWt%Gha2~}N#dsZa1$OkP27x;*wuyskDDcK zt`9fqaR-T;@54=b+&#n{>cdTY++pI5>>AyS$1D(Yv`-YW9(Rnm<9)a}k2^u!y+(G| zhz)w&eZ2r5S3~V>F)ZDxVv6#Z_$Mj$JCo-K474D@%r|x@lEiYUs@x z>RDC2*{syO9@(-@H?OLddc9#+>}sQKsp@041I;f^oV;Qgrgida^J?SdN_BCOK29v( zwXZkoozIipZo`^hzH4G*ae&3vUIM4a z)=Xl=6aZV_jW5<372C|BAqU_Z^QaAVV1O!NJ5z(syfeQ_uQM;CAn=BECN67s<(A>f z4b3h+4p}Kz>(Mrj!bU(Q+QzIi=gh6r>&yuo!Hu@@AoX-F8(pH*r5JHN#+Q!7mrne` zEu(Ii%wZxI6MurLbc^?{e&bLN46g-<8sUnPqP_)r!sb@E% z%L!wET#$te}rmNjAi7>!s=1wA`Jt>y%PuN1g190fhNa3;|P zKqxGj*yHHnu=7bvc1liZwbTxH-Oi6t6h@rO&gE5loy#Hs7%VyfuQh9#FDrGuu_RnI z;Y)b#0v-nT!doO`0UvHRt$(5Hit2hvx z9jql+sZ}XS@z_W0=EKA>0f?CO4ndCx&y+{Ipru zkTuBzvsn*EANH8o!;w2@3LOAA8jgPSngKuBLt z%6(Q&>v6&iKS~nrKv|@FH*u>{YZ_L`M6%Q*f=0hGnbOdev6dl~K>c>7M5I zi0S3@c46Yr!qgvysm;Q%r-frJWi8dBKR)q2o+u>4J(;Hp-3X+Bj0_igGs>7I1M*Y;CvExjNzPf_Bbp!me5Pq{Kp zgoT(N65)7}p25b@8cWOPR*rXK(H+R?nOZ|5p>tH}FsEq%3u)J38{?T#xl^cy}-7FH>LTXTn5~R|-)&Pk@OP>accx=*QdN-xlNkHv9V}s%?&+eoB}> z^E7{EBY8%s$_BUn5t8Qzir6%m9#_G=h{r>0Cpg0G2qx*{=m22rS>F&iU4PHAdmfCg zUD{B_>Dg4q+nFI}w!Np|%(jkfCtGB8a zWkcbDd4@&~PR|V503V`)GgMfCrf4hrBx0F1n&KwT-_>eW&BO+A;~IS!rEoU>2Ma5f$qb}qC&5Xbw=vk?4fyN^;&aQ3|njElRteR1pg0qn|4)jC1tPRSf6 z(O}^GlNyl<-?CEPjj-LR_*cXKYMmRWTgElRjazobv|ZV#>(Lg@!fL?BkrrmWdv(}C zE>tS+aWnpZLWX6^7)}8s0Q}a@uf<4T;y%D*au}aTIegdiJ-`v}{P_ zA(iiv%5Qa~a*zr_>nlj*AeHNq%K1`bkP1R;7E)u78tal8^Q2^{u*JgAy0DGb=Kx;{ zw6y2f2y_ME!4!0jK-Y*b1zOURnuJskpo>}|HQ6OK>H9?%N-(nrT1`lig#=wv1y5=~ zqJ$lWZL~cH_%a|3d-hF0Nf5+rO+eFxF9lj>wt@nDkOxO$-!4+Y;6ZAn_4O+vD0IcJ dD8c|;)cPFYTL_wndsu)Ef|U^|kB$HU diff --git a/ziffers/__pycache__/common.cpython-311.pyc b/ziffers/__pycache__/common.cpython-311.pyc deleted file mode 100644 index b26c5e59c25ffbb245096dec2eac038f42664781..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmZ3^%ge<81UI^GCN}};#~=<2FhLogg@BCd3@Hq$3~5X$j4dotj44dP44TZh*osn1 zN{jN68DUz0G#d~z1M%k_Kw>&W36fk5!!jUmHC&_wW&==VDMOJ{2`i8R1vLyQjFK=8 zx;}Qe1OvL6DNNZcAlV{uG}D+;7+RTdnV83z&QJx^mB&=Wkj@D5o8L>2DK9~8)nvKF zQc_uvdW$6|v$*6Idsc~fHW6}0*MBOyWaj60)kIkp0T_d5p%&C zgnG><7*8miV%BNjW4~2-L-IzAEgCxlH|cE9nVY^Kd4=K%r4>p`(l5&CU6IqfAg6c0 z=_0rL1t3aJyO5NAfhGMj&|n5XO{OAHsDbTU$xy@tVsitDUmP~M`6;D2sdhztKrYxR chCs##W=2NF4@``V8H^KLJ}`i2{3O^&0BPcX`Tzg` diff --git a/ziffers/__pycache__/defaults.cpython-311.pyc b/ziffers/__pycache__/defaults.cpython-311.pyc deleted file mode 100644 index b40e672ec49f1907e12fb94fcbb4ab66af29a6da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1264 zcmX|;J4{ny7>3WG6bkgp{eHidOA8drotC?kiy<*C2KahGfzqBGOT(eRFbho;w_s8qUR|Z@Ukyn)Z_i z^OP#N`T=>O?P;Wuex_3iS-?`Vf@M?=+Nc7oq$82h`z0?Qx(*QU~UT}zp!4Vn-edGtnXdIlN060lgV34N4 z8JY#>XdYakMR18iV3?M{6$LIO4_WvKARFk885Xf{)*Q=|CSL+8UCHjPQstvi$*bw9-XA)i9>VrtDfOI zI=Qwj93&{SA6ZJZqORjIK7zuc>$)iEbvrMdo?Jj!V3)8tVTFk@%~g$UIlE1B)#O%1 z1$!m$XGImeU1l8YPMLAByJg11UM({{{VTRDGQ zw6V8yeqD61cXDP%bg_4{Pl_IPjnOMheeC^Q+7JWmgRc*GMVWeJYL03Q#0(CX$l**Y=8|7WNcYZ47MdC8IzXw0NkXzUVB2i zAkSjNOLntc2?|&!rkVtZZMD^;ayU6}gsJnBCs(S}dwYfZmq>Gt%4+@w!E}s8qrSaCKo)OH6QJDN+IR;6}9;~8TSMa}mc7ErDI4T6Ro!oBx z*;;Ih+}4841MH>qdy^~^IPlg;BvV&6y06h#0d@Bccoz1nZ1v5j*fQkNZ$PX9D>z<|8}rcMChw%rdJ7?b=cu| z2qrSIjU3#=7@4F;EMyiqF^e_y4x1&Y&eaganL1h!NEzx`$<0A^UUCr6_=-Y7InT+| za~C)P>|%~B3a_fr)2yGpSw+VOPYQPm`b=ABE{Q~rhvcC@14O!Kp zx+yBix9Z~Lx4~oS1Nn%11&&Sn2KS2Qoo%GE6mE}noXl(nhT|B)Nc0GO>n7Mq%TOiw zX)0!w7Gz_mFiZgbl*nu*c#z<6f+q<+Ot72aX9+eE%o98uZSRWp8N9-@D&@!NqRdfB zA*U-MtV7UAf=3CCjW1w3M`7_}KcF3|xv|sd0Ud{3y+I|DAssq229Xy~!!)hPI^qq< z=AC$!HCdarn4T#mpFPx}eqh0UC)A1U$ntG#VEi@t7n4>EM%xtZ^!!2TmYaZ`5pXvI zjmt+O%3~{yVkp=!jb#jFI+LuB1JPo+?|+xnwAXBJrFCzgH7Q$WU7EKI9bTgWbcQr_ zooX86aLNrhrv|2N7=b<|=*oAFLos2oI>0>+8|o-F+#!eIq*5A8W7(1IeqfyG_A=cx zwx9V8au6=~BGXM{uQFYv+~kB-6*ij2))Y4I;0u*f@Vl!pZxF?Pjy*ZUOmFN03c3S@ z^^G93Mj7@}VZI%QLef;NW4WqtsXnqCF8ORcrgfw&+luFoA5Cn_<=`<6n{r%RdZ|}~ zk%gAyxt14)%Omw)1?qRX->Ymr+SxdGxUsdl^I$uf$>>igVDKBr@T1k<4S5i@`*GiE zKevWMXj=XxI`rJUZS!Np@om2BPm=PgLU4Bge`KpL{7x6l*%V$7Q9aX0HXXz6aWAK diff --git a/ziffers/__pycache__/mapper.cpython-311.pyc b/ziffers/__pycache__/mapper.cpython-311.pyc deleted file mode 100644 index 853b10a83d8b90b07009ab7212384b6d11a36f42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8229 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 diff --git a/ziffers/__pycache__/parser.cpython-310.pyc b/ziffers/__pycache__/parser.cpython-310.pyc deleted file mode 100644 index 906f8863020697150cb3c94e7ae7eb6d3c55df6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2070 zcmZ`)OK;mo5Z>iWv>vVyxK7P*=wIQrr<`-^q38@LTQcG{j_G}ni+>V{Z@f;XCUQJNp98=GI zKzNP2CxpAgJT|=*z9QWOgB{YLMeTtKk|a=l}AGIA&S}2LQWZLCRTg z6vdq7G7)+hr2{5Mn#n#3SSXV$7P>lh5X2F`P<)QnB2pDzXmsLW=y%wpxy9}cLAMg= z4l8PtD%J`)usgZ=R0;mFy;3 zm*|AlLOLUz-ZVi>=`Yx6L?4qgx_f4LD~PY31_|6=iz9tzs#Q3s-a&!hly|DcyD%-> z%3KzH1hY4&y-6q6uXHI3|JNIJ9aX=FVgtnu6o}rErDkPGL89NZEP*Hfk3mZ`y#v?9} zQ9(LpOEqZ0&mWZR1-*C-S~R2t>U%Ck#v;vvoPn|Pf{;K;q`J#W4`97w9;QgZ4u>)p z7e2ELe1EnL4On(r5N-%lhT#RA4n z-`^hvF;Wm_HQ(nl^nJAsO4TNc4^VuFVnL8{gnTT^E&i)=?KJs@iciwr{t8*C{#}}gSrb`|#o2N1k0} zF&2E!F5&2y>SLT)S_$FR$~CE${4QNaE`A9;$8uk%4y{v#YrCD6w}v{SM5d7(<=sK` zvr~w$ckR*^R-#;?>xBgj9hTKhp+>|Iq7E2-3bP6ZGuKMtpQSXkh5L0Cl5Y{7 S98$Y}37$9*RU@@YZAd8xS2jk7egCQp1rGzwve&+^lSHCSrrXf3c zz{CRw6F7204gLZC3Eu3;66QBCA@L#?vxJ)`U$++7%X{zpe)scz-+s(wWIz&kf2{q9 z0sIP_h?1dk{u_-wFu)K@umn{Qz=#>58Cwcs#1t)}5{!WnH{+J1N&>`y5}G&^0FF@l zv>wd^HAPc~)KCCa87rlAwE9G4nlKVZ5~Jxu3>`%Y_>ww|qmR-jHDkzcLCw;fp==;> z09M2Y@?BG z)G8Iq+*uPn9)GEuo0Jn%H(7~riBVJY>OAgxI`g>X=**>zD<0Erw^C;oWos9!!B2>x zoX?@L2OjE(4ldV4L3jg$S6D=p3#Ay(hN!ggi}BtWfTph;<_5Ehe`m_i5RF@2-CV7g z!-m_=mRGIYkz4Nf&pKOtsAp=C3rM<3{?|;Duoke@>rQXAT4F8txWl3 z>Krq`lbUAfHCxjfspUJx<-5guD=Q17JSVKSR%OAZxn${%gR4n6xLmWg%A_EQdt@6d z5zeU8OsZ+UEmGU#>E}$hES=#Uy(&+H9w&8&+I(2;Kg-hpO|u-%>46Ra*}8?pSn!*C z1~wX`hEe@ZKCtS>rb!>NYv=}xa=)YMih>|?V9X!n4qWjg?!Z-lkS}NZWv9839dGyX zyY2Ve?cDWdx+9P6PqgHl&BSSbe0TIiVSoP9{jc-i=6vl1a!YgDn(ODiR^Dspy=Jyc z1mQ*(E|df$z0)`r3%*$BkW};0&g_XiaV$^lzi!FXZF#yyX4+)NkGLxW8OPe*h5rHb C?E|L( diff --git a/ziffers/__pycache__/transformer.cpython-311.pyc b/ziffers/__pycache__/transformer.cpython-311.pyc deleted file mode 100644 index dc3dc3f64432b31af5f58305bd38fbdb55d02d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8285 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 C?f#np diff --git a/ziffers/classes.py b/ziffers/classes.py index 7d82b78..8c8175d 100644 --- a/ziffers/classes.py +++ b/ziffers/classes.py @@ -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): diff --git a/ziffers/mapper.py b/ziffers/mapper.py index 78b3e05..1721342 100644 --- a/ziffers/mapper.py +++ b/ziffers/mapper.py @@ -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 "." diff --git a/ziffers/parser.py b/ziffers/parser.py index b131aaa..4862b59 100644 --- a/ziffers/parser.py +++ b/ziffers/parser.py @@ -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) \ No newline at end of file diff --git a/ziffers/ziffers.lark b/ziffers/ziffers.lark index 6fcd6d5..1b6c7bd 100644 --- a/ziffers/ziffers.lark +++ b/ziffers/ziffers.lark @@ -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)*