def parse_expression(q): if q[0] == "(": lhs, q = parse_boolean(q[1:]) q = _expect(")", q) return lhs, q elif q[0] == "attr": lhs, q = parse_attribute(_expect("attr", q)) elif "." in q[0]: raise StringParseError("Found a . in %s; missing attr?" % q[0]) else: for op, kls in sorted(UNARY_BOOLEAN_OPERATORS.iteritems(), key=len, reverse=True): if op == q[0]: exp, rest = parse_expression(_expect(op, q)) return kls(exp), rest else: lhs = q[0] q = q[1:] for op, kls in sorted(SUFFIX_OPERATORS.iteritems(), key=len, reverse=True): if q[0] == op: return kls(lhs), q[1:] for op, kls in sorted(INFIX_OPERATORS.iteritems(), key=len, reverse=True): if q[0] == op: return kls(lhs, q[1]), q[2:] else: raise UnexpectedTokenError(q)
def lex(q): keywords = ["attr"] keywords.extend(SEARCH_KEYWORDS) keywords.extend(BOOLEAN_OPERATORS.keys()) keywords.extend(UNARY_BOOLEAN_OPERATORS.keys()) keywords.extend(INFIX_OPERATORS.keys()) keywords.extend(("(", ")")) keywords.sort(key=len, reverse=True) results = [] while q: q = q.lstrip() for keyword in keywords: if q.startswith(keyword): if _unquoted_string_re.match(keyword): if not _separator_re.match(consume(keyword, q)): continue results.append(keyword) q = consume(keyword, q) break else: result, q = lex_string(q) results.append(result) return results