From 451dce91e5adfd5979ab08b01027da2e144e00fd Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Fri, 2 Feb 2018 18:32:16 +0300 Subject: [PATCH] Accept missing * for str parsing --- mapytex/calculus/core/str2.py | 101 +++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 2 deletions(-) diff --git a/mapytex/calculus/core/str2.py b/mapytex/calculus/core/str2.py index cac4c2b..69fef09 100644 --- a/mapytex/calculus/core/str2.py +++ b/mapytex/calculus/core/str2.py @@ -13,6 +13,7 @@ Converting a string with coroutines from functools import partial from decimal import Decimal from .coroutine import * +from .operator import is_operator __all__ = ["str2", ] @@ -312,6 +313,85 @@ def concurent_broadcast(target, lookfors = []): target_.send(i) yield target_.throw(err) +@coroutine +def missing_times(target): + """ Coroutine which send a "*" when it's missing + + Cases where a "*" is missing: + - 2x or yx or )x + - 2( or y( or )( + + :param target: target to send data to + + :example: + + >>> miss_time = missing_times(list_sink) + >>> for i in "2a": + ... miss_time.send(i) + >>> a = miss_time.throw(STOOOP) + >>> print(a) + ['2', '*', 'a'] + >>> miss_time = missing_times(list_sink) + >>> for i in "ab": + ... miss_time.send(i) + >>> a = miss_time.throw(STOOOP) + >>> print(a) + ['a', '*', 'b'] + >>> miss_time = missing_times(list_sink) + >>> for i in "a(": + ... miss_time.send(i) + >>> a = miss_time.throw(STOOOP) + >>> print(a) + ['a', '*', '('] + >>> miss_time = missing_times(list_sink) + >>> for i in "2(": + ... miss_time.send(i) + >>> a = miss_time.throw(STOOOP) + >>> print(a) + ['2', '*', '('] + >>> miss_time = missing_times(list_sink) + >>> for i in ")(": + ... miss_time.send(i) + >>> a = miss_time.throw(STOOOP) + >>> print(a) + [')', '*', '('] + + >>> miss_time = missing_times(list_sink) + >>> for i in "3+4": + ... miss_time.send(i) + >>> a = miss_time.throw(STOOOP) + >>> print(a) + ['3', '+', '4'] + """ + try: + target_ = target() + except TypeError: + target_ = target + + previous = None + try: + while True: + tok = yield + if not previous is None: + previous = None + + if type(tok) == str: + if tok == '(': + target_.send("*") + elif not is_operator(tok) and tok != ')': + target_.send("*") + + if type(tok) == int or \ + (type(tok) == str and \ + not is_operator(tok) and \ + not tok == '('): + previous = tok + + target_.send(tok) + + except STOOOP as err: + yield target_.throw(err) + @coroutine def lookforNumbers(target): """ Coroutine which parse numbers @@ -464,6 +544,14 @@ def str2(sink): >>> t = str2nestedlist(exp) >>> print(t) [12, '*', [3, '+', 4]] + >>> exp = "12(3+4)" + >>> t = str2nestedlist(exp) + >>> print(t) + [12, '*', [3, '+', 4]] + >>> exp = "2a(3+4)" + >>> t = str2nestedlist(exp) + >>> print(t) + [2, '*', 'a', '*', [3, '+', 4]] >>> from .tree import MutableTree >>> str2tree = str2(MutableTree.sink) @@ -486,17 +574,26 @@ def str2(sink): >>> exp = "12*(3+4)" >>> t = str2tree(exp) >>> print(t) + * + > 12 + > + + | > 3 + | > 4 + >>> exp = "12(3+4)" + >>> t = str2tree(exp) + >>> print(t) * > 12 > + | > 3 | > 4 """ - lfop = lookfor(something_in("+-*/")) + lfop = lookfor(is_operator) operator_corout = partial(concurent_broadcast, lookfors = [lfop]) def pipeline(expression): - str2_corout = lookforNumbers(operator_corout(pparser(sink))) + str2_corout = lookforNumbers(operator_corout(missing_times(pparser(sink)))) + #str2_corout = lookforNumbers(operator_corout(pparser(sink))) for i in expression: str2_corout.send(i) a = str2_corout.throw(STOOOP)