def _parse_expression_fallback(self, end: List[str], parser: Callable[([], ASTExpression)], allow: bool=True) -> ASTExpression:
    prevPos = self.pos
    try:
        return parser()
    except DefinitionError as e:
        if ((not allow) or (not self.allowFallbackExpressionParsing)):
            raise
        self.warn(('Parsing of expression failed. Using fallback parser. Error was:\n%s' % e))
        self.pos = prevPos
    assert (end is not None)
    self.skip_ws()
    startPos = self.pos
    if self.match(_string_re):
        value = self.matched_text
    else:
        brackets = {'(': ')', '{': '}', '[': ']', '<': '>'}
        symbols = []
        while (not self.eof):
            if ((len(symbols) == 0) and (self.current_char in end)):
                break
            if (self.current_char in brackets.keys()):
                symbols.append(brackets[self.current_char])
            elif ((len(symbols) > 0) and (self.current_char == symbols[(- 1)])):
                symbols.pop()
            self.pos += 1
        if ((len(end) > 0) and self.eof):
            self.fail(('Could not find end of expression starting at %d.' % startPos))
        value = self.definition[startPos:self.pos].strip()
    return ASTFallbackExpr(value.strip())
def _parse_expression_fallback(self, end: List[str], parser: Callable[([], ASTExpression)], allow: bool=True) -> ASTExpression:
    prevPos = self.pos
    try:
        return parser()
    except DefinitionError as e:
        if ((not allow) or (not self.allowFallbackExpressionParsing)):
            raise
        self.warn(('Parsing of expression failed. Using fallback parser. Error was:\n%s' % e))
        self.pos = prevPos
    assert (end is not None)
    self.skip_ws()
    startPos = self.pos
    if self.match(_string_re):
        value = self.matched_text
    else:
        brackets = {'(': ')', '{': '}', '[': ']', '<': '>'}
        symbols = []
        while (not self.eof):
            if ((len(symbols) == 0) and (self.current_char in end)):
                break
            if (self.current_char in brackets.keys()):
                symbols.append(brackets[self.current_char])
            elif ((len(symbols) > 0) and (self.current_char == symbols[(- 1)])):
                symbols.pop()
            self.pos += 1
        if ((len(end) > 0) and self.eof):
            self.fail(('Could not find end of expression starting at %d.' % startPos))
        value = self.definition[startPos:self.pos].strip()
    return ASTFallbackExpr(value.strip())