QueryParser.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. import pyparsing as pp
  2. class QueryParser:
  3. def __init__(self):
  4. # TODO: allow lists as input, like: ipaddress(macaddress in [1,2,3])
  5. extractor = pp.Keyword("random") ^ pp.Keyword("first") ^ pp.Keyword("last")
  6. # Valid selectors - except "avg", because not all attributes can be combined with it
  7. selector_no_avg = pp.Keyword("most_used") ^ pp.Keyword("least_used") ^ pp.Keyword("all")
  8. attributes_no_avg = pp.Keyword("ipaddress") ^ pp.Keyword("macaddress") ^ pp.Keyword("portnumber") ^\
  9. pp.Keyword("protocolname") ^ pp.Keyword("winsize") ^ pp.Keyword("ipclass")
  10. attributes_avg = pp.Keyword("ttlvalue") ^ pp.Keyword("mssvalue") ^\
  11. pp.Keyword("pktssent") ^ pp.Keyword("pktsreceived") ^ pp.Keyword("mss") ^\
  12. pp.Keyword("kbytesreceived") ^ pp.Keyword("kbytessent")
  13. attributes_all = attributes_no_avg ^ attributes_avg
  14. simple_selector_query = (selector_no_avg + pp.Suppress("(") + attributes_all + pp.Suppress(")")) ^\
  15. (pp.Keyword("avg") + pp.Suppress("(") + attributes_avg + pp.Suppress(")"))
  16. param_selectors = pp.Keyword("ipaddress").setParseAction(pp.replaceWith("ipaddress_param")) ^\
  17. pp.Keyword("macaddress").setParseAction(pp.replaceWith("macaddress_param"))
  18. operators = pp.Literal("<=") ^ pp.Literal("<") ^ pp.Literal("=") ^\
  19. pp.Literal(">=") ^ pp.Literal(">") ^ pp.CaselessLiteral("in")
  20. expr = pp.Forward()
  21. comparison = pp.Group(attributes_all + operators + (pp.Word(pp.alphanums + ".:") ^ expr))
  22. parameterized_query = param_selectors + pp.Suppress("(") + pp.Group(pp.delimitedList(comparison)) + pp.Suppress(")")
  23. all_selector_queries = (simple_selector_query ^ parameterized_query)
  24. extractor_selector_query = extractor + pp.Suppress("(") + all_selector_queries + pp.Suppress(")")
  25. named_query = (extractor_selector_query ^ all_selector_queries)
  26. expr << pp.Group(named_query)
  27. self.full_query = named_query + pp.Suppress(";")
  28. def parse_query(self, querystring: str) -> pp.ParseResults:
  29. return self.full_query.parseString(querystring)