Chord name parsing.
[python_utils.git] / music / chords.g4
diff --git a/music/chords.g4 b/music/chords.g4
new file mode 100644 (file)
index 0000000..bd180a9
--- /dev/null
@@ -0,0 +1,127 @@
+// © Copyright 2022, Scott Gasch
+//
+// antlr4 -Dlanguage=Python3 ./chords.g4
+//
+// Hi, self.  In ANTLR grammars, there are two separate types of symbols: those
+// for the lexer and those for the parser.  The former begin with a CAPITAL
+// whereas the latter begin with lowercase.  The order of the lexer symbols
+// is the order that the lexer will recognize them in.  There's a good tutorial
+// on this shit at:
+//
+//    https://tomassetti.me/antlr-mega-tutorial/
+//
+// There are also a zillion premade grammars at:
+//
+//    https://github.com/antlr/grammars-v4
+
+grammar chords;
+
+parse
+    : rootNote majMinSusPowerExpr* addNotesExpr* extensionExpr* overBassNoteExpr*
+    ;
+
+rootNote
+    : NOTE
+    ;
+
+overBassNoteExpr
+    : SLASH NOTE
+    ;
+
+majMinSusPowerExpr
+    : majExpr
+    | minExpr
+    | susExpr
+    | diminishedExpr
+    | augmentedExpr
+    | powerChordExpr
+    ;
+
+majExpr: MAJOR;
+
+minExpr: MINOR;
+
+susExpr: SUS ('2'|'4');
+
+diminishedExpr: DIMINISHED;
+
+augmentedExpr: AUGMENTED;
+
+powerChordExpr: '5';
+
+addNotesExpr
+    : SIX
+    | SEVEN
+    | MAJ_SEVEN
+    | ADD_NINE
+    ;
+
+extensionExpr
+    : INTERVAL
+    ;
+
+SPACE: [ \t\r\n] -> skip;
+
+NOTE: (AS|BS|CS|DS|ES|FS|GS) ;
+
+AS
+    : ('A'|'a')
+    | ('Ab'|'ab')
+    | ('A#'|'a#')
+    ;
+
+BS
+    : ('B'|'b')
+    | ('Bb'|'bb')
+    ;
+
+CS
+    : ('C'|'c')
+    | ('C#'|'c#')
+    ;
+
+DS
+    : ('D'|'d')
+    | ('Db'|'db')
+    | ('D#'|'d#')
+    ;
+
+ES
+    : ('E'|'e')
+    | ('Eb'|'eb')
+    ;
+
+FS
+    : ('F'|'f')
+    | ('F#'|'f#')
+    ;
+
+GS
+    : ('G'|'g')
+    | ('Gb'|'gb')
+    | ('G#'|'g#')
+    ;
+
+MAJOR: ('M'|'Maj'|'maj'|'Major'|'major');
+
+MINOR: ('m'|'min'|'minor');
+
+SUS: ('sus'|'suspended');
+
+DIMINISHED: ('dim'|'diminished');
+
+AUGMENTED: ('aug'|'augmented');
+
+SLASH: ('/'|'\\');
+
+SIX: '6';
+
+SEVEN: '7';
+
+MAJ_SEVEN: MAJOR '7';
+
+ADD_NINE: ('add'|'Add')* '9';
+
+INTERVAL: (MAJOR|MINOR)* ('b'|'#')* DIGITS ;
+
+DIGITS: [1-9]+ ;