Add powerset to list_utils; improve chord parser.
[python_utils.git] / music / chords.g4
1 // © Copyright 2022, Scott Gasch
2 //
3 // antlr4 -Dlanguage=Python3 ./chords.g4
4 //
5 // Hi, self.  In ANTLR grammars, there are two separate types of symbols: those
6 // for the lexer and those for the parser.  The former begin with a CAPITAL
7 // whereas the latter begin with lowercase.  The order of the lexer symbols
8 // is the order that the lexer will recognize them in.  There's a good tutorial
9 // on this shit at:
10 //
11 //    https://tomassetti.me/antlr-mega-tutorial/
12 //
13 // There are also a zillion premade grammars at:
14 //
15 //    https://github.com/antlr/grammars-v4
16
17 grammar chords;
18
19 parse
20     : rootNote majMinSusPowerExpr* addNotesExpr* extensionExpr* overBassNoteExpr*
21     ;
22
23 rootNote
24     : NOTE
25     ;
26
27 overBassNoteExpr
28     : SLASH NOTE
29     ;
30
31 majMinSusPowerExpr
32     : majExpr
33     | minExpr
34     | susExpr
35     | diminishedExpr
36     | augmentedExpr
37     | powerChordExpr
38     ;
39
40 majExpr: MAJOR;
41
42 minExpr: MINOR;
43
44 susExpr: SUS ('2'|'4');
45
46 diminishedExpr: DIMINISHED;
47
48 augmentedExpr: AUGMENTED;
49
50 powerChordExpr: '5';
51
52 addNotesExpr
53     : ADD* SIX
54     | ADD* SEVEN
55     | MAJ_SEVEN
56     | ADD* NINE
57     | ADD* ELEVEN
58     ;
59
60 extensionExpr
61     : INTERVAL
62     ;
63
64 SPACE: [ \t\r\n] -> skip;
65
66 NOTE: (AS|BS|CS|DS|ES|FS|GS) ;
67
68 AS
69     : ('A'|'a')
70     | ('Ab'|'ab')
71     | ('A#'|'a#')
72     ;
73
74 BS
75     : ('B'|'b')
76     | ('Bb'|'bb')
77     ;
78
79 CS
80     : ('C'|'c')
81     | ('C#'|'c#')
82     ;
83
84 DS
85     : ('D'|'d')
86     | ('Db'|'db')
87     | ('D#'|'d#')
88     ;
89
90 ES
91     : ('E'|'e')
92     | ('Eb'|'eb')
93     ;
94
95 FS
96     : ('F'|'f')
97     | ('F#'|'f#')
98     ;
99
100 GS
101     : ('G'|'g')
102     | ('Gb'|'gb')
103     | ('G#'|'g#')
104     ;
105
106 MAJOR: ('M'|'Maj'|'maj'|'Major'|'major');
107
108 MINOR: ('m'|'min'|'minor');
109
110 SUS: ('sus'|'suspended');
111
112 DIMINISHED: ('dim'|'diminished'|'-');
113
114 AUGMENTED: ('aug'|'augmented'|'+');
115
116 SLASH: ('/'|'\\');
117
118 ADD: ('add'|'Add'|'dom');
119
120 SIX: '6';
121
122 SEVEN: '7';
123
124 NINE: '9';
125
126 ELEVEN: '11';
127
128 MAJ_SEVEN: MAJOR '7';
129
130 INTERVAL: (MAJOR|MINOR)* ('b'|'#')* DIGITS ;
131
132 DIGITS: [1-9]+ ;