spiffyscore

Check-in [bd456efa03]
Login
Overview
Comment:Now parses notes, accidentals, and octaves
Timelines: family | ancestors | descendants | both | ply
Files: files | file ages | folders
SHA1:bd456efa03f4f52e38da72ce601bbb6c8b27aea8
User & Date: spiffytech@gmail.com on 2010-11-16 08:29:29
Other Links: manifest | tags
Context
2010-11-16
08:36
Now parses note duration check-in: dc8bbfb68e user: spiffytech@gmail.com tags: ply
08:29
Now parses notes, accidentals, and octaves check-in: bd456efa03 user: spiffytech@gmail.com tags: ply
2010-11-13
08:28
Added basic ABC tokenizing via the PLY module check-in: ff84293301 user: spiffytech@gmail.com tags: ply
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Modified parse.py from [17628fda61] to [b5bfbaf68d].

     1      1   #!/usr/bin/env python
     2      2   
     3      3   from ply import lex, yacc
     4      4   
            5  +# Tokenize (lex)
     5      6   tokens = (
     6         -    "NOTE",
            7  +    "NOTE_LENGTH",
            8  +    "BASENOTE",
            9  +    "ACCIDENTAL",
     7     10       "REST",
     8         -    "SHARP",
     9         -    "FLAT",
    10     11       "OCTAVE",
    11         -    "NATURAL",
    12         -    "LENGTH",
           12  +    "CHORD_TYPE",
    13     13   )
    14     14   
    15         -t_NOTE = r"[A-Ga-g]"
           15  +t_BASENOTE = r"[A-Ga-g]"
           16  +t_ACCIDENTAL = r"\^{1,2}|_{1,2}|="
    16     17   t_REST = r"z"
    17         -t_SHARP = r"\^"
    18         -t_FLAT = r"_"
    19         -t_NATURAL = r"="
    20     18   t_OCTAVE = r"'+|,+"
           19  +t_CHORD_TYPE = r"m|7|m7|0|o|\+|mb5|sus|sus4|maj7|mmaj7|7sus4|dim|dim7|7b5|m7b5|6|b6|m6|mb6|46|maj9|9|add9|7b9|m9"
    21     20   
    22         -def t_LENGTH(t):
           21  +def t_NOTE_LENGTH(t):
    23     22       r"/?\d+"
    24     23       multiplier = float(t.value.strip("/"))
    25     24       if t.value.startswith("/"):
    26     25           multiplier = 1/multiplier
    27     26       t.value = multiplier
    28     27       return t
    29     28   
................................................................................
    30     29   def t_error(t):
    31     30       raise TypeError("Unknown text '%s'" % (t.value,))
    32     31   
    33     32   t_ignore = " |"
    34     33   
    35     34   lex.lex()
    36     35   
    37         -lex.input("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD")
           36  +#lex.input("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD")
           37  +#s = "GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD"
           38  +s = "GF_G,"
           39  +lex.input(s)
    38     40   for tok in iter(lex.token, None):
    39     41       print repr(tok.type), repr(tok.value)
           42  +
           43  +
           44  +# Parse (yacc)
           45  +
           46  +class Note(object):
           47  +    def __init__(self, value, duration=.25, octave=8):
           48  +        self.value = value
           49  +        self.duration = duration
           50  +        self.octave = octave
           51  +    def __repr__(self):
           52  +        return "Note %s %s %s" % (self.value, self.duration, self.octave)
           53  +
           54  +#def p_element(p):
           55  +#    "element : note_element"
           56  +#    p[0] = p[1]
           57  +#
           58  +#def p_note_element(p):
           59  +#    '''note_element : note_element note_stem
           60  +#                     | note_stem
           61  +#    '''
           62  +#    p[0] = p[1]
           63  +#
           64  +#def p_note_stem(p):
           65  +#    '''note_stem : note'''
           66  +#    p[0] = p[1]
           67  +#
           68  +#def p_note(p):
           69  +#    '''note : note_or_rest
           70  +#            | note_or_rest NOTE_LENGTH
           71  +#    '''
           72  +#    p[0] = p[1]
           73  +#
           74  +#def p_note_or_rest(p):
           75  +#    '''note_or_rest : pitch
           76  +#                    | REST
           77  +#    '''
           78  +#    p[0] = p[1]
           79  +#
           80  +#def p_pitch(p):
           81  +
           82  +def p_pitch_list(p):
           83  +    '''score : score pitch
           84  +    '''
           85  +    p[0] = p[1] + [p[2]]
           86  +
           87  +def p_sore(p):
           88  +    '''score : pitch
           89  +    '''
           90  +    p[0] = [p[1]]
           91  +
           92  +
           93  +def p_pitch_more(p):
           94  +    ''' score : pitch NOTE_LENGTH
           95  +    '''
           96  +    print "stuff"
           97  +    new_note = p[1]
           98  +    new_note.duration = p[2]
           99  +    p[0] = new_note
          100  +
          101  +def p_pitch(p):
          102  +    '''pitch : BASENOTE
          103  +    '''
          104  +    p[0] = Note(p[1])
          105  +
          106  +def p_accidental(p):
          107  +    '''pitch : ACCIDENTAL pitch
          108  +    '''
          109  +    p[2].accidental = p[1]
          110  +    p[0] = p[2]
          111  +
          112  +def p_octave(p):
          113  +    '''pitch : pitch OCTAVE
          114  +    '''
          115  +    count = len(p[2])
          116  +    increment_or_decrement = 1 if p[2][0] == "," else -1
          117  +    octave = 8 + (count * increment_or_decrement)
          118  +    p[1].octave = octave
          119  +    p[0] = p[1]
          120  +
          121  +def p_error(p):
          122  +    print "Syntax error at '%s' of element type %s" % (p.value, p.type)
          123  +    
          124  +yacc.yacc()
          125  +
          126  +#print yacc.parse("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD")
          127  +print yacc.parse(s)