Esempio n. 1
0
    def parseImpl(self, string, loc, doActions=True):
        maxExcLoc = -1
        maxException = None
        matches = []
        for e in self.exprs:
            try:
                loc2 = e.tryParse(string, loc)
            except ParseException as err:
                err.__traceback__ = None
                if err.loc > maxExcLoc:
                    maxException = err
                    maxExcLoc = err.loc
            except IndexError:
                if len(string) > maxExcLoc:
                    maxException = ParseException(string, len(string), self)
                    maxExcLoc = len(string)
            else:
                # save match among all matches, to retry longest to shortest
                matches.append((loc2, e))

        if matches:
            # re-evaluate all matches in descending order of length of match, in case attached actions
            # might change whether or how much they match of the input.
            matches.sort(key=itemgetter(0), reverse=True)

            if not doActions:
                # no further conditions or parse actions to change the selection of
                # alternative, so the first match will be the best match
                _, best_expr = matches[0]
                loc, best_results = best_expr._parse(string, loc, doActions)
                return loc, ParseResults(self, [best_results])

            longest = -1, None
            for loc1, expr1 in matches:
                if loc1 <= longest[0]:
                    # already have a longer match than this one will deliver, we are done
                    return longest

                try:
                    loc2, toks = expr1._parse(string, loc, doActions)
                except ParseException as err:
                    err.__traceback__ = None
                    if err.loc > maxExcLoc:
                        maxException = err
                        maxExcLoc = err.loc
                else:
                    if loc2 >= loc1:
                        return loc2, ParseResults(self, [toks])
                    # didn't match as much as before
                    elif loc2 > longest[0]:
                        longest = loc2, ParseResults(self, [toks])

            if longest != (-1, None):
                return longest

        if maxException is not None:
            maxException.msg = "Expecting " + text(self)
            raise maxException
        else:
            raise ParseException(string, loc, "no defined alternatives to match", self)
Esempio n. 2
0
    def parseImpl(self, string, loc, doActions=True):
        maxExcLoc = -1
        maxException = None
        for e in self.exprs:
            try:
                loc, ret = e._parse(string, loc, doActions)
                return loc, ParseResults(self, [ret])
            except ParseException as err:
                if err.loc > maxExcLoc:
                    maxException = err
                    maxExcLoc = err.loc
            except IndexError:
                if len(string) > maxExcLoc:
                    maxException = ParseException(string, len(string), self)
                    maxExcLoc = len(string)

        # only got here if no expression matched, raise exception for match that made it the furthest
        else:
            if maxException is not None:
                maxException.msg = "Expecting " + text(self)
                raise maxException
            else:
                raise ParseException(self, loc, string)