| 117 | |
| 118 | |
| 119 | def _parse(tokens, priority=-1): |
| 120 | result = '' |
| 121 | nexttok = next(tokens) |
| 122 | while nexttok == '!': |
| 123 | result += 'not ' |
| 124 | nexttok = next(tokens) |
| 125 | |
| 126 | if nexttok == '(': |
| 127 | sub, nexttok = _parse(tokens) |
| 128 | result = '%s(%s)' % (result, sub) |
| 129 | if nexttok != ')': |
| 130 | raise ValueError('unbalanced parenthesis in plural form') |
| 131 | elif nexttok == 'n': |
| 132 | result = '%s%s' % (result, nexttok) |
| 133 | else: |
| 134 | try: |
| 135 | value = int(nexttok, 10) |
| 136 | except ValueError: |
| 137 | raise _error(nexttok) from None |
| 138 | result = '%s%d' % (result, value) |
| 139 | nexttok = next(tokens) |
| 140 | |
| 141 | j = 100 |
| 142 | while nexttok in _binary_ops: |
| 143 | i = _binary_ops[nexttok] |
| 144 | if i < priority: |
| 145 | break |
| 146 | # Break chained comparisons |
| 147 | if i in (3, 4) and j in (3, 4): # '==', '!=', '<', '>', '<=', '>=' |
| 148 | result = '(%s)' % result |
| 149 | # Replace some C operators by their Python equivalents |
| 150 | op = _c2py_ops.get(nexttok, nexttok) |
| 151 | right, nexttok = _parse(tokens, i + 1) |
| 152 | result = '%s %s %s' % (result, op, right) |
| 153 | j = i |
| 154 | if j == priority == 4: # '<', '>', '<=', '>=' |
| 155 | result = '(%s)' % result |
| 156 | |
| 157 | if nexttok == '?' and priority <= 0: |
| 158 | if_true, nexttok = _parse(tokens, 0) |
| 159 | if nexttok != ':': |
| 160 | raise _error(nexttok) |
| 161 | if_false, nexttok = _parse(tokens) |
| 162 | result = '%s if %s else %s' % (if_true, result, if_false) |
| 163 | if priority == 0: |
| 164 | result = '(%s)' % result |
| 165 | |
| 166 | return result, nexttok |
| 167 | |
| 168 | |
| 169 | def _as_int(n): |