Ejemplo n.º 1
0
    def Parse(self, query, table=None):
        """
        Parses the query string and returns (sql, sql params, words).

        @param   table  if set, search is performed on all the fields of this
                        specific table, ignoring all Skype-specific keywords,
                        only taking into account the table: keyword
                        {"name": "Table name": "columns[{"name", "pk_id", }, ]}
        @return         (SQL string, SQL parameter dict, word and phrase list)
        """
        words = []  # All encountered text words and quoted phrases
        keywords = collections.defaultdict(
            list)  # {"from": [], "chat": [], ..}
        sql_params = {
        }  # Parameters for SQL query {"body_like0": "%word%", ..}

        try:
            parse_results = self._grammar.parseString(query, parseAll=True)
        except Exception:
            # Grammar parsing failed: do a naive parsing into keywords and words
            split_words = query.split()

            for word in split_words[:]:
                if self.PATTERN_KEYWORD.match(word):
                    _, negation, key, value, _ = self.PATTERN_KEYWORD.split(
                        word)
                    key = negation + key
                    keywords[key.lower()].append(value)
                    split_words.remove(word)
            try:
                parse_results = ParseResults(split_words)
            except NameError:  # pyparsing.ParseResults not available
                parse_results = split_words

        result = self._makeSQL(parse_results,
                               words,
                               keywords,
                               sql_params,
                               table=table)
        if table:
            skip_table = False
            for kw, values in keywords.items():
                if ("table"  == kw and table["name"].lower() not in values) \
                or ("-table" == kw and table["name"].lower() in values):
                    skip_table = True
                    break  # break for kw, value in keywords.items()
            if skip_table:
                result = ""
            else:
                result = "SELECT * FROM %s WHERE %s" % (table["name"], result)
                for col in table["columns"]:
                    if col.get("pk"):
                        result += " ORDER BY %s ASC" % col["name"]
                        break  # break for col in table["columns"]
        else:
            if "table" in keywords: del keywords["table"]
            if "-table" in keywords: del keywords["-table"]
            kw_sql = self._makeKeywordsSQL(keywords, sql_params)
        if not table and kw_sql:
            result = "%s%s" % ("%s AND " % result if result else "", kw_sql)

        return result, sql_params, words
Ejemplo n.º 2
0
def turn_parseresults_to_list(s, loc, toks):
	return ParseResults(normalise_templates(toks[0].asList()))
Ejemplo n.º 3
0
def tree2str(t: ParseResults) -> str:
    out = []
    if isinstance(t, ParseResults):
        for e in t.asList():
            out.append(tree2str(e))
        for k, v in sorted(t.items()):
            out.append(tree2str(v))

    elif isinstance(t, CompValue):
        if t.name == 'PrefixDecl' and 'iri' in t:
            pref = t['prefix'] if 'prefix' in t else ''
            out.append('PREFIX %s: %s\n' % (pref, t['iri'].n3()))

        elif t.name.endswith('Query') or t.name.startswith('Sub'):
            ret = []
            for k, v in t.items():
                if k == 'modifier':
                    ret.append(v)
                elif k == 'projection':
                    ret.append(list2str(v, ele2str, joiner=' '))
                elif k == 'template':
                    ret.append('{%s}' % list2str(v, triple2str))
                elif k == 'limitoffset':
                    for k_, v_ in v.items():
                        ret.append('%s %s \n' % (k_.upper(), tree2str(v_)))
                elif k in fixed_recursion:
                    ret.append(fixed_recursion[k] % (tree2str(v)))
                else:
                    ret.append(tree2str(v))
            query_type = t.name[:-5] if t.name.endswith(
                'Query') else t.name[3:]
            out.append('%s %s' % (query_type.upper(), ' '.join(ret)))

        elif t.name == 'TriplesBlock' and 'triples' in t:
            for tri in t['triples']:
                out.append('%s\n' % (triple2str(tri)))
        elif t.name == 'OptionalGraphPattern' and 'graph' in t:
            out.append('OPTIONAL {%s} .\n' % tree2str(t['graph']))
        elif t.name == 'InlineData' and 'var' in t and 'value' in t:
            out.append(
                'Values (%s) {%s} .\n' %
                (ele2str(t['var']),
                 list2str(
                     t['value'], ele2str, prefix='(', suffix=')',
                     joiner='\n')))
        elif t.name == 'GroupOrUnionGraphPattern' and 'graph' in t:
            if len(t['graph']) > 1:
                ret = []
                for x in t['graph']:
                    ret.append(tree2str(x))
                out.append('{\n%s\n}' % ('\n} UNION {\n'.join(ret)))
            elif len(t['graph']) == 1:
                out.append('{\n%s\n}' % tree2str(t['graph']))
        elif t.name in ['Filter']:
            out.append('\n%s ( %s ) .\n' %
                       (t.name.upper(), ele2str(t['expr'])))
        elif t.name == 'OrderCondition' and 'order' in t and 'expr' in t:
            out.append('%s(%s)' % (ele2str(t['order']), ele2str(t['expr'])))

        else:
            for k, v in t.items():
                out.append(tree2str(v))
    elif isinstance(t, dict):
        for k, v in t.items():
            out.append(tree2str(v))
    elif isinstance(t, list):
        for e in t:
            out.append(tree2str(e))
    else:
        out.append("%s " % (ele2str(t)))
    return "".join(out)
