# Path: penman/exceptions.py
# class DecodeError(PenmanError):
#     """Raised on PENMAN syntax errors."""
# 
#     def __init__(self,
#                  message: str = None,
#                  filename: str = None,
#                  lineno: int = None,
#                  offset: int = None,
#                  text: str = None):
#         self.message = message
#         self.filename = filename
#         self.lineno = lineno
#         self.offset = offset
#         self.text = text
# 
#     def __str__(self):
#         parts = []
#         if self.filename is not None:
#             parts.append(f'File "{self.filename}"')
#         if self.lineno is not None:
#             parts.append(f'line {self.lineno}')
#         if parts:
#             parts = ['', '  ' + ', '.join(parts)]
#         if self.text is not None:
#             parts.append('    ' + self.text)
#             if self.offset is not None:
#                 parts.append('    ' + (' ' * self.offset) + '^')
#         elif parts:
#             parts[-1] += f', character {self.offset}'
#         if self.message is not None:
#             name = self.__class__.__name__
#             parts.append(f'{name}: {self.message}')
#         return '\n'.join(parts)


from typing import Union, Iterable, Iterator, NamedTuple, Pattern
from penman.exceptions import DecodeError
import re
import logging
        except StopIteration:
            raise self.error('Unexpected end of input')
        if token.type not in choices:
            raise self.error('Expected: {}'.format(', '.join(choices)),
                             token=token)
        return token

    def accept(self, *choices):
        """
        Return the next token if its type is in *choices*.

        The iterator is advanced if successful. If unsuccessful,
        ``None`` is returned.
        """
        if self._next is not None and self._next.type in choices:
            return self.next()
        return None

    def error(self, message: str, token=None) -> DecodeError:
        if token is None:
            type = line = None
            if self._last is not None:
                lineno = self._last.lineno
                offset = self._last.offset + len(self._last.text)
                line = self._last.line
            else:
                lineno = offset = 0
        else:
            type, _, lineno, offset, line = token


# Path: penman/exceptions.py
# class DecodeError(PenmanError):
#     """Raised on PENMAN syntax errors."""
# 
#     def __init__(self,
#                  message: str = None,
#                  filename: str = None,
#                  lineno: int = None,
#                  offset: int = None,
#                  text: str = None):
#         self.message = message
#         self.filename = filename
#         self.lineno = lineno
#         self.offset = offset
#         self.text = text
# 
#     def __str__(self):
#         parts = []
#         if self.filename is not None:
#             parts.append(f'File "{self.filename}"')
#         if self.lineno is not None:
#             parts.append(f'line {self.lineno}')
#         if parts:
#             parts = ['', '  ' + ', '.join(parts)]
#         if self.text is not None:
#             parts.append('    ' + self.text)
#             if self.offset is not None:
#                 parts.append('    ' + (' ' * self.offset) + '^')
#         elif parts:
#             parts[-1] += f', character {self.offset}'
#         if self.message is not None:
#             name = self.__class__.__name__
#             parts.append(f'{name}: {self.message}')
#         return '\n'.join(parts)


# Path: penman/_lexer.py
from typing import Union, Iterable, Iterator, NamedTuple, Pattern
from penman.exceptions import DecodeError
import re
import logging

        except StopIteration:
            raise self.error('Unexpected end of input')
        if token.type not in choices:
            raise self.error('Expected: {}'.format(', '.join(choices)),
                             token=token)
        return token

    def accept(self, *choices):
        """
        Return the next token if its type is in *choices*.

        The iterator is advanced if successful. If unsuccessful,
        ``None`` is returned.
        """
        if self._next is not None and self._next.type in choices:
            return self.next()
        return None

    def error(self, message: str, token=None) -> DecodeError:
        if token is None:
            type = line = None
            if self._last is not None:
                lineno = self._last.lineno
                offset = self._last.offset + len(self._last.text)
                line = self._last.line
            else:
                lineno = offset = 0
        else:
            type, _, lineno, offset, line = token


        return DecodeError(message, lineno=lineno, offset=offset, text=line)