Parse string within the given context. The context may define the result in case of ambiguous expressions. For instance, consider expressions `f(x, y)` and `(x, y) + (a, b)` where `f` is a function and pair `(x, y)` denotes complex number. Specifying context as "args
(self, s, context='expr')
| 1315 | return self.process(unquoted) |
| 1316 | |
| 1317 | def process(self, s, context='expr'): |
| 1318 | """Parse string within the given context. |
| 1319 | |
| 1320 | The context may define the result in case of ambiguous |
| 1321 | expressions. For instance, consider expressions `f(x, y)` and |
| 1322 | `(x, y) + (a, b)` where `f` is a function and pair `(x, y)` |
| 1323 | denotes complex number. Specifying context as "args" or |
| 1324 | "expr", the subexpression `(x, y)` will be parse to an |
| 1325 | argument list or to a complex number, respectively. |
| 1326 | """ |
| 1327 | if isinstance(s, (list, tuple)): |
| 1328 | return type(s)(self.process(s_, context) for s_ in s) |
| 1329 | |
| 1330 | assert isinstance(s, str), (type(s), s) |
| 1331 | |
| 1332 | # replace subexpressions in parenthesis with f2py @-names |
| 1333 | r, raw_symbols_map = replace_parenthesis(s) |
| 1334 | r = r.strip() |
| 1335 | |
| 1336 | def restore(r): |
| 1337 | # restores subexpressions marked with f2py @-names |
| 1338 | if isinstance(r, (list, tuple)): |
| 1339 | return type(r)(map(restore, r)) |
| 1340 | return unreplace_parenthesis(r, raw_symbols_map) |
| 1341 | |
| 1342 | # comma-separated tuple |
| 1343 | if ',' in r: |
| 1344 | operands = restore(r.split(',')) |
| 1345 | if context == 'args': |
| 1346 | return tuple(self.process(operands)) |
| 1347 | if context == 'expr': |
| 1348 | if len(operands) == 2: |
| 1349 | # complex number literal |
| 1350 | return as_complex(*self.process(operands)) |
| 1351 | raise NotImplementedError( |
| 1352 | f'parsing comma-separated list (context={context}): {r}') |
| 1353 | |
| 1354 | # ternary operation |
| 1355 | m = re.match(r'\A([^?]+)[?]([^:]+)[:](.+)\Z', r) |
| 1356 | if m: |
| 1357 | assert context == 'expr', context |
| 1358 | oper, expr1, expr2 = restore(m.groups()) |
| 1359 | oper = self.process(oper) |
| 1360 | expr1 = self.process(expr1) |
| 1361 | expr2 = self.process(expr2) |
| 1362 | return as_ternary(oper, expr1, expr2) |
| 1363 | |
| 1364 | # relational expression |
| 1365 | if self.language is Language.Fortran: |
| 1366 | m = re.match( |
| 1367 | r'\A(.+)\s*[.](eq|ne|lt|le|gt|ge)[.]\s*(.+)\Z', r, re.I) |
| 1368 | else: |
| 1369 | m = re.match( |
| 1370 | r'\A(.+)\s*([=][=]|[!][=]|[<][=]|[<]|[>][=]|[>])\s*(.+)\Z', r) |
| 1371 | if m: |
| 1372 | left, rop, right = m.groups() |
| 1373 | if self.language is Language.Fortran: |
| 1374 | rop = '.' + rop + '.' |
no test coverage detected