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
def turn_parseresults_to_list(s, loc, toks): return ParseResults(normalise_templates(toks[0].asList()))
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)
def __init__(self, t: ParseResults): self.typename = Typename(t.asList())
def parse_join(x, op="and"): result = [op] * (len(x) * 2 - 1) result[0::2] = x return ParseResults(result)
def StatementLiteral(self, lhs, comp, rhs): return ParseResults(lhs, "lhs", False) + \ ParseResults(comp, "comp", False) + \ ParseResults([rhs], "rhs", True)
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
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
def from_parse_result(parse_result: ParseResults): """Return the result of parsing.""" if parse_result: return ArgumentList(parse_result.asList()) else: return ArgumentList([])
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
def _Parse(self, parts: pp.ParseResults): self.library = parts.get("library") self.element = parts.get("element") self.object = parts.get("object")
def _Parse(self, parts: pp.ParseResults): self.left = parts.get("left") self.right = parts.get("right") self.direction = str(parts.get("dir")).lower()
def __init__(self, exprs): self.exprs = ParseResults(exprs)
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)
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)
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])