| 1301 | |
| 1302 | |
| 1303 | class _FromStringWorker: |
| 1304 | |
| 1305 | def __init__(self, language=Language.C): |
| 1306 | self.original = None |
| 1307 | self.quotes_map = None |
| 1308 | self.language = language |
| 1309 | |
| 1310 | def finalize_string(self, s): |
| 1311 | return insert_quotes(s, self.quotes_map) |
| 1312 | |
| 1313 | def parse(self, inp): |
| 1314 | self.original = inp |
| 1315 | unquoted, self.quotes_map = eliminate_quotes(inp) |
| 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) |
no outgoing calls
no test coverage detected
searching dependent graphs…