Esempio n. 1
0
def lst(k, l, p):
    """
    Matches 0 or more repetitions of p, extracting values of l and assigning them to the list k
    >>> t = seq(html('<body>'), seq(lst('names', 'name', seq(html('<h2>'), seq(safe('name'), html('</h2>')))), html('</body>')))
    >>> [(m, v, y) for m, v, y in t({}, '<body><h2>Ori</h2></body>') if m]
    [(True, {'names': ['Ori']}, '')]
    >>> [(m, v, y) for m, v, y in t({}, '<body><h2>Ori</h2><h2>Dori</h2></body>') if m]
    [(True, {'names': ['Ori', 'Dori']}, ''), (True, {'names': ['Ori</h2><h2>Dori']}, '')]
    >>> t = seq(html('<body>'), seq(lst('character.names', 'name', seq(html('<h2>'), seq(esc('name'), html('</h2>')))), html('</body>')))
    >>> [(m, v, y) for m, v, y in t({}, '<body><h2>Ori</h2></body>') if m]
    [(True, {'character': {'names': ['Ori']}}, '')]
    >>> t = lst('names', 'name', seq(lit('<'), seq(esc('tag'), seq(lit('>'), seq(esc('name'), seq(lit('</'), seq(esc('tag'), lit('>'))))))))
    >>> [(m, v, y) for m, v, y in t({}, '<h2>Ori</h2><h2>Dori</h2>') if m and y == '']
    [(True, {'names': ['Ori', 'Dori'], 'tag': 'h2'}, '')]
    >>> [(m, v, y) for m, v, y in t({}, '<h1>Ori</h1><h2>Dori</h2>') if m]
    [(True, {'names': ['Ori'], 'tag': 'h1'}, '<h2>Dori</h2>'), (True, {'names': []}, '<h1>Ori</h1><h2>Dori</h2>')]
    """
    def q(c, x):
        for m, d, y in p(c, x):
            if m:
                v = sat.get(l, d)
                e = sat.rem(l, sat.upd(k, lambda w: w + [v], d))
                yield True, e, y
            else:
                yield m, d, y

    def f():
        return alt(seq(q, ref(f)), eps())

    return let(lambda: [sat.ctx(k, [])], ref(f))
Esempio n. 2
0
 def p(c, x):
     v = ''
     y = x
     while len(y) > 0 and y[0] not in r:
         d = sat.ctx(k, f(v))
         if sat.cmp(c, d):
             yield True, sat.cmb(c, d), y
         # note: not yielding a failure here, because it would be either:
         #   - unnecessary because of a match at the end
         #   - identical to the failure yielded at the end
         v = v + y[0]
         y = y[1:]
     d = sat.ctx(k, f(v))
     if sat.cmp(c, d):
         yield True, sat.cmb(c, d), y
     else:
         yield False, sat.get(k, c), x
Esempio n. 3
0
def var(k):
    """
    Match a value into a variable k
    >>> e = var('foo')
    >>> e('bar')
    [{'foo': 'bar'}]
    """
    return lambda x: [sat.ctx(k, x)]
Esempio n. 4
0
    def _calc_lookup_key(self, target_expression, key_expression):
        if target_expression.data == 'target_object' and key_expression.data == 'target_object':
            pairs = {
                str(target_pair.children[0]):
                (target_pair.children[1]
                 if target_pair.data == 'target_full_pair' else Tree(
                     'target_variable', target_pair.children))
                for target_pair in target_expression.children
                if target_pair.data in ('target_shorthand_pair',
                                        'target_full_pair')
            }
            rest = next((child.children[0]
                         for child in target_expression.children
                         if child.data == 'target_rest_expression'), None)

            lookup_key = {}
            for child in key_expression.children:
                if child.data == 'target_shorthand_pair':
                    key = str(child.children[0])
                    if key not in pairs:
                        return None
                    elif pairs[key].data != 'target_constant':
                        return None
                    else:
                        lookup_key = sat.cmb(
                            lookup_key,
                            sat.ctx(key, json.loads(pairs[key].children[0])))
                elif child.data == 'target_full_pair':
                    key = str(child.children[0])
                    if key not in pairs:
                        return None
                    else:
                        lookup_key = sat.cmb(
                            lookup_key,
                            self._calc_lookup_key(pairs[key],
                                                  child.children[1]))
                elif child.data == 'target_rest_expression':
                    if rest is None:
                        return None

            return lookup_key
        elif target_expression.data == 'target_constant' and key_expression.data == 'target_variable':
            return sat.ctx(str(key_expression.children[0]),
                           json.loads(target_expression.children[0]))
        else:
            return None
Esempio n. 5
0
def als(e, k):
    """
    Destructure a value using expression e, assigning te original value to alias k
    >>> e = als(lit('foo'), 'foo')
    >>> e('bar')
    []
    >>> e('foo')
    [{'foo': 'foo'}]
    """
    return lambda x: [
        sat.cmb(c, d) for c in e(x) for d in [sat.ctx(k, x)] if sat.cmp(c, d)
    ]
Esempio n. 6
0
def key(i):
    """
    Match a value into key i
    >>> e = key(0)
    >>> e('bar')  # doctest: +ELLIPSIS
    [{'$keys': <function ...>}]
    >>> sat.cmp(e('bar')[0], {'$keys': ['bar', 'baz']})
    True
    >>> sat.cmp(e('bar')[0], {'$keys': ['baz', 'bar']})
    False
    """
    return lambda x: [
        sat.ctx('$keys', lambda y: isinstance(y, list) and len(y) > i and y[i]
                == x)
    ]