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