From 821030dba5a6eae935f171f79827c3b884dbed07 Mon Sep 17 00:00:00 2001 From: Louis Date: Wed, 2 Sep 2015 13:16:13 +0200 Subject: [PATCH] [chordpro] Chords parsing is less strict --- patacrep/songs/chordpro/ast.py | 19 +------- .../chordpro/data/chordpro/content_chord | 11 +---- .../songs/chordpro/data/latex/content_chord | 13 +---- patacrep/songs/chordpro/lexer.py | 2 +- patacrep/songs/chordpro/syntax.py | 48 ++++--------------- .../songs/chordpro/test/invalid_chord.sgc | 2 - .../songs/chordpro/test/invalid_chord.source | 4 +- .../songs/chordpro/test/invalid_chord.tex | 2 - .../chordpro/test/invalid_customchord.source | 6 +-- 9 files changed, 17 insertions(+), 90 deletions(-) diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 178e09ba..5cffbb86 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -145,24 +145,9 @@ class Chord(AST): _template = "chord" - def __init__( - self, - key, - alteration=None, - modifier=None, - addnote=None, - basskey=None, - bassalteration=None, - star=None, - ): + def __init__(self, chord): # pylint: disable=too-many-arguments - self.key = key - self.alteration = alteration - self.modifier = modifier - self.addnote = addnote - self.basskey = basskey - self.bassalteration = bassalteration - self.star = star + self.chord = chord class Verse(AST): """A verse (or bridge, or chorus)""" diff --git a/patacrep/songs/chordpro/data/chordpro/content_chord b/patacrep/songs/chordpro/data/chordpro/content_chord index 99e0d4c4..7d5ec6ca 100644 --- a/patacrep/songs/chordpro/data/chordpro/content_chord +++ b/patacrep/songs/chordpro/data/chordpro/content_chord @@ -1,10 +1 @@ -((- content.key -)) -(* if content.alteration *)(( content.alteration ))(* endif -*) -(* if content.modifier *)((content.modifier))(* endif -*) -(* if content.addnote *)((content.addnote))(* endif -*) -(* if content.basskey -*) - / - ((- content.basskey -)) - (* if content.bassalteration *)(( content.bassalteration ))(* endif -*) -(* if content.star *)*(* endif -*) -(* endif -*) +((- content.chord -)) diff --git a/patacrep/songs/chordpro/data/latex/content_chord b/patacrep/songs/chordpro/data/latex/content_chord index 406b75fe..61b51c8a 100644 --- a/patacrep/songs/chordpro/data/latex/content_chord +++ b/patacrep/songs/chordpro/data/latex/content_chord @@ -1,12 +1 @@ -((- content.key -)) -(* if content.alteration == '#' *)#(* endif -*) -(* if content.alteration == 'b' *)&(* endif -*) -(* if content.modifier *)((content.modifier))(* endif -*) -(* if content.addnote *)((content.addnote))(* endif -*) -(* if content.basskey -*) - / - ((- content.basskey -)) - (* if content.bassalteration == '#' *)#(* endif -*) - (* if content.bassalteration == 'b' *)&(* endif -*) -(* if content.star *)*(* endif -*) -(* endif -*) +((- content.chord|replace("b", "&") -)) diff --git a/patacrep/songs/chordpro/lexer.py b/patacrep/songs/chordpro/lexer.py index 6d47bea8..aba37a1c 100644 --- a/patacrep/songs/chordpro/lexer.py +++ b/patacrep/songs/chordpro/lexer.py @@ -39,7 +39,7 @@ class ChordProLexer: t_SPACE = r'[ \t]+' - t_chord_CHORD = r'[A-G#bmajdisus+*2-9/ ]+' + t_chord_CHORD = r'[^\]]+' t_directive_SPACE = r'[ \t]+' t_directive_KEYWORD = r'[a-zA-Z_]+' diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index 89264f68..80baf66f 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -7,24 +7,6 @@ from patacrep.songs.syntax import Parser from patacrep.songs.chordpro import ast from patacrep.songs.chordpro.lexer import tokens, ChordProLexer -CHORD_RE = re.compile( - r""" - ^ - (?P[A-G]) - (?P[b#])? - (?P(maj|sus|dim|m|\+))? - (?P[2-9])? - ( - / - (?P[A-G]) - (?P[b#])? - )? - (?P\*)? - $ - """, - re.VERBOSE - ) - class ChordproParser(Parser): """ChordPro parser class""" # pylint: disable=too-many-public-methods @@ -69,17 +51,17 @@ class ChordproParser(Parser): """ symbols[0] = None - def _parse_define(self, groups, *, symbols): + @staticmethod + def _parse_define(groups): """Parse a `{define: KEY base-fret BASE frets FRETS fingers FINGERS}` directive Return a :class:`ast.Define` object. """ # pylint: disable=too-many-branches - key = list(self._parse_chords(groups['key'], symbols=symbols)) - if len(key) != 1: + if not groups['key'].strip(): return None else: - key = key[0] + key = ast.Chord(groups['key'].strip()) if groups['basefret'] is None: basefret = None @@ -151,7 +133,7 @@ class ChordproParser(Parser): symbols[0] = ast.Error() return - symbols[0] = self._parse_define(match.groupdict(), symbols=symbols) + symbols[0] = self._parse_define(match.groupdict()) if symbols[0] is None: self.error( line=symbols.lexer.lineno, @@ -207,24 +189,10 @@ class ChordproParser(Parser): """space : SPACE""" symbols[0] = ast.Space() - def _parse_chords(self, string, *, symbols): - """Parse a list of chords. - - Iterate over :class:`ast.Chord` objects. - """ - for chord in string.split(): - match = CHORD_RE.match(chord) - if match is None: - self.error( - line=symbols.lexer.lineno, - message="Invalid chord '{}'.".format(chord), - ) - continue - yield ast.Chord(**match.groupdict()) - - def p_chord(self, symbols): + @staticmethod + def p_chord(symbols): """chord : CHORD""" - symbols[0] = ast.ChordList(*list(self._parse_chords(symbols[1], symbols=symbols))) + symbols[0] = ast.ChordList(*[ast.Chord(chord) for chord in symbols[1].split()]) @staticmethod def p_chorus(symbols): diff --git a/patacrep/songs/chordpro/test/invalid_chord.sgc b/patacrep/songs/chordpro/test/invalid_chord.sgc index 2a17e6e7..7ec4fd65 100644 --- a/patacrep/songs/chordpro/test/invalid_chord.sgc +++ b/patacrep/songs/chordpro/test/invalid_chord.sgc @@ -2,6 +2,4 @@ {start_of_verse} This is invalid. - This [A]too. - And []as well. {end_of_verse} diff --git a/patacrep/songs/chordpro/test/invalid_chord.source b/patacrep/songs/chordpro/test/invalid_chord.source index 7df0d1f9..0e63a90b 100644 --- a/patacrep/songs/chordpro/test/invalid_chord.source +++ b/patacrep/songs/chordpro/test/invalid_chord.source @@ -1,3 +1 @@ -This is [H] invalid. -This [A@]too. -And [Amm]as well. +This is [] invalid. diff --git a/patacrep/songs/chordpro/test/invalid_chord.tex b/patacrep/songs/chordpro/test/invalid_chord.tex index 8e874988..476d776a 100644 --- a/patacrep/songs/chordpro/test/invalid_chord.tex +++ b/patacrep/songs/chordpro/test/invalid_chord.tex @@ -8,8 +8,6 @@ \begin{verse} This is invalid. - This \[A]too. - And as well. \end{verse} \endsong diff --git a/patacrep/songs/chordpro/test/invalid_customchord.source b/patacrep/songs/chordpro/test/invalid_customchord.source index 9754318f..d0baf679 100644 --- a/patacrep/songs/chordpro/test/invalid_customchord.source +++ b/patacrep/songs/chordpro/test/invalid_customchord.source @@ -1,5 +1,5 @@ {define : } -{define: H base-fret 7 frets 0 1 3 3 x x} -{define: E4 base-fret H frets 0 1 3 3 x x} -{define: E4 base-fret 7 frets 0 1 3 3 x A} +{define: base-fret 7 frets 0 1 3 3 x x} +{define: E4 base-fret frets 0 1 3 3 x x} +{define: E4 base-fret H frets 0 1 3 3 x A} {define: E5 base-fret 7 frets 0 1 3 3 x x fingers - 1 2 3 - A}