Esempio n. 1
0
    def _run_from(self, start_index, stream, delta, search):
        self._reset(0, stream, None)
        self._advance(delta)
        self._search = search
        self._checkpoints = {}
        self._lookaheads = (self._offset, {})
        search = self._search # read only, dereference optimisation

        # states are ordered by group start, which explains a lot of
        # the otherwise rather opaque logic below.
        self._states = [(start_index, self._offset, 0)]
        
        try:

            while self._states and self._excess < 2:

                known_next = set()
                next_states = []

                while self._states:

                    # unpack state
                    (index, self._start, 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, self._start, 0))
                                known_next.add(index)

                        elif skip == -1:
                            raise Match

                        else:
                            skip -= 1

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

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

                    except Fail:
                        pass

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

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

                # add current position as search if necessary
                if search and start_index not in known_next:
                    self._states.append((start_index, self._offset, 0))

                self._states.reverse()

            # pick first matched state, if any
            while self._states:
                (index, self._start, skip) = self._states.pop()
                if skip == -1:
                    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, self._start)
            groups.end_group(0, self._offset)
            return groups
Esempio n. 2
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
Esempio n. 3
0
    def _run_from(self, start_index, stream, delta, search):
        self._reset(0, stream, None)
        self._advance(delta)
        self._search = search
        self._checkpoints = {}
        self._lookaheads = (self._offset, {})
        search = self._search  # read only, dereference optimisation

        # states are ordered by group start, which explains a lot of
        # the otherwise rather opaque logic below.
        self._states = [(start_index, self._offset, 0)]

        try:

            while self._states and self._excess < 2:

                known_next = set()
                next_states = []

                while self._states:

                    # unpack state
                    (index, self._start, 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, self._start, 0))
                                known_next.add(index)

                        elif skip == -1:
                            raise Match

                        else:
                            skip -= 1

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

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

                    except Fail:
                        pass

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

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

                # add current position as search if necessary
                if search and start_index not in known_next:
                    self._states.append((start_index, self._offset, 0))

                self._states.reverse()

            # pick first matched state, if any
            while self._states:
                (index, self._start, skip) = self._states.pop()
                if skip == -1:
                    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, self._start)
            groups.end_group(0, self._offset)
            return groups
Esempio n. 4
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