Ejemplo n.º 4
0
 def __init__(self, t: ParseResults):
     self.typename = Typename(t.asList())
Ejemplo n.º 5
0
def parse_join(x, op="and"):
    result = [op] * (len(x) * 2 - 1)
    result[0::2] = x
    return ParseResults(result)
Ejemplo n.º 6
0
 def StatementLiteral(self, lhs, comp, rhs):
     return ParseResults(lhs, "lhs", False)  + \
         ParseResults(comp, "comp", False) + \
         ParseResults([rhs], "rhs", True)
Ejemplo n.º 7
0
 def _prepare_args_completions(
     self, parsed_command: pp.ParseResults, last_token
 ) -> Iterable[Completion]:
     assert parsed_command is not None
     args_meta = self.meta.arguments.values()
     # are we expecting a sub command?
     if self.cmd.super_command:
         # We have a sub-command (supposedly)
         subcommand = parsed_command.get("__subcommand__")
         assert subcommand
         sub_meta = self.cmd.subcommand_metadata(subcommand)
         if not sub_meta:
             logging.debug("Parsing unknown sub-command failed!")
             return []
         # we did find the sub-command, yay!
         # In this case we chain the arguments from super and the
         # sub-command together
         args_meta = itertools.chain(args_meta, sub_meta.arguments.values())
     # Now let's see if we can figure which argument we are talking about
     args_meta = self._filter_arguments_by_prefix(last_token, args_meta)
     # Which arguments did we fully parse already? let's avoid printing them
     # in completions
     parsed_keys = parsed_command.asDict().get("kv", [])
     # We are either completing an argument name, argument value, or
     # positional value.
     # Dissect the last_token and figure what is the right completion
     parsed_token = TokenParse(last_token)
     if parsed_token.is_positional:
         # TODO: Handle positional argument completions too
         # To figure which positional we are in right now, we need to run the
         # same logic that figures if all required arguments has been
         # supplied and how many positionals have been processed and which
         # one is next.
         # This code is already in cmdbase.py run_interactive but needs to be
         # refactored to be reusable here.
         pass
     elif parsed_token.is_argument:
         argument_name = parsed_token.argument_name
         arg = self._find_argument_by_name(argument_name)
         if not arg or arg.choices in [False, None]:
             return []
         # TODO: Support dictionary keys/named tuples completion
         if parsed_token.is_dict:
             return []
         # We are completing a value, in this case, we need to get the last
         # meaninful piece of the token `x=[Tr` => `Tr`
         return [
             Completion(
                 text=str(choice),
                 start_position=-len(parsed_token.last_value),
             )
             for choice in arg.choices
             if str(choice).lower().startswith(parsed_token.last_value.lower())
         ]
     # We are completing arguments, or positionals.
     # TODO: We would like to only show positional choices if we exhaust all
     # required arguments. This will make it easier for the user to figure
     # that there are still required named arguments. After that point we
     # will show optional arguments and positionals as possible completions
     ret = [
         Completion(
             text=arg_meta.name + "=",
             start_position=-len(last_token),
             display_meta=self._get_arg_help(arg_meta),
         )
         for arg_meta in args_meta
         if arg_meta.name not in parsed_keys
     ]
     return ret
Ejemplo n.º 8
0
 def __init__(self, item: ParseResults):
     self.carrots = len(item.get('carrots', ''))
     self.explicitlyIndexed = ('index' in item)
     self.index = int(item['index']) if 'index' in item else None
     self.bang = item.get('bang', '') == '!'
 def _parse_action(tokens):
     """Wrap children in a group if there are multiple"""
     if len(tokens) > 1:
         return ParseResults(toklist=[tokens], name=name)
     return tokens
