Example #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')
Example #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
Example #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
Example #4
0
 def group_reference(self, next, number):
     raise UnsupportedOperation('group_reference')
Example #5
0
 def group_reference(self, next, number):
     '''Match a previously matched group.'''
     raise UnsupportedOperation('group_reference')
Example #6
0
 def word(self, inverted):
     '''Match a word.'''
     raise UnsupportedOperation('word')
Example #7
0
 def digit(self, inverted):
     '''Match a digit.'''
     raise UnsupportedOperation('digit')
Example #8
0
 def end_of_line(self, multiline):
     '''Match the end of a line.'''
     raise UnsupportedOperation('end_of_line')
Example #9
0
 def dot(self, multiline):
     '''Match "any" character (exact details depend on regexp options).'''
     raise UnsupportedOperation('dot')
Example #10
0
 def match(self):
     '''Indicate a successful (end of) a match.'''
     raise UnsupportedOperation('match')
Example #11
0
 def word(self, char, flags):
     '''Test whether the character is a word character or not.'''
     raise UnsupportedOperation('word')
Example #12
0
 def space(self, char, flags):
     '''Test whether the character is a whitespace or not.'''
     raise UnsupportedOperation('space')
Example #13
0
 def digit(self, char, flags):
     '''Test whether the character is a digit or not.'''
     raise UnsupportedOperation('digit')
Example #14
0
 def repeat(self, next, begin, end, lazy):
     raise UnsupportedOperation('repeat')
Example #15
0
 def conditional(self, next, number):
     raise UnsupportedOperation('conditional')
Example #16
0
 def start_group(self, number):
     '''Start a numbered group.'''
     raise UnsupportedOperation('start_group')
Example #17
0
 def end_group(self, number):
     '''End a numbered group (called symmetrically with `start_group()`).'''
     raise UnsupportedOperation('end_group')
Example #18
0
 def split(self, next):
     '''
     A branch (alternatives ordered by priority).
     For example, this is used to implement repetition.
     '''
     raise UnsupportedOperation('split')
Example #19
0
 def no_match(self):
     '''Indicate a failure to match.'''
     raise UnsupportedOperation('no_match')
Example #20
0
 def lookahead(self, next, equal, forwards, mutates, reads, length):
     '''Perform a lookahead match.'''
     raise UnsupportedOperation('lookahead')
Example #21
0
 def start_of_line(self, multiline):
     '''Match the start of a line.'''
     raise UnsupportedOperation('start_of_line')
Example #22
0
 def repeat(self, next, begin, end, lazy):
     '''Perform a counted repetition.'''
     raise UnsupportedOperation('repeat')
Example #23
0
 def word_boundary(self, inverted):
     '''Match a word boundary.'''
     raise UnsupportedOperation('word_boundary')
Example #24
0
 def string(self, next, text):
     '''Literal text replacement.'''
     raise UnsupportedOperation('string')
Example #25
0
 def space(self, inverted):
     '''Match a space character.'''
     raise UnsupportedOperation('space')
Example #26
0
 def group_reference(self, next, number):
     '''Replace with matched data.'''
     raise UnsupportedOperation('group_reference')
Example #27
0
 def string(self, next, text):
     '''Match the given literal.'''
     raise UnsupportedOperation('string')
Example #28
0
 def character(self, charset):
     '''Match the given character (more exactly, a "string" of length 1).'''
     raise UnsupportedOperation('character')
Example #29
0
 def conditional(self, next, number):
     '''Condition on a previously matched group.'''
     raise UnsupportedOperation('conditional')
Example #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