Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from pyparsing import ZeroOrMore
from pyparsing import alphanums
from pyparsing import nums
# Intermediate parsers
_varchar_names = (CaselessKeyword('VARCHAR') | CaselessKeyword('TEXT'))
_varchar_names |= CaselessKeyword('NVARCHAR')
# Data types
_smallint = (CaselessKeyword('SMALLINT') | CaselessKeyword('INT2'))
_integer = CaselessKeyword('INTEGER')
_integer |= CaselessKeyword('INT') | CaselessKeyword('INT4')
_bigint = (CaselessKeyword('BIGINT') | CaselessKeyword('INT8'))
_decimal = Combine((CaselessKeyword('DECIMAL') | CaselessKeyword('NUMERIC')) + '(' + Word(nums + ' ,') + ')') # noqa
_real = (CaselessKeyword('REAL') | CaselessKeyword('FLOAT4'))
_double = (CaselessKeyword('DOUBLE PRECISION') | CaselessKeyword('FLOAT') | CaselessKeyword('FLOAT8') | CaselessKeyword('DOUBLE')) # noqa
_boolean = CaselessKeyword('BOOLEAN')
_char = (CaselessKeyword('CHAR') | CaselessKeyword('CHARACTER'))
_char |= (CaselessKeyword('NCHAR') | CaselessKeyword('BPCHAR'))
_varchar = Combine(_varchar_names + '(' + Word(alphanums) + ')')
_date = CaselessKeyword('DATE')
_text = CaselessKeyword('TEXT')
_timestamp = CaselessKeyword('TIMESTAMP')
# Create SQL keywords
_create = CaselessKeyword('CREATE')
_table = CaselessKeyword('TABLE')
_view = CaselessKeyword('VIEW')
_temp = CaselessKeyword('TEMP')
_temporary = CaselessKeyword('TEMPORARY')
_if_not_exists = CaselessKeyword('IF NOT EXISTS')
_or_replace = CaselessKeyword('OR REPLACE')
def AddWithin(tokens):
clauses['WITHIN'][len(clauses['SELECT'])] = tokens[0]
def AddJoinArgument(tokens):
clauses[tokens[0]].append(list(temp_stack))
temp_stack[:] = []
temp_stack = []
as_kw = pp.CaselessKeyword('AS')
select_kw = pp.CaselessKeyword('SELECT')
within_kw = pp.CaselessKeyword('WITHIN')
flatten_kw = pp.CaselessKeyword('FLATTEN')
from_kw = pp.CaselessKeyword('FROM')
join_kw = pp.CaselessKeyword('JOIN')
join_on_kw = pp.CaselessKeyword('ON')
where_kw = pp.CaselessKeyword('WHERE')
having_kw = pp.CaselessKeyword('HAVING')
order_kw = pp.CaselessKeyword('ORDER BY')
asc_kw = pp.CaselessKeyword('ASC')
desc_kw = pp.CaselessKeyword('DESC')
group_kw = pp.CaselessKeyword('GROUP BY')
limit_kw = pp.CaselessKeyword('LIMIT')
push_label = pp.Word(
pp.alphas, pp.alphas + pp.nums + '_' + '.').setParseAction(AddLabel)
pos_int = pp.Word(pp.nums).setParseAction(AddInteger)
order_label = (push_label +
pp.Optional((asc_kw | desc_kw).setParseAction(AddLast)))
label = pp.Word(pp.alphas, pp.alphas + pp.nums + '_' + '.')
alias_label = pp.Word(
def define_shape(name, shape_args, args_repeat=None):
lparen = Literal("(").suppress()
rparen = Literal(")").suppress()
comma = Literal(",").suppress()
shape_name = CaselessKeyword(name)
if args_repeat is None:
shape_with_parens = And([shape_name, lparen,
as_comma_separated_list(shape_args),
rparen])
shape_with_spaces = shape_name + And(shape_args)
else:
n1, n2 = args_repeat
sl = []
ss = shape_args[:n1]
if ss:
sl.append(as_comma_separated_list(ss))
class ExWithinSelection(Selection):
"""Exclusive within :class:`Selection` class."""
def apply(self, atoms):
other = self.selection[-1].apply(atoms)
filtered = atoms.query_ball_tree(other, self.selection[0])
filtered = super().apply(atoms, filtered=filtered) - other
return super().apply(atoms, filtered=filtered)
class AtomsSelectionParser(BaseClass):
"""Selection parser class."""
ALL = CaselessKeyword('all')
NONE = CaselessKeyword('none')
NAME = CaselessKeyword('name')
TYPE = CaselessKeyword('type')
INDEX = CaselessKeyword('index')
ID = CaselessKeyword('id')
MOLID = CaselessKeyword('molid') | CaselessKeyword('mol')
WITHIN = CaselessKeyword('within')
EXWITHIN = CaselessKeyword('exwithin')
SERIAL = CaselessKeyword('serial')
ATOMICNUMBER = CaselessKeyword('atomicnumber')
ELEMENT = CaselessKeyword('element')
RESIDUE = CaselessKeyword('residue')
NUMBONDS = CaselessKeyword('numbonds')
OF = CaselessKeyword('of')
NOT = CaselessKeyword('not')
AND = CaselessKeyword('and')
OR = CaselessKeyword('or')
def _parse_query(self):
"""
Defines and parses the Resource DSL based on the query associated with the PanoptesResourceDSL object
Returns:
list: The list of tokens parsed
Raises:
ParseException: This exception is raised if any parsing error occurs
"""
resource_fields = oneOf(
'resource_site resource_class resource_subclass resource_type resource_id resource_endpoint',
caseless=True)
resource_metadata = CaselessLiteral('resource_metadata') + Literal('.') + Word(alphanums + '_')
and_ = CaselessKeyword('AND').setParseAction(upcaseTokens)
or_ = CaselessKeyword('OR').setParseAction(upcaseTokens)
not_ = CaselessKeyword('NOT').setParseAction(upcaseTokens)
in_ = CaselessKeyword('IN').setParseAction(upcaseTokens)
like_ = CaselessKeyword('LIKE').setParseAction(upcaseTokens)
operators = oneOf("= != eq ne", caseless=True).setParseAction(upcaseTokens)
query_expression = Forward()
query_l_val = (resource_fields | resource_metadata).setParseAction(downcaseTokens)
query_r_val = QuotedString(quoteChar='"', escChar='\\')
query_condition = Group(
(query_l_val + operators + query_r_val) |
(query_l_val + Optional(not_) + like_ + query_r_val) |
(query_l_val + Optional(not_) + in_ + '(' + delimitedList(query_r_val) + ')')
def AddJoinArgument(tokens):
clauses[tokens[0]].append(list(temp_stack))
temp_stack[:] = []
temp_stack = []
as_kw = pp.CaselessKeyword('AS')
select_kw = pp.CaselessKeyword('SELECT')
within_kw = pp.CaselessKeyword('WITHIN')
flatten_kw = pp.CaselessKeyword('FLATTEN')
from_kw = pp.CaselessKeyword('FROM')
join_kw = pp.CaselessKeyword('JOIN')
join_on_kw = pp.CaselessKeyword('ON')
where_kw = pp.CaselessKeyword('WHERE')
having_kw = pp.CaselessKeyword('HAVING')
order_kw = pp.CaselessKeyword('ORDER BY')
asc_kw = pp.CaselessKeyword('ASC')
desc_kw = pp.CaselessKeyword('DESC')
group_kw = pp.CaselessKeyword('GROUP BY')
limit_kw = pp.CaselessKeyword('LIMIT')
push_label = pp.Word(
pp.alphas, pp.alphas + pp.nums + '_' + '.').setParseAction(AddLabel)
pos_int = pp.Word(pp.nums).setParseAction(AddInteger)
order_label = (push_label +
pp.Optional((asc_kw | desc_kw).setParseAction(AddLast)))
label = pp.Word(pp.alphas, pp.alphas + pp.nums + '_' + '.')
alias_label = pp.Word(
pp.alphas, pp.alphas + pp.nums + '_' + '.').setParseAction(AddAlias)
within_label = pp.Word(
pp.alphas, pp.alphas + pp.nums + '_' + '.').setParseAction(AddWithin)
| Comp('Builtin_SECONDS', Keyword('SECONDS') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_SECONDS) \
| Comp('Builtin_TIMEZONE', Keyword('TIMEZONE') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_TIMEZONE) \
| Comp('Builtin_TZ', Keyword('TZ') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_TZ) \
| Comp('Builtin_NOW', Keyword('NOW') + NIL).setEvalFn(op.Builtin_NOW) \
| Comp('Builtin_UUID', Keyword('UUID') + NIL).setEvalFn(op.Builtin_UUID) \
| Comp('Builtin_STRUUID', Keyword('STRUUID') + NIL).setEvalFn(op.Builtin_STRUUID) \
| Comp('Builtin_MD5', Keyword('MD5') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_MD5) \
| Comp('Builtin_SHA1', Keyword('SHA1') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_SHA1) \
| Comp('Builtin_SHA256', Keyword('SHA256') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_SHA256) \
| Comp('Builtin_SHA384', Keyword('SHA384') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_SHA384) \
| Comp('Builtin_SHA512', Keyword('SHA512') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_SHA512) \
| Comp('Builtin_COALESCE', Keyword('COALESCE') + Param('arg', ExpressionList)).setEvalFn(op.Builtin_COALESCE) \
| Comp('Builtin_IF', Keyword('IF') + '(' + Param('arg1', Expression) + ',' + Param('arg2', Expression) + ',' + Param('arg3', Expression) + ')').setEvalFn(op.Builtin_IF) \
| Comp('Builtin_STRLANG', Keyword('STRLANG') + '(' + Param('arg1', Expression) + ',' + Param('arg2', Expression) + ')').setEvalFn(op.Builtin_STRLANG) \
| Comp('Builtin_STRDT', Keyword('STRDT') + '(' + Param('arg1', Expression) + ',' + Param('arg2', Expression) + ')').setEvalFn(op.Builtin_STRDT) \
| Comp('Builtin_sameTerm', Keyword('sameTerm') + '(' + Param('arg1', Expression) + ',' + Param('arg2', Expression) + ')').setEvalFn(op.Builtin_sameTerm) \
| Comp('Builtin_isIRI', Keyword('isIRI') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_isIRI) \
| Comp('Builtin_isURI', Keyword('isURI') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_isIRI) \
| Comp('Builtin_isBLANK', Keyword('isBLANK') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_isBLANK) \
| Comp('Builtin_isLITERAL', Keyword('isLITERAL') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_isLITERAL) \
| Comp('Builtin_isNUMERIC', Keyword('isNUMERIC') + '(' + Param('arg', Expression) + ')').setEvalFn(op.Builtin_isNUMERIC) \
| RegexExpression \
| ExistsFunc \
| NotExistsFunc
# [71] ArgList ::= NIL | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
ArgList = NIL | '(' + Param('distinct', _Distinct) + delimitedList(
ParamList('expr', Expression)) + ')'
# [128] iriOrFunction ::= iri Optional(ArgList)
iriOrFunction = (Comp(
'Function', Param('iri', iri) + ArgList).setEvalFn(op.Function)) | iri
def parse(self, query):
"""Parses a query string."""
# Parse instructions
quoted_string = QuotedString(quoteChar='"', escChar='\\', unquoteResults=True)
field_name = Word(alphas, alphanums + '_')
subexpression = Forward()
boolean_expression = Forward()
binary_operator = Literal('=') | Literal('<=') | Literal('<') | Literal('>=') | Literal('>')
boolean_operator = CaselessKeyword('AND') | CaselessKeyword('OR')
boolean_not = CaselessKeyword('NOT')
boolean_value = CaselessKeyword("true") ^ CaselessKeyword("false")
integer = Word(nums)
rvalue = quoted_string ^ boolean_value ^ integer
field_to_value = field_name + binary_operator + rvalue
expression = Optional(boolean_not) + ((subexpression + ZeroOrMore(boolean_expression)) | (field_to_value + ZeroOrMore(boolean_expression)))
boolean_expression << boolean_operator + expression
left_bracket = Literal('(')
right_bracket = Literal(')')
subexpression << (left_bracket + expression + right_bracket)
search_query = expression
# Parse actions for emitting special cases
field_to_value.setParseAction(do_field_to_value)
boolean_operator.setParseAction(do_boolean_operator)
boolean_not.setParseAction(do_boolean_operator)
boolean_value.setParseAction(do_boolean_value)
integer.setParseAction(do_integer)
"sqrt": self.sqrt,
"cos": self.cos,
"sin": self.sin,
"tan": self.tan,
"acos": self.acos,
"asin": self.asin,
"atan": self.atan,
"distance": self.distance,
}
self.conditionals = ["==", "!=", ">", ">=", "<", "<="]
# use CaselessKeyword for e and pi, to avoid accidentally matching
# functions that start with 'e' or 'pi' (such as 'exp'); Keyword
# and CaselessKeyword only match whole words
e = CaselessKeyword("E")
pi = CaselessKeyword("PI")
# fnumber = Combine(Word("+-"+nums, nums) +
# Optional("." + Optional(Word(nums))) +
# Optional(e + Word("+-"+nums, nums)))
# or use provided pyparsing_common.number, but convert back to str:
# fnumber = ppc.number().addParseAction(lambda t: str(t[0]))
fnumber = Regex(r"[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?")
ident = Word(alphas, alphanums + "_$")
plus, minus, mult, div = map(Literal, "+-*/")
lpar, rpar = map(Suppress, "()")
addop = plus | minus
multop = mult | div
expop = Literal("^")
comparison_op = oneOf(" ".join(self.conditionals))
qm, colon = map(Literal, "?:")
assignment = Literal("=")
Verb.setName('Verb')
# Expression:
Expression = Forward()
if DEBUG:
Expression.setName('Expression')
# BuiltInCall:
STR = Suppress(CaselessKeyword('STR'))
LANG = Suppress(CaselessKeyword('LANG'))
LANGMATCHES = Suppress(CaselessKeyword('LANGMATCHES'))
DATATYPE = Suppress(CaselessKeyword('DATATYPE'))
BOUND = Suppress(CaselessKeyword('BOUND'))
isIRI = Suppress(CaselessKeyword('isIRI'))
isURI = Suppress(CaselessKeyword('isURI'))
isBLANK = Suppress(CaselessKeyword('isBLANK'))
isLITERAL = Suppress(CaselessKeyword('isLITERAL'))
sameTerm = Suppress(CaselessKeyword('sameTERM'))
# RegexExpression
REGEX = Suppress(CaselessKeyword('REGEX'))
RegexExpression = (REGEX + LP + Expression + COMMA + Expression +
Optional(COMMA + Expression) + RP).setParseAction(
refer_component(components.FunctionLibrary.ParsedREGEXInvocation))
if DEBUG:
RegexExpression.setName('RegexExpression')
BuiltInCall = (
(STR + LP + Expression + RP).setParseAction(
refer_component(components.FunctionLibrary.BuiltinFunctionCall,
[components.FunctionLibrary.STR])) |