1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
from __future__ import annotations
import re
class ParseException(Exception):
pass
# alias
TatSuException = ParseException
class OptionSucceeded(ParseException):
pass
class GrammarError(ParseException):
pass
class SemanticError(ParseException):
pass
class CodegenError(ParseException):
pass
class MissingSemanticFor(SemanticError):
pass
class ParseError(ParseException):
pass
class FailedSemantics(ParseError):
pass
class FailedKeywordSemantics(FailedSemantics):
pass
class NoParseInfo(ParseException):
pass
class FailedParse(ParseError):
def __init__(self, tokenizer, stack, item):
stack = list(stack) # NOTE: can't pass through multiprocessing if generator
# note: pass all arguments to super() to avoid pickling problems
# https://stackoverflow.com/questions/27993567/
super().__init__(tokenizer, stack, item)
self.tokenizer = tokenizer
self.stack = stack
self.pos = tokenizer.pos
self.item = item
@property
def message(self):
return self.item
def __str__(self):
info = self.tokenizer.line_info(self.pos)
template = '{}({}:{}) {} :\n{}\n{}^\n{}'
text = info.text.rstrip()
leading = re.sub(r'[^\t]', ' ', text)[: info.col]
text = text.expandtabs()
leading = leading.expandtabs()
return template.format(
info.filename,
info.line + 1,
info.col + 1,
self.message.rstrip(),
text,
leading,
'\n'.join(self.stack),
)
class FailedToken(FailedParse):
def __init__(self, tokenizer, stack, token):
super().__init__(tokenizer, stack, token)
self.token = token
@property
def message(self):
return 'expecting {}'.format(repr(self.token).lstrip('u'))
class FailedPattern(FailedParse):
def __init__(self, tokenizer, stack, pattern):
super().__init__(tokenizer, stack, pattern)
self.pattern = pattern
@property
def message(self):
return f'expecting /{self.pattern}/'
class FailedRef(FailedParse):
def __init__(self, tokenizer, stack, name):
super().__init__(tokenizer, stack, name)
self.name = name
@property
def message(self):
return f"could not resolve reference to rule '{self.name}'"
class FailedChoice(FailedParse):
@property
def message(self):
return 'no viable option'
class FailedLookahead(FailedParse):
@property
def message(self):
return 'failed lookahead'
class FailedLeftRecursion(FailedParse):
@property
def message(self):
return 'infinite left recursion'
class FailedExpectingEndOfText(FailedParse):
pass
class FailedKeyword(FailedParse):
pass
|