spiffyscore

Hex Artifact Content
Login

Artifact 2894767aa03cfec87c6e380a6334bf18bf832b2a:


0000: 23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 70  #!/usr/bin/env p
0010: 79 74 68 6f 6e 0a 0a 69 6d 70 6f 72 74 20 74 72  ython..import tr
0020: 65 65 0a 0a 66 72 6f 6d 20 70 6c 79 20 69 6d 70  ee..from ply imp
0030: 6f 72 74 20 6c 65 78 2c 20 79 61 63 63 0a 63 6c  ort lex, yacc.cl
0040: 61 73 73 20 4e 6f 74 65 28 29 3a 0a 20 20 20 20  ass Note():.    
0050: 64 65 66 20 5f 5f 69 6e 69 74 5f 5f 28 73 65 6c  def __init__(sel
0060: 66 2c 20 76 61 6c 75 65 2c 20 64 75 72 61 74 69  f, value, durati
0070: 6f 6e 3d 31 2c 20 6f 63 74 61 76 65 3d 38 29 3a  on=1, octave=8):
0080: 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 64 75  .        self.du
0090: 72 61 74 69 6f 6e 20 3d 20 64 75 72 61 74 69 6f  ration = duratio
00a0: 6e 0a 20 20 20 20 20 20 20 20 69 66 20 76 61 6c  n.        if val
00b0: 75 65 20 3e 20 31 32 3a 0a 20 20 20 20 20 20 20  ue > 12:.       
00c0: 20 20 20 20 20 73 65 6c 66 2e 64 75 72 61 74 69       self.durati
00d0: 6f 6e 20 2b 3d 20 31 0a 20 20 20 20 20 20 20 20  on += 1.        
00e0: 20 20 20 20 76 61 6c 75 65 20 3d 20 76 61 6c 75      value = valu
00f0: 65 20 25 20 31 32 0a 20 20 20 20 20 20 20 20 73  e % 12.        s
0100: 65 6c 66 2e 76 61 6c 75 65 20 3d 20 76 61 6c 75  elf.value = valu
0110: 65 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6f  e.        self.o
0120: 63 74 61 76 65 20 3d 20 6f 63 74 61 76 65 0a 20  ctave = octave. 
0130: 20 20 20 64 65 66 20 5f 5f 72 65 70 72 5f 5f 28     def __repr__(
0140: 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 72  self):.        r
0150: 65 74 75 72 6e 20 22 4e 6f 74 65 20 25 73 20 25  eturn "Note %s %
0160: 73 20 25 73 22 20 25 20 28 73 65 6c 66 2e 76 61  s %s" % (self.va
0170: 6c 75 65 2c 20 73 65 6c 66 2e 64 75 72 61 74 69  lue, self.durati
0180: 6f 6e 2c 20 73 65 6c 66 2e 6f 63 74 61 76 65 29  on, self.octave)
0190: 0a 0a 63 6c 61 73 73 20 43 68 6f 72 64 28 29 3a  ..class Chord():
01a0: 0a 20 20 20 20 64 65 66 20 5f 5f 69 6e 69 74 5f  .    def __init_
01b0: 5f 28 73 65 6c 66 2c 20 6e 6f 74 65 73 2c 20 64  _(self, notes, d
01c0: 75 72 61 74 69 6f 6e 3d 31 29 3a 0a 20 20 20 20  uration=1):.    
01d0: 20 20 20 20 73 65 6c 66 2e 6e 6f 74 65 73 20 3d      self.notes =
01e0: 20 6e 6f 74 65 73 0a 20 20 20 20 20 20 20 20 73   notes.        s
01f0: 65 6c 66 2e 64 75 72 61 74 69 6f 6e 20 3d 20 64  elf.duration = d
0200: 75 72 61 74 69 6f 6e 0a 20 20 20 20 64 65 66 20  uration.    def 
0210: 5f 5f 72 65 70 72 5f 5f 28 73 65 6c 66 29 3a 0a  __repr__(self):.
0220: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
0230: 43 68 6f 72 64 20 25 73 22 20 25 20 28 73 65 6c  Chord %s" % (sel
0240: 66 2e 6e 6f 74 65 73 29 0a 0a 63 6c 61 73 73 20  f.notes)..class 
0250: 52 65 73 74 28 29 3a 0a 20 20 20 20 64 65 66 20  Rest():.    def 
0260: 5f 5f 69 6e 69 74 5f 5f 28 73 65 6c 66 2c 20 64  __init__(self, d
0270: 75 72 61 74 69 6f 6e 3d 31 29 3a 0a 20 20 20 20  uration=1):.    
0280: 20 20 20 20 73 65 6c 66 2e 64 75 72 61 74 69 6f      self.duratio
0290: 6e 20 3d 20 64 75 72 61 74 69 6f 6e 0a 20 20 20  n = duration.   
02a0: 20 64 65 66 20 5f 5f 72 65 70 72 5f 5f 28 73 65   def __repr__(se
02b0: 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 72 65 74  lf):.        ret
02c0: 75 72 6e 20 22 52 65 73 74 20 6e 6f 64 65 20 25  urn "Rest node %
02d0: 73 22 20 25 20 73 65 6c 66 2e 64 75 72 61 74 69  s" % self.durati
02e0: 6f 6e 0a 0a 0a 64 65 66 20 70 61 72 73 65 28 73  on...def parse(s
02f0: 63 6f 72 65 2c 20 64 65 66 61 75 6c 74 5f 6f 63  core, default_oc
0300: 74 61 76 65 3d 38 29 3a 0a 20 20 20 20 23 20 54  tave=8):.    # T
0310: 6f 6b 65 6e 69 7a 65 20 28 6c 65 78 29 0a 20 20  okenize (lex).  
0320: 20 20 74 6f 6b 65 6e 73 20 3d 20 28 0a 20 20 20    tokens = (.   
0330: 20 20 20 20 20 22 4e 4f 54 45 5f 4c 45 4e 47 54       "NOTE_LENGT
0340: 48 22 2c 0a 20 20 20 20 20 20 20 20 22 42 41 53  H",.        "BAS
0350: 45 4e 4f 54 45 22 2c 0a 20 20 20 20 20 20 20 20  ENOTE",.        
0360: 22 41 43 43 49 44 45 4e 54 41 4c 22 2c 0a 20 20  "ACCIDENTAL",.  
0370: 20 20 20 20 20 20 22 52 45 53 54 22 2c 0a 20 20        "REST",.  
0380: 20 20 20 20 20 20 22 4f 43 54 41 56 45 22 2c 0a        "OCTAVE",.
0390: 20 20 20 20 20 20 20 20 22 43 48 4f 52 44 5f 54          "CHORD_T
03a0: 59 50 45 22 2c 0a 20 20 20 20 20 20 20 20 22 42  YPE",.        "B
03b0: 52 41 43 4b 45 54 22 2c 0a 20 20 20 20 20 20 20  RACKET",.       
03c0: 20 22 53 59 4e 43 4f 50 41 54 45 22 2c 0a 20 20   "SYNCOPATE",.  
03d0: 20 20 20 20 20 20 22 4e 4f 44 45 22 2c 0a 20 20        "NODE",.  
03e0: 20 20 29 0a 0a 20 20 20 20 74 5f 69 67 6e 6f 72    )..    t_ignor
03f0: 65 20 3d 20 22 20 7c 22 0a 0a 20 20 20 20 74 5f  e = " |"..    t_
0400: 42 41 53 45 4e 4f 54 45 20 3d 20 72 22 5b 41 2d  BASENOTE = r"[A-
0410: 47 61 2d 67 5d 22 0a 23 20 20 20 20 74 5f 42 41  Ga-g]".#    t_BA
0420: 53 45 4e 4f 54 45 20 3d 20 72 22 49 2b 56 3f 7c  SENOTE = r"I+V?|
0430: 56 49 2a 7c 69 2b 76 3f 7c 76 69 2a 22 0a 20 20  VI*|i+v?|vi*".  
0440: 20 20 74 5f 41 43 43 49 44 45 4e 54 41 4c 20 3d    t_ACCIDENTAL =
0450: 20 72 22 5c 5e 7b 31 7d 7c 5f 7b 31 7d 7c 3d 22   r"\^{1}|_{1}|="
0460: 0a 20 20 20 20 74 5f 52 45 53 54 20 3d 20 72 22  .    t_REST = r"
0470: 7a 22 0a 20 20 20 20 74 5f 4f 43 54 41 56 45 20  z".    t_OCTAVE 
0480: 3d 20 72 22 27 2b 7c 2c 2b 22 0a 20 20 20 20 74  = r"'+|,+".    t
0490: 5f 43 48 4f 52 44 5f 54 59 50 45 20 3d 20 72 22  _CHORD_TYPE = r"
04a0: 6d 7c 37 7c 6d 37 7c 30 7c 6f 7c 5c 2b 7c 6d 62  m|7|m7|0|o|\+|mb
04b0: 35 7c 73 75 73 7c 73 75 73 34 7c 6d 61 6a 37 7c  5|sus|sus4|maj7|
04c0: 6d 6d 61 6a 37 7c 37 73 75 73 34 7c 64 69 6d 7c  mmaj7|7sus4|dim|
04d0: 64 69 6d 37 7c 37 62 35 7c 6d 37 62 35 7c 36 7c  dim7|7b5|m7b5|6|
04e0: 62 36 7c 6d 36 7c 6d 62 36 7c 34 36 7c 6d 61 6a  b6|m6|mb6|46|maj
04f0: 39 7c 39 7c 61 64 64 39 7c 37 62 39 7c 6d 39 22  9|9|add9|7b9|m9"
0500: 0a 20 20 20 20 74 5f 42 52 41 43 4b 45 54 20 3d  .    t_BRACKET =
0510: 20 72 22 5c 5b 7c 5c 5d 22 0a 20 20 20 20 74 5f   r"\[|\]".    t_
0520: 53 59 4e 43 4f 50 41 54 45 20 3d 20 22 5c 2b 7c  SYNCOPATE = "\+|
0530: 2d 22 0a 20 20 20 20 74 5f 4e 4f 44 45 20 3d 20  -".    t_NODE = 
0540: 72 22 5c 28 5b 61 2d 7a 41 2d 5a 30 2d 39 5f 2d  r"\([a-zA-Z0-9_-
0550: 5d 2b 5c 29 22 0a 0a 20 20 20 20 64 65 66 20 74  ]+\)"..    def t
0560: 5f 4e 4f 54 45 5f 4c 45 4e 47 54 48 28 74 29 3a  _NOTE_LENGTH(t):
0570: 0a 20 20 20 20 20 20 20 20 72 22 2f 3f 5c 64 2b  .        r"/?\d+
0580: 22 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 70  ".        multip
0590: 6c 69 65 72 20 3d 20 66 6c 6f 61 74 28 74 2e 76  lier = float(t.v
05a0: 61 6c 75 65 2e 73 74 72 69 70 28 22 2f 22 29 29  alue.strip("/"))
05b0: 0a 20 20 20 20 20 20 20 20 69 66 20 74 2e 76 61  .        if t.va
05c0: 6c 75 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  lue.startswith("
05d0: 2f 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  /"):.           
05e0: 20 6d 75 6c 74 69 70 6c 69 65 72 20 3d 20 31 2f   multiplier = 1/
05f0: 6d 75 6c 74 69 70 6c 69 65 72 0a 20 20 20 20 20  multiplier.     
0600: 20 20 20 74 2e 76 61 6c 75 65 20 3d 20 6d 75 6c     t.value = mul
0610: 74 69 70 6c 69 65 72 0a 20 20 20 20 20 20 20 20  tiplier.        
0620: 72 65 74 75 72 6e 20 74 0a 0a 20 20 20 20 64 65  return t..    de
0630: 66 20 74 5f 65 72 72 6f 72 28 74 29 3a 0a 20 20  f t_error(t):.  
0640: 20 20 20 20 20 20 72 61 69 73 65 20 54 79 70 65        raise Type
0650: 45 72 72 6f 72 28 22 55 6e 6b 6e 6f 77 6e 20 74  Error("Unknown t
0660: 65 78 74 20 27 25 73 27 22 20 25 20 28 74 2e 76  ext '%s'" % (t.v
0670: 61 6c 75 65 2c 29 29 0a 0a 20 20 20 20 6c 65 78  alue,))..    lex
0680: 2e 6c 65 78 28 29 0a 20 20 20 20 6c 65 78 2e 69  .lex().    lex.i
0690: 6e 70 75 74 28 73 63 6f 72 65 29 0a 0a 0a 20 20  nput(score)...  
06a0: 20 20 23 20 50 61 72 73 65 20 28 79 61 63 63 29    # Parse (yacc)
06b0: 0a 0a 20 20 20 20 64 65 66 20 70 5f 6e 6f 74 65  ..    def p_note
06c0: 5f 6c 69 73 74 28 70 29 3a 0a 20 20 20 20 20 20  _list(p):.      
06d0: 20 20 27 27 27 73 63 6f 72 65 20 3a 20 73 63 6f    '''score : sco
06e0: 72 65 20 6e 6f 74 65 0a 20 20 20 20 20 20 20 20  re note.        
06f0: 20 20 20 20 20 20 20 20 20 7c 20 73 63 6f 72 65           | score
0700: 20 63 68 6f 72 64 0a 20 20 20 20 20 20 20 20 20   chord.         
0710: 20 20 20 20 20 20 20 20 7c 20 73 63 6f 72 65 20          | score 
0720: 72 65 73 74 0a 20 20 20 20 20 20 20 20 20 20 20  rest.           
0730: 20 7c 20 73 63 6f 72 65 20 6e 6f 64 65 0a 20 20   | score node.  
0740: 20 20 20 20 20 20 27 27 27 0a 20 20 20 20 20 20        '''.      
0750: 20 20 70 5b 30 5d 20 3d 20 70 5b 31 5d 20 2b 20    p[0] = p[1] + 
0760: 5b 70 5b 32 5d 5d 0a 0a 20 20 20 20 64 65 66 20  [p[2]]..    def 
0770: 70 5f 73 63 6f 72 65 28 70 29 3a 0a 20 20 20 20  p_score(p):.    
0780: 20 20 20 20 27 27 27 73 63 6f 72 65 20 3a 20 6e      '''score : n
0790: 6f 74 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  ote.            
07a0: 20 20 20 20 20 7c 20 63 68 6f 72 64 0a 20 20 20       | chord.   
07b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7c 20                | 
07c0: 72 65 73 74 0a 20 20 20 20 20 20 20 20 20 20 20  rest.           
07d0: 20 7c 20 6e 6f 64 65 0a 20 20 20 20 20 20 20 20   | node.        
07e0: 27 27 27 0a 20 20 20 20 20 20 20 20 70 5b 30 5d  '''.        p[0]
07f0: 20 3d 20 5b 70 5b 31 5d 5d 0a 0a 0a 20 20 20 20   = [p[1]]...    
0800: 64 65 66 20 70 5f 63 68 6f 72 64 5f 6c 65 6e 67  def p_chord_leng
0810: 74 68 28 70 29 3a 0a 20 20 20 20 20 20 20 20 27  th(p):.        '
0820: 27 27 20 63 68 6f 72 64 20 3a 20 63 68 6f 72 64  '' chord : chord
0830: 20 4e 4f 54 45 5f 4c 45 4e 47 54 48 0a 20 20 20   NOTE_LENGTH.   
0840: 20 20 20 20 20 27 27 27 0a 20 20 20 20 20 20 20       '''.       
0850: 20 6e 65 77 5f 6e 6f 74 65 20 3d 20 70 5b 31 5d   new_note = p[1]
0860: 0a 20 20 20 20 20 20 20 20 6e 65 77 5f 6e 6f 74  .        new_not
0870: 65 2e 64 75 72 61 74 69 6f 6e 20 3d 20 70 5b 32  e.duration = p[2
0880: 5d 0a 20 20 20 20 20 20 20 20 70 5b 30 5d 20 3d  ].        p[0] =
0890: 20 6e 65 77 5f 6e 6f 74 65 0a 0a 0a 20 20 20 20   new_note...    
08a0: 64 65 66 20 70 5f 6e 6f 74 65 5f 6c 65 6e 67 74  def p_note_lengt
08b0: 68 28 70 29 3a 0a 20 20 20 20 20 20 20 20 27 27  h(p):.        ''
08c0: 27 20 6e 6f 74 65 20 3a 20 6e 6f 74 65 20 4e 4f  ' note : note NO
08d0: 54 45 5f 4c 45 4e 47 54 48 0a 20 20 20 20 20 20  TE_LENGTH.      
08e0: 20 20 27 27 27 0a 20 20 20 20 20 20 20 20 6e 65    '''.        ne
08f0: 77 5f 6e 6f 74 65 20 3d 20 70 5b 31 5d 0a 20 20  w_note = p[1].  
0900: 20 20 20 20 20 20 6e 65 77 5f 6e 6f 74 65 2e 64        new_note.d
0910: 75 72 61 74 69 6f 6e 20 3d 20 70 5b 32 5d 0a 20  uration = p[2]. 
0920: 20 20 20 20 20 20 20 70 5b 30 5d 20 3d 20 6e 65         p[0] = ne
0930: 77 5f 6e 6f 74 65 0a 0a 0a 20 20 20 20 64 65 66  w_note...    def
0940: 20 70 5f 63 68 6f 72 64 28 70 29 3a 0a 20 20 20   p_chord(p):.   
0950: 20 20 20 20 20 27 27 27 63 68 6f 72 64 20 3a 20       '''chord : 
0960: 42 52 41 43 4b 45 54 20 6e 6f 74 65 20 42 52 41  BRACKET note BRA
0970: 43 4b 45 54 0a 20 20 20 20 20 20 20 20 20 20 20  CKET.           
0980: 20 20 20 20 20 20 7c 20 42 52 41 43 4b 45 54 20        | BRACKET 
0990: 6e 6f 74 65 20 43 48 4f 52 44 5f 54 59 50 45 20  note CHORD_TYPE 
09a0: 42 52 41 43 4b 45 54 0a 20 20 20 20 20 20 20 20  BRACKET.        
09b0: 27 27 27 0a 0a 20 20 20 20 20 20 20 20 69 66 20  '''..        if 
09c0: 6c 65 6e 28 70 29 20 3e 20 33 3a 0a 20 20 20 20  len(p) > 3:.    
09d0: 20 20 20 20 20 20 20 20 63 68 6f 72 64 65 64 5f          chorded_
09e0: 6e 6f 74 65 73 20 3d 20 5b 5d 0a 20 20 20 20 20  notes = [].     
09f0: 20 20 20 20 20 20 20 72 6f 6f 74 5f 6e 6f 74 65         root_note
0a00: 20 3d 20 70 5b 32 5d 2e 76 61 6c 75 65 0a 20 20   = p[2].value.  
0a10: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 6f 66            for of
0a20: 66 73 65 74 20 69 6e 20 5b 30 2c 20 34 2c 20 37  fset in [0, 4, 7
0a30: 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]:.             
0a40: 20 20 20 63 68 6f 72 64 65 64 5f 6e 6f 74 65 73     chorded_notes
0a50: 2e 61 70 70 65 6e 64 28 4e 6f 74 65 28 72 6f 6f  .append(Note(roo
0a60: 74 5f 6e 6f 74 65 2b 6f 66 66 73 65 74 2c 20 6f  t_note+offset, o
0a70: 63 74 61 76 65 3d 70 5b 32 5d 2e 6f 63 74 61 76  ctave=p[2].octav
0a80: 65 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  e)).            
0a90: 63 68 6f 72 64 20 3d 20 43 68 6f 72 64 28 6e 6f  chord = Chord(no
0aa0: 74 65 73 3d 63 68 6f 72 64 65 64 5f 6e 6f 74 65  tes=chorded_note
0ab0: 73 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a  s).        else:
0ac0: 20 20 23 20 54 68 69 73 20 77 6f 6e 27 6b 20 77    # This won'k w
0ad0: 6f 72 6b 20 75 6e 74 69 6c 20 74 68 65 20 67 72  ork until the gr
0ae0: 61 6d 6d 61 72 20 69 73 20 6d 6f 64 69 66 69 65  ammar is modifie
0af0: 64 20 74 6f 20 72 6f 63 6f 67 6e 69 73 65 20 6d  d to rocognise m
0b00: 75 6c 74 69 70 6c 65 20 6e 6f 74 65 73 20 62 6f  ultiple notes bo
0b10: 74 77 65 65 6e 20 62 72 61 63 6b 65 74 73 0a 20  tween brackets. 
0b20: 20 20 20 20 20 20 20 20 20 20 20 63 68 6f 72 64             chord
0b30: 20 3d 20 70 5b 31 3a 2d 32 5d 0a 20 20 20 20 20   = p[1:-2].     
0b40: 20 20 20 20 20 20 20 20 20 20 20 0a 0a 20 20 20             ..   
0b50: 20 20 20 20 20 70 5b 30 5d 20 3d 20 63 68 6f 72       p[0] = chor
0b60: 64 0a 0a 0a 20 20 20 20 64 65 66 20 70 5f 6e 6f  d...    def p_no
0b70: 74 65 5f 73 79 6e 63 6f 70 61 74 65 28 70 29 3a  te_syncopate(p):
0b80: 0a 20 20 20 20 20 20 20 20 27 27 27 20 6e 6f 74  .        ''' not
0b90: 65 20 3a 20 6e 6f 74 65 20 53 59 4e 43 4f 50 41  e : note SYNCOPA
0ba0: 54 45 0a 20 20 20 20 20 20 20 20 27 27 27 0a 20  TE.        '''. 
0bb0: 20 20 20 20 20 20 20 6e 6f 74 65 2e 73 79 6e 63         note.sync
0bc0: 6f 70 61 74 65 20 3d 20 70 5b 32 5d 0a 0a 0a 20  opate = p[2]... 
0bd0: 20 20 20 64 65 66 20 70 5f 61 63 63 69 64 65 6e     def p_acciden
0be0: 74 61 6c 28 70 29 3a 0a 20 20 20 20 20 20 20 20  tal(p):.        
0bf0: 27 27 27 6e 6f 74 65 20 3a 20 41 43 43 49 44 45  '''note : ACCIDE
0c00: 4e 54 41 4c 20 6e 6f 74 65 0a 20 20 20 20 20 20  NTAL note.      
0c10: 20 20 27 27 27 0a 20 20 20 20 20 20 20 20 69 66    '''.        if
0c20: 20 70 5b 31 5d 20 3d 3d 20 22 5e 22 3a 0a 20 20   p[1] == "^":.  
0c30: 20 20 20 20 20 20 20 20 20 20 70 5b 32 5d 2e 76            p[2].v
0c40: 61 6c 75 65 20 2b 3d 20 31 0a 20 20 20 20 20 20  alue += 1.      
0c50: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
0c60: 20 20 20 20 70 5b 32 5d 2e 76 61 6c 75 65 20 2d      p[2].value -
0c70: 3d 20 31 0a 20 20 20 20 20 20 20 20 70 5b 30 5d  = 1.        p[0]
0c80: 20 3d 20 70 5b 32 5d 0a 0a 20 20 20 20 64 65 66   = p[2]..    def
0c90: 20 70 5f 6f 63 74 61 76 65 28 70 29 3a 0a 20 20   p_octave(p):.  
0ca0: 20 20 20 20 20 20 27 27 27 6e 6f 74 65 20 3a 20        '''note : 
0cb0: 6e 6f 74 65 20 4f 43 54 41 56 45 0a 20 20 20 20  note OCTAVE.    
0cc0: 20 20 20 20 27 27 27 0a 20 20 20 20 20 20 20 20      '''.        
0cd0: 63 6f 75 6e 74 20 3d 20 6c 65 6e 28 70 5b 32 5d  count = len(p[2]
0ce0: 29 0a 20 20 20 20 20 20 20 20 69 6e 63 72 65 6d  ).        increm
0cf0: 65 6e 74 5f 6f 72 5f 64 65 63 72 65 6d 65 6e 74  ent_or_decrement
0d00: 20 3d 20 31 20 69 66 20 70 5b 32 5d 2e 73 74 61   = 1 if p[2].sta
0d10: 72 74 73 77 69 74 68 28 22 27 22 29 20 65 6c 73  rtswith("'") els
0d20: 65 20 2d 31 0a 20 20 20 20 20 20 20 20 70 5b 31  e -1.        p[1
0d30: 5d 2e 6f 63 74 61 76 65 20 2b 3d 20 28 63 6f 75  ].octave += (cou
0d40: 6e 74 20 2a 20 69 6e 63 72 65 6d 65 6e 74 5f 6f  nt * increment_o
0d50: 72 5f 64 65 63 72 65 6d 65 6e 74 29 0a 20 20 20  r_decrement).   
0d60: 20 20 20 20 20 70 5b 30 5d 20 3d 20 70 5b 31 5d       p[0] = p[1]
0d70: 0a 0a 20 20 20 20 64 65 66 20 70 5f 6e 6f 74 65  ..    def p_note
0d80: 28 70 29 3a 0a 20 20 20 20 20 20 20 20 27 27 27  (p):.        '''
0d90: 6e 6f 74 65 20 3a 20 42 41 53 45 4e 4f 54 45 0a  note : BASENOTE.
0da0: 20 20 20 20 20 20 20 20 27 27 27 0a 20 20 20 20          '''.    
0db0: 20 20 20 20 6e 6f 74 65 73 20 3d 20 7b 0a 20 20      notes = {.  
0dc0: 20 20 20 20 20 20 20 20 20 20 22 43 22 3a 20 30            "C": 0
0dd0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 22 44  ,.            "D
0de0: 22 3a 20 32 2c 0a 20 20 20 20 20 20 20 20 20 20  ": 2,.          
0df0: 20 20 22 45 22 3a 20 34 2c 0a 20 20 20 20 20 20    "E": 4,.      
0e00: 20 20 20 20 20 20 22 46 22 3a 20 35 2c 0a 20 20        "F": 5,.  
0e10: 20 20 20 20 20 20 20 20 20 20 22 47 22 3a 20 37            "G": 7
0e20: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 22 41  ,.            "A
0e30: 22 3a 20 39 2c 0a 20 20 20 20 20 20 20 20 20 20  ": 9,.          
0e40: 20 20 22 42 22 3a 20 31 31 0a 20 20 20 20 20 20    "B": 11.      
0e50: 20 20 7d 0a 20 20 20 20 20 20 20 20 6e 20 3d 20    }.        n = 
0e60: 6e 6f 74 65 73 5b 70 5b 31 5d 5d 0a 20 20 20 20  notes[p[1]].    
0e70: 20 20 20 20 70 5b 30 5d 20 3d 20 4e 6f 74 65 28      p[0] = Note(
0e80: 6e 2c 20 6f 63 74 61 76 65 3d 64 65 66 61 75 6c  n, octave=defaul
0e90: 74 5f 6f 63 74 61 76 65 29 0a 0a 20 20 20 20 64  t_octave)..    d
0ea0: 65 66 20 70 5f 72 65 73 74 28 70 29 3a 0a 20 20  ef p_rest(p):.  
0eb0: 20 20 20 20 20 20 27 27 27 20 72 65 73 74 20 3a        ''' rest :
0ec0: 20 52 45 53 54 0a 20 20 20 20 20 20 20 20 20 20   REST.          
0ed0: 20 20 20 20 20 20 20 7c 20 52 45 53 54 20 4e 4f         | REST NO
0ee0: 54 45 5f 4c 45 4e 47 54 48 0a 20 20 20 20 20 20  TE_LENGTH.      
0ef0: 20 20 27 27 27 0a 20 20 20 20 20 20 20 20 70 5b    '''.        p[
0f00: 30 5d 20 3d 20 52 65 73 74 28 29 0a 20 20 20 20  0] = Rest().    
0f10: 20 20 20 20 69 66 20 6c 65 6e 28 70 29 20 3e 20      if len(p) > 
0f20: 32 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  2:.            p
0f30: 5b 30 5d 2e 64 75 72 61 74 69 6f 6e 20 3d 20 70  [0].duration = p
0f40: 5b 32 5d 0a 0a 20 20 20 20 64 65 66 20 70 5f 6e  [2]..    def p_n
0f50: 6f 64 65 28 70 29 3a 0a 20 20 20 20 20 20 20 20  ode(p):.        
0f60: 27 27 27 6e 6f 64 65 20 3a 20 4e 4f 44 45 0a 20  '''node : NODE. 
0f70: 20 20 20 20 20 20 20 27 27 27 0a 20 20 20 20 20         '''.     
0f80: 20 20 20 70 5b 30 5d 20 3d 20 74 72 65 65 2e 54     p[0] = tree.T
0f90: 72 65 65 28 70 5b 31 5d 2e 73 74 72 69 70 28 22  ree(p[1].strip("
0fa0: 28 22 29 2e 73 74 72 69 70 28 22 29 22 29 29 0a  (").strip(")")).
0fb0: 0a 0a 20 20 20 20 64 65 66 20 70 5f 65 72 72 6f  ..    def p_erro
0fc0: 72 28 70 29 3a 0a 23 20 20 20 20 20 20 20 20 69  r(p):.#        i
0fd0: 6d 70 6f 72 74 20 69 70 64 62 0a 23 20 20 20 20  mport ipdb.#    
0fe0: 20 20 20 20 69 70 64 62 2e 73 65 74 5f 74 72 61      ipdb.set_tra
0ff0: 63 65 28 29 0a 20 20 20 20 20 20 20 20 70 72 69  ce().        pri
1000: 6e 74 20 70 0a 20 20 20 20 20 20 20 20 72 61 69  nt p.        rai
1010: 73 65 20 45 78 63 65 70 74 69 6f 6e 28 22 53 79  se Exception("Sy
1020: 6e 74 61 78 20 65 72 72 6f 72 20 61 74 20 27 25  ntax error at '%
1030: 73 27 20 6f 66 20 65 6c 65 6d 65 6e 74 20 74 79  s' of element ty
1040: 70 65 20 25 73 22 20 25 20 28 70 2e 76 61 6c 75  pe %s" % (p.valu
1050: 65 2c 20 70 2e 74 79 70 65 29 29 0a 20 20 20 20  e, p.type)).    
1060: 20 20 20 20 0a 20 20 20 20 79 61 63 63 2e 79 61      .    yacc.ya
1070: 63 63 28 29 0a 0a 20 20 20 20 72 65 74 75 72 6e  cc()..    return
1080: 20 79 61 63 63 2e 70 61 72 73 65 28 73 63 6f 72   yacc.parse(scor
1090: 65 29 0a                                         e).