Пример #1
0
 def checkpoint(self, id):
     '''
     Successive calls to checkpoint with the same id must consume text.
     If they don't, there is an error (a repeating empty loop) and the
     engine should abort (raise an exception).
     '''
     raise UnsupportedOperation('checkpoint')
Пример #2
0
    def run(self, stream, pos=0, search=False, fail_on_groups=True):

        self._initial_stream = stream

        # TODO - add explicit search if expression starts with constant

        self.group_defined = False
        result = self._run_from(0, stream, pos, search)
        if self.group_defined and fail_on_groups:
            raise UnsupportedOperation('groups')
        else:
            return result
Пример #3
0
    def lookahead(self, next, equal, forwards, mutates, reads, length):

        # discard old values
        if self._lookaheads[0] != self._offset:
            self._lookaheads = (self._offset, {})
        lookaheads = self._lookaheads[1]

        if next[1] not in lookaheads:

            # requires complex engine
            if reads:
                raise UnsupportedOperation('lookahead')
            size = None if (reads and mutates) else length(None)

            # invoke simple engine and cache
            self._push()
            try:
                if forwards:
                    stream = self._initial_stream
                    pos = self._offset
                    search = False
                else:
                    (text, _) = s_next(self._initial_stream, self._offset)
                    stream = s_stream(self._initial_stream, text)
                    if size is None:
                        pos = 0
                        search = True
                    else:
                        pos = self._offset - size
                        search = False
                if pos >= 0:
                    result = bool(self._run_from(next[1], stream, pos,
                                                 search)) == equal
                else:
                    result = not equal
            finally:
                self._pop()
            lookaheads[next[1]] = result

        if lookaheads[next[1]]:
            return next[0]
        else:
            raise Fail
Пример #4
0
 def group_reference(self, next, number):
     raise UnsupportedOperation('group_reference')
Пример #5
0
 def group_reference(self, next, number):
     '''Match a previously matched group.'''
     raise UnsupportedOperation('group_reference')
Пример #6
0
 def word(self, inverted):
     '''Match a word.'''
     raise UnsupportedOperation('word')
Пример #7
0
 def digit(self, inverted):
     '''Match a digit.'''
     raise UnsupportedOperation('digit')
Пример #8
0
 def end_of_line(self, multiline):
     '''Match the end of a line.'''
     raise UnsupportedOperation('end_of_line')
Пример #9
0
 def dot(self, multiline):
     '''Match "any" character (exact details depend on regexp options).'''
     raise UnsupportedOperation('dot')
Пример #10
0
 def match(self):
     '''Indicate a successful (end of) a match.'''
     raise UnsupportedOperation('match')
Пример #11
0
 def word(self, char, flags):
     '''Test whether the character is a word character or not.'''
     raise UnsupportedOperation('word')
Пример #12
0
 def space(self, char, flags):
     '''Test whether the character is a whitespace or not.'''
     raise UnsupportedOperation('space')
Пример #13
0
 def digit(self, char, flags):
     '''Test whether the character is a digit or not.'''
     raise UnsupportedOperation('digit')
Пример #14
0
 def repeat(self, next, begin, end, lazy):
     raise UnsupportedOperation('repeat')
Пример #15
0
 def conditional(self, next, number):
     raise UnsupportedOperation('conditional')
Пример #16
0
 def start_group(self, number):
     '''Start a numbered group.'''
     raise UnsupportedOperation('start_group')
Пример #17
0
 def end_group(self, number):
     '''End a numbered group (called symmetrically with `start_group()`).'''
     raise UnsupportedOperation('end_group')
Пример #18
0
 def split(self, next):
     '''
     A branch (alternatives ordered by priority).
     For example, this is used to implement repetition.
     '''
     raise UnsupportedOperation('split')
Пример #19
0
 def no_match(self):
     '''Indicate a failure to match.'''
     raise UnsupportedOperation('no_match')
Пример #20
0
 def lookahead(self, next, equal, forwards, mutates, reads, length):
     '''Perform a lookahead match.'''
     raise UnsupportedOperation('lookahead')
Пример #21
0
 def start_of_line(self, multiline):
     '''Match the start of a line.'''
     raise UnsupportedOperation('start_of_line')
Пример #22
0
 def repeat(self, next, begin, end, lazy):
     '''Perform a counted repetition.'''
     raise UnsupportedOperation('repeat')
Пример #23
0
 def word_boundary(self, inverted):
     '''Match a word boundary.'''
     raise UnsupportedOperation('word_boundary')
Пример #24
0
 def string(self, next, text):
     '''Literal text replacement.'''
     raise UnsupportedOperation('string')
Пример #25
0
 def space(self, inverted):
     '''Match a space character.'''
     raise UnsupportedOperation('space')
Пример #26
0
 def group_reference(self, next, number):
     '''Replace with matched data.'''
     raise UnsupportedOperation('group_reference')
Пример #27
0
 def string(self, next, text):
     '''Match the given literal.'''
     raise UnsupportedOperation('string')
Пример #28
0
 def character(self, charset):
     '''Match the given character (more exactly, a "string" of length 1).'''
     raise UnsupportedOperation('character')
Пример #29
0
 def conditional(self, next, number):
     '''Condition on a previously matched group.'''
     raise UnsupportedOperation('conditional')
Пример #30
0
    def run(self, stream, pos=0, search=False):
        if pos or search:
            raise UnsupportedOperation('Search')
        self._initial_stream = stream
        self._reset(0, stream, None)
        self._checkpoints = {}
        self._last_group = 0  # default for no group

        self._states = [(0, 0)]

        try:

            while self._states and self._excess < 2:

                known_next = set()
                next_states = []

                while self._states:

                    # unpack state
                    (index, skip) = self._states.pop()
                    try:

                        if not skip:
                            # process the current character
                            index = self._program[index]()
                            if index not in known_next:
                                next_states.append((index, 0))
                                known_next.add(index)

                        elif skip < 0:
                            raise Match

                        else:
                            skip -= 1

                            # if we have other states
                            if next_states or self._states:
                                if (index, skip) not in known_next:
                                    next_states.append((index, skip))
                                    known_next.add((index, skip))

                            # otherwise, we can jump directly
                            else:
                                self._advance(skip)
                                next_states.append((index, 0))

                    except Fail:
                        pass

                    except Match:
                        # no groups starting earlier?
                        if skip >= 0:
                            skip = self._last_group
                        if not next_states:
                            raise
                        # some other, pending, earlier starting, state may
                        # still give a match
                        if index not in known_next:
                            next_states.append((index, skip))
                            known_next.add(index)
                        # but we can discard anything that starts later
                        self._states = []

                # move to next character
                self._advance()
                self._states = next_states
                self._states.reverse()

            # pick first matched state, if any
            while self._states:
                (index, skip) = self._states.pop()
                if skip < 0:
                    raise Match

            # exhausted states with no match
            return Groups()

        except Match:
            groups = Groups(group_state=self._parser_state.groups,
                            stream=self._initial_stream)
            groups.start_group(0, 0)
            groups.end_group(0, self._offset)
            groups.start_group(-skip, 0)
            groups.end_group(-skip, self._offset)
            return groups