| 1557 | } |
| 1558 | |
| 1559 | def match_atom(token, p): |
| 1560 | if not token: |
| 1561 | return None |
| 1562 | if not p: |
| 1563 | return None |
| 1564 | if token.str == p: |
| 1565 | return token |
| 1566 | if p in ['!', '|', '||', '%', '!=', '*']: |
| 1567 | return None |
| 1568 | if p in patterns: |
| 1569 | return patterns[p](token) |
| 1570 | if '|' in p: |
| 1571 | for x in p.split('|'): |
| 1572 | t = match_atom(token, x) |
| 1573 | if t: |
| 1574 | return t |
| 1575 | elif p.startswith('!!'): |
| 1576 | t = match_atom(token, p[2:]) |
| 1577 | if not t: |
| 1578 | return token |
| 1579 | elif p.startswith('**'): |
| 1580 | a = p[2:] |
| 1581 | t = token |
| 1582 | while t: |
| 1583 | if match_atom(t, a): |
| 1584 | return t |
| 1585 | if t.link and t.str in ['(', '[', '<', '{']: |
| 1586 | t = t.link |
| 1587 | t = t.next |
| 1588 | return None |
| 1589 | |
| 1590 | class MatchResult: |
| 1591 | def __init__(self, matches, bindings=None, keys=None): |