def parse_tokens(tokenrules, tokentexts, dictionarytype=dict):

    def inc(pos):
        return pos + 1

    def rule_at(pos):
        try:
            return tokenrules[pos]
        except IndexError:
            raise ParserError('Expecting more tokens', pos)

    def text_at(pos):
        try:
            return tokentexts[pos]
        except IndexError:
            raise ParserError('Expecting more tokens', pos)

    def skip_literal(pos, rulenr):
        if rule_at(pos) == rulenr:
            return inc(pos)
        return pos

    def musthave_literal(pos, s):
        nextpos = skip_literal(pos, s)
        if nextpos == pos:
            raise ParserError("Expecting '%s'" % s, pos)
        return nextpos

    def sequence(pos, *args):
        elements = []
        for element in args:
            if callable(element):
                r = element(pos)
                v, pos = r
                elements.append(v)
            else:
                pos = musthave_literal(pos, element)
        return elements, pos

    def zero_or_more(pos, func, nextelem):
        elements = []
        while True:
            try:
                v, pos = func(pos)
                elements.append(v)
            except ParserError as e:
                try:
                    musthave_literal(pos, nextelem)
                except ParserError as e2:
                    e2.prevexc = e
                    raise e2
                return elements, pos
        return elements, pos

    def anystring(pos):
        rulenr = rule_at(pos)
        if rulenr == RULE_UNQUOTEDSTRING:
            return unquotedstring(pos)
        elif rulenr == RULE_QUOTEDSTRING:
            return quotedstring(pos)
        raise ParserError('Expecting string', pos)

    def value(pos):
        rulenr = rule_at(pos)
        if rulenr == RULE_UNQUOTEDSTRING:
            return unquotedstring(pos)
        elif rulenr == RULE_DICTIONARY:
            return dictionary(pos)
        elif rulenr == RULE_QUOTEDSTRING:
            return quotedstring(pos)
        elif rulenr == RULE_ARRAY:
            return array(pos)
        raise ParserError('Expecting value', pos)

    def arrayvalue(pos):
        rulenr = rule_at(pos)
        if rulenr == RULE_UNQUOTEDSTRING:
            return unquotedstring(pos)
        elif rulenr == RULE_QUOTEDSTRING:
            return quotedstring(pos)
        elif rulenr == RULE_DICTIONARY:
            return dictionary(pos)
        raise ParserError('Expecting array value', pos)

    def arrayelements(pos):
        try:
            return zero_or_more(pos, arrayelement, RULE_ARRAYEND)
        except RuntimeError as exc:
            if str(exc).startswith('maximum recursion depth exceeded'):
                raise ParserError("Exceeded maximum recursion", pos)

    def arrayelement(pos):
        v, pos = arrayvalue(pos)

        p2 = skip_literal(pos, RULE_COMMA)
        if p2 > pos:
            # There is a comma after the array element
            return v, p2

        # No comma after an array element is also fine in case
        # a closing paren follows which we don't consume.
        musthave_literal(pos, RULE_ARRAYEND)
        return v, pos

    def array(pos):
        v, pos = sequence(pos, RULE_ARRAY, arrayelements, RULE_ARRAYEND)
        return v[0], pos

    def kvpair(pos):
        k, p = anystring(pos)
        p = musthave_literal(p, RULE_EQUALS)
        v, p = value(p)
        p = musthave_literal(p, RULE_SEMICOLON)
        return (k, v), p

    def kvpairs(pos):
        return zero_or_more(pos, kvpair, RULE_DICTIONARYEND)

    def dictionary(pos):
        try:
            v, pos = sequence(pos, RULE_DICTIONARY, kvpairs, RULE_DICTIONARYEND)
            return dictionarytype(v[0]), pos
        except RuntimeError as exc:
            if str(exc).startswith('maximum recursion depth exceeded'):
                raise ParserError("Exceeded maximum recursion", pos)

    def quotedstring(pos):
        v, pos = named_rule(pos, RULE_QUOTEDSTRING)
        return unescape_str(v), pos

    def unquotedstring(pos):
        return named_rule(pos, RULE_UNQUOTEDSTRING)

    def named_rule(pos, rulenr):
        if rule_at(pos) != rulenr:
            raise ParserError(rulenr % 'Expecting rule %d', pos)
        return text_at(pos), inc(pos)

    def parse_xcodeplist_tokens(pos):
        try:
            root = dictionary(pos)
        except ParserError as e:
            return False, e
        if root is None:
            return False, None

        v, pos = root
        if pos != len(tokenrules):
            return False, ParserError("there are still tokens left after parsing", pos)
        return True, v

    success, root = parse_xcodeplist_tokens(0)
    return success, root
dataset/ETHPy150Open mikr/xcodeprojer/xcodeprojer.py/parse_tokens/swapped operands of `%`