-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSongLexer.py
96 lines (79 loc) · 2.37 KB
/
SongLexer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"Defines constants and tokens for the lexer portion of this program"
from ply import lex
#----------------------
# Constant Definitions
#----------------------
KEY_NOTES = "1!2@34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm"
# Not key notes: - _ = + [ ] { } \ | ; : ' " , < . > / ?
# Also not key notes: # & ) R U A F K X N M
_TRANSLATE_TABLE = { # Keys that require the shift modifier
'!': '1', '@': '2', '#': '3', '$': '4', '%': '5',
'^': '6', '&': '7', '*': '8', '(': '9', ')': '0',
'~': '`', '_': '-', '+': '=', '{': '[', '}': ']',
'|':'\\', ':': ';', '"': "'", '<': ',', '>': '.', '?': '/',
'A': 'a', 'B': 'b', 'C': 'c', 'D': 'd', 'E': 'e',
'F': 'f', 'G': 'g', 'H': 'h', 'I': 'i', 'J': 'j',
'K': 'k', 'L': 'l', 'M': 'm', 'N': 'n', 'O': 'o',
'P': 'p', 'Q': 'q', 'R': 'r', 'S': 's', 'T': 't',
'U': 'u', 'V': 'v', 'W': 'w', 'X': 'x', 'Y': 'y', 'Z': 'z',
}
_REV_TRANSLATE_TABLE = {v:k for k,v in _TRANSLATE_TABLE.items()}
REGULAR_NOTES = "".join(key for key in KEY_NOTES if key not in _TRANSLATE_TABLE)
SHIFTED_NOTES = "".join(key for key in KEY_NOTES if key in _TRANSLATE_TABLE)
#-------------------
# Token Definitions
#-------------------
states = (
('code', 'exclusive'),
)
tokens = (
"NOTE",
"SHIFTED_NOTE",
"REST",
"LEFT_PAREN_SQUARE",
"RIGHT_PAREN_SQUARE",
"LEFT_PAREN_CURLY",
"RIGHT_PAREN_CURLY",
"APOSTROPHE",
"LEFT_PAREN_ANGLED",
"RIGHT_PAREN_ANGLED",
"ID",
"EQUALS",
"NUMBER",
)
def t_COMMENT (_):
r";.*?(?:;|\n|$)"
pass
def t_LEFT_PAREN_ANGLED (t):
r"<"
t.lexer.begin('code')
def t_code_RIGHT_PAREN_ANGLED (t):
r">"
t.lexer.begin('INITIAL')
def t_code_ID (t):
r"[bB][pP][mM]"
t.value = t.value.lower()
return t
def t_code_NUMBER (t):
r"\d+(?:\.\d+)?"
t.value = float(t.value)
return t
t_REST = r"~"
t_LEFT_PAREN_SQUARE = r"\["
t_RIGHT_PAREN_SQUARE = r"\]"
t_LEFT_PAREN_CURLY = r"{"
t_RIGHT_PAREN_CURLY = r"}"
t_APOSTROPHE = r"'"
t_NOTE = r"[" + REGULAR_NOTES + "]"
t_SHIFTED_NOTE = "[" + SHIFTED_NOTES + "]"
t_code_EQUALS = r"="
t_ignore = " \t\n"
t_code_ignore = " \t\n"
def t_error (t):
print('Illegal character "%s"' % t.value[0])
t.lexer.skip(1)
def t_code_error (t):
print('Illegal code character "%s"' % t.value[0])
t.lexer.skip(1)
##################
lexer = lex.lex()