diff --git a/patacrep/songs/chordpro/ast.py b/patacrep/songs/chordpro/ast.py index 02ba1632..8d287a79 100644 --- a/patacrep/songs/chordpro/ast.py +++ b/patacrep/songs/chordpro/ast.py @@ -64,6 +64,10 @@ class AST: """Generic object representing elements of the song.""" _template = None inline = False + lexer = None + + def __init__(self): + self.lineno = self.lexer.lineno def template(self): """Return the template to be used to render this object.""" @@ -140,6 +144,7 @@ class ChordList(LineElement): _template = "chordlist" def __init__(self, *chords): + super().__init__() self.chords = chords class Chord(AST): @@ -148,7 +153,7 @@ class Chord(AST): _template = "chord" def __init__(self, chord): - # pylint: disable=too-many-arguments + super().__init__() self.chord = chord @property @@ -218,7 +223,7 @@ class Song(AST): "tag": "add_cumulative", } - def __init__(self, filename): + def __init__(self, filename, directives): super().__init__() self.content = [] self.meta = OrderedDict() @@ -226,6 +231,8 @@ class Song(AST): self._titles = [] self._subtitles = [] self.filename = filename + for directive in directives: + self.add(directive) def add(self, data): """Add an element to the song""" diff --git a/patacrep/songs/chordpro/syntax.py b/patacrep/songs/chordpro/syntax.py index e88d7360..14195be4 100644 --- a/patacrep/songs/chordpro/syntax.py +++ b/patacrep/songs/chordpro/syntax.py @@ -19,28 +19,30 @@ class ChordproParser(Parser): def __init__(self, filename=None): super().__init__() self.tokens = tokens - self.song = ast.Song(filename) self.filename = filename + self._directives = [] self.parser = yacc.yacc( module=self, debug=0, write_tables=0, ) - def parse(self, *args, **kwargs): + def parse(self, content): """Parse file This is a shortcut to `yacc.yacc(...).parse()`. The arguments are transmitted to this method. """ - return self.parser.parse(*args, **kwargs) + lexer = ChordProLexer(filename=self.filename).lexer + ast.AST.lexer = lexer + return self.parser.parse(content, lexer=lexer) def p_song(self, symbols): """song : block song | empty """ if len(symbols) == 2: - symbols[0] = self.song + symbols[0] = ast.Song(self.filename, self._directives) else: symbols[0] = symbols[2].add(symbols[1]) @@ -158,14 +160,14 @@ class ChordproParser(Parser): ) symbols[0] = ast.Error() return - self.song.add(define) + self._directives.append(define) else: directive = ast.Directive(keyword, argument) if directive.inline: symbols[0] = directive else: - self.song.add(directive) + self._directives.append(directive) @staticmethod @@ -312,7 +314,4 @@ class ChordproParser(Parser): def parse_song(content, filename=None): """Parse song and return its metadata.""" - return ChordproParser(filename).parse( - content, - lexer=ChordProLexer(filename=filename).lexer, - ) + return ChordproParser(filename).parse(content)