def skipWhitespace(s, start): i = start while i < len(s) and s[i].isspace(): i+=1 return i def strRowCol(s, i): k = 0 (r, c) = (0, 0) for (r, line) in enumerate(s.splitlines(True)): c = i-k if k+len(line) > i: break else: k += len(line) return (r+1, c+1) class ParserError(Exception): def __init__(self, msg, s, i): self.msg = msg (self.row, self.col) = strRowCol(s, i) self.context = s[i:i+16] def __str__(self): return "{0} at row {1}, col {2}, got '{3}...' instead".format(self.msg, self.row, self.col, self.context) class ParserWarning(ParserError): pass