Browse Source

[chordpro] Lexer errors are added to the songbook errors

pull/176/head
Louis 9 years ago
parent
commit
86833febf1
  1. 10
      patacrep/songs/chordpro/lexer.py
  2. 15
      patacrep/songs/chordpro/syntax.py

10
patacrep/songs/chordpro/lexer.py

@ -1,8 +1,12 @@
"""ChordPro lexer"""
import functools
import logging
import ply.lex as lex
from patacrep.songs import errors
LOGGER = logging.getLogger()
#pylint: disable=invalid-name
@ -85,6 +89,7 @@ class ChordProLexer:
def __init__(self, *, filename=None):
self.__class__.lexer = lex.lex(module=self)
self.error_builders = []
self.filename = filename
# Define a rule so we can track line numbers
@ -140,6 +145,11 @@ class ChordProLexer:
char=token.value[0],
more=more,
)
self.error_builders.append(functools.partial(
errors.SongSyntaxError,
line=token.lexer.lineno,
message=message,
))
if self.filename is not None:
message = "File {}: {}".format(self.filename, message)
LOGGER.warning(message)

15
patacrep/songs/chordpro/syntax.py

@ -29,15 +29,17 @@ class ChordproParser(Parser):
write_tables=0,
)
def parse(self, content, *, lexer):
def parse(self, content):
"""Parse file
This is a shortcut to `yacc.yacc(...).parse()`. The arguments are
transmitted to this method.
"""
lexer = ChordProLexer(filename=self.filename).lexer
ast.AST.lexer = lexer
return self.parser.parse(content, lexer=lexer)
lexer = ChordProLexer(filename=self.filename)
ast.AST.lexer = lexer.lexer
parsed = self.parser.parse(content, lexer=lexer.lexer)
parsed.error_builders.extend(lexer.error_builders)
return parsed
def p_song(self, symbols):
"""song : block song
@ -324,10 +326,7 @@ class ChordproParser(Parser):
def parse_song(content, filename=None):
"""Parse song and return its metadata."""
parser = ChordproParser(filename)
parsed_content = parser.parse(
content,
lexer=ChordProLexer(filename=filename).lexer,
)
parsed_content = parser.parse(content)
if parsed_content is None:
raise ContentError(message='Fatal error during song parsing.')
return parsed_content

Loading…
Cancel
Save