diff --git a/lark/common.py b/lark/common.py index ad16cfe..7611a2c 100644 --- a/lark/common.py +++ b/lark/common.py @@ -17,11 +17,12 @@ class ParseError(Exception): pass class UnexpectedToken(ParseError): - def __init__(self, token, expected, seq, index): + def __init__(self, token, expected, seq, index, considered_rules=None): self.token = token self.expected = expected self.line = getattr(token, 'line', '?') self.column = getattr(token, 'column', '?') + self.considered_rules = considered_rules try: context = ' '.join(['%r(%s)' % (t.value, t.type) for t in seq[index:index+5]]) diff --git a/lark/lexer.py b/lark/lexer.py index 2fdc6b9..e48a970 100644 --- a/lark/lexer.py +++ b/lark/lexer.py @@ -10,7 +10,7 @@ class LexError(Exception): pass class UnexpectedInput(LexError): - def __init__(self, seq, lex_pos, line, column, allowed=None): + def __init__(self, seq, lex_pos, line, column, allowed=None, considered_rules=None): context = seq[lex_pos:lex_pos+5] message = "No token defined for: '%s' in %r at line %d col %d" % (seq[lex_pos], context, line, column) if allowed: @@ -22,6 +22,7 @@ class UnexpectedInput(LexError): self.column = column self.context = context self.allowed = allowed + self.considered_rules = considered_rules class Token(Str): def __new__(cls, type_, value, pos_in_stream=None, line=None, column=None): diff --git a/lark/parsers/earley.py b/lark/parsers/earley.py index 39c39a9..2b04a1e 100644 --- a/lark/parsers/earley.py +++ b/lark/parsers/earley.py @@ -197,7 +197,7 @@ class Parser: if not next_set: expect = {i.expect for i in column.to_scan} - raise UnexpectedToken(token, expect, stream, i) + raise UnexpectedToken(token, expect, stream, set(column.to_scan)) return next_set diff --git a/lark/parsers/xearley.py b/lark/parsers/xearley.py index 45c9fee..d710f34 100644 --- a/lark/parsers/xearley.py +++ b/lark/parsers/xearley.py @@ -112,7 +112,7 @@ class Parser: del delayed_matches[i+1] # No longer needed, so unburden memory if not next_set and not delayed_matches: - raise UnexpectedInput(stream, i, text_line, text_column, {item.expect for item in to_scan}) + raise UnexpectedInput(stream, i, text_line, text_column, {item.expect for item in to_scan}, set(to_scan)) return next_set