Ejemplo n.º 10
0
 def from_parse_result(parse_result: ParseResults):
     """Return the result of parsing."""
     if parse_result:
         return ArgumentList(parse_result.asList())
     else:
         return ArgumentList([])
Ejemplo n.º 11
0
    def _ast_to_dictsql(self, input_ast):
        """
        """
        # Add implicit AND operator between expressions if there is no explicit
        # operator specified.
        ast = []
        for token, lookahead in izip_longest(input_ast, input_ast[1:]):
            if token.getName() == "boolean":
                # only add boolean operator if it is NOT the last token
                if lookahead is not None:
                    ast.append(token)
                continue
            else:
                # add non-boolean token
                ast.append(token)
                # if next token is boolean, continue so it can be added
                if lookahead is None or lookahead.getName() == "boolean":
                    continue
                # if next token is NOT a boolean, add implicit AND
                ast.append(ParseResults('and', 'boolean'))

        # dictSql stack
        dss = {'operator': None, 'val1': None, 'val2': None}
        success = True
        dse = None
        for part, lookahead in izip_longest(ast, ast[1:]):
            self._logger.debug("part: %s %s" % (part, part.getName()))

            # handle operators joining together expressions
            if part.getName() == 'boolean':
                op = part[0].lower()
                dss['operator'] = op
                dss['interpretation'] = {
                    'interpretation': op,
                    'operator': op,
                    'error': False
                }
                continue

            # string expr that we expand to dictsql expression
            elif part.getName() == 'expression':
                if part.operator in self.match_operators:
                    tmp_success, dse = self._parse_expr(part)
                    success = success and tmp_success
                else:
                    tmp_success, dse = self._ast_to_dictsql(part)
                    success = success and tmp_success
            elif part.getName() == 'nested':
                tmp_success, dse = self._ast_to_dictsql(part)
                success = success and tmp_success
            elif part.getName() in ('ipv6_prefix', 'ipv6_address', 'word',
                                    'tag', 'vrf_rt', 'quoted_string'):
                # dict sql expression
                dse = self._string_to_dictsql(part)
                self._logger.debug('string part: %s  => %s' % (part, dse))
            else:
                raise ParserError("Unhandled part in AST: %s %s" %
                                  (part, part.getName()))

            if dss['val1'] is None:
                self._logger.debug('val1 not set, using dse: %s' %
                                   unicode(dse))
                dss['val1'] = dse
            else:
                self._logger.debug(
                    "val1 is set, operator is '%s', val2 = dst: %s" %
                    (dss['operator'], unicode(dse)))
                dss['val2'] = dse

            if lookahead is not None:
                if dss['val1'] is not None and dss['val2'] is not None:
                    dss = {'operator': None, 'val1': dss, 'val2': None}

        # special handling when AST is only one expression, then we overwrite
        # the dss with dse
        if len(ast) == 1:
            dss = dse
        if len(ast) == 0:
            dss = self._string_to_dictsql(ParseResults('', 'word'))

        # return the final composed stack of dictsql expressions
        return success, dss
Ejemplo n.º 12
0
 def _Parse(self, parts: pp.ParseResults):
     self.library = parts.get("library")
     self.element = parts.get("element")
     self.object = parts.get("object")
Ejemplo n.º 13
0
 def _Parse(self, parts: pp.ParseResults):
     self.left = parts.get("left")
     self.right = parts.get("right")
     self.direction = str(parts.get("dir")).lower()
Ejemplo n.º 14
0
 def __init__(self, exprs):
     self.exprs = ParseResults(exprs)
Ejemplo n.º 15
0
def parse_add(*args, **kwargs):
    op = kwargs.get("op", "and")
    x = args[0]
    for y in args[1:]:
        x = x + ParseResults(op) + y
    return ParseResults(x)
Ejemplo n.º 16
0
 def call_parse_result(self, res: pp.ParseResults, msg, *args, **kwargs):
     d = res.asDict()
     if "help" in d["options"]:
         return d["options"]["help"]
     return d["command"](msg, *args, bot=self, args=d["options"], **kwargs)
Ejemplo n.º 17
0
def parse_refinement(string: str, location: int, tokens: ParseResults) -> Type:
    if "constraint" not in tokens:
        tokens.append(TRUE)
    return Refinement("", tokens[0], Field(tokens[1]), tokens[2], tokens[3])