def _make(): # Order is important - multi-char expressions need to come before narrow # ones. parts = [] for klass in filt_unary: f = pp.Literal("~%s"%klass.code) f.setParseAction(klass.make) parts.append(f) simplerex = "".join(c for c in pp.printables if c not in "()~'\"") rex = pp.Word(simplerex) |\ pp.QuotedString("\"", escChar='\\') |\ pp.QuotedString("'", escChar='\\') for klass in filt_rex: f = pp.Literal("~%s"%klass.code) + rex.copy() f.setParseAction(klass.make) parts.append(f) for klass in filt_int: f = pp.Literal("~%s"%klass.code) + pp.Word(pp.nums) f.setParseAction(klass.make) parts.append(f) # A naked rex is a URL rex: f = rex.copy() f.setParseAction(FUrl.make) parts.append(f) atom = pp.MatchFirst(parts) expr = pp.operatorPrecedence( atom, [ (pp.Literal("!").suppress(), 1, pp.opAssoc.RIGHT, lambda x: FNot(*x)), (pp.Literal("&").suppress(), 2, pp.opAssoc.LEFT, lambda x: FAnd(*x)), (pp.Literal("|").suppress(), 2, pp.opAssoc.LEFT, lambda x: FOr(*x)), ] ) expr = pp.OneOrMore(expr) return expr.setParseAction(lambda x: FAnd(x) if len(x) != 1 else x)
ascii_uppercase=string.ascii_uppercase, digits=string.digits, hexdigits=string.hexdigits, octdigits=string.octdigits, punctuation=string.punctuation, whitespace=string.whitespace, ascii=string.printable, bytes="".join(chr(i) for i in range(256))) v_integer = pp.Word(pp.nums)\ .setName("integer")\ .setParseAction(lambda toks: int(toks[0])) v_literal = pp.MatchFirst([ pp.QuotedString("\"", escChar="\\", unquoteResults=True, multiline=True), pp.QuotedString("'", escChar="\\", unquoteResults=True, multiline=True), ]) v_naked_literal = pp.MatchFirst([ v_literal, pp.Word("".join(i for i in pp.printables if i not in ",:\n@\'\"")) ]) class LiteralGenerator: def __init__(self, s): self.s = s def __len__(self): return len(self.s)