| @@ -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 | ||||