@@ -17,11 +17,12 @@ class ParseError(Exception): | |||||
pass | pass | ||||
class UnexpectedToken(ParseError): | class UnexpectedToken(ParseError): | ||||
def __init__(self, token, expected, seq, index): | |||||
def __init__(self, token, expected, seq, index, considered_rules=None): | |||||
self.token = token | self.token = token | ||||
self.expected = expected | self.expected = expected | ||||
self.line = getattr(token, 'line', '?') | self.line = getattr(token, 'line', '?') | ||||
self.column = getattr(token, 'column', '?') | self.column = getattr(token, 'column', '?') | ||||
self.considered_rules = considered_rules | |||||
try: | try: | ||||
context = ' '.join(['%r(%s)' % (t.value, t.type) for t in seq[index:index+5]]) | context = ' '.join(['%r(%s)' % (t.value, t.type) for t in seq[index:index+5]]) | ||||
@@ -10,7 +10,7 @@ class LexError(Exception): | |||||
pass | pass | ||||
class UnexpectedInput(LexError): | 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] | 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) | message = "No token defined for: '%s' in %r at line %d col %d" % (seq[lex_pos], context, line, column) | ||||
if allowed: | if allowed: | ||||
@@ -22,6 +22,7 @@ class UnexpectedInput(LexError): | |||||
self.column = column | self.column = column | ||||
self.context = context | self.context = context | ||||
self.allowed = allowed | self.allowed = allowed | ||||
self.considered_rules = considered_rules | |||||
class Token(Str): | class Token(Str): | ||||
def __new__(cls, type_, value, pos_in_stream=None, line=None, column=None): | def __new__(cls, type_, value, pos_in_stream=None, line=None, column=None): | ||||
@@ -197,7 +197,7 @@ class Parser: | |||||
if not next_set: | if not next_set: | ||||
expect = {i.expect for i in column.to_scan} | 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 | return next_set | ||||
@@ -112,7 +112,7 @@ class Parser: | |||||
del delayed_matches[i+1] # No longer needed, so unburden memory | del delayed_matches[i+1] # No longer needed, so unburden memory | ||||
if not next_set and not delayed_matches: | 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 | return next_set | ||||