@@ -52,6 +52,11 @@ class UnsupportedSampleFilteringError(UnsupportedFilteringFeatureError):
52
52
feature = "Per-sample filter expressions"
53
53
54
54
55
+ class UnsupportedFunctionsError (UnsupportedFilteringFeatureError ):
56
+ issue = "190"
57
+ feature = "Function evaluation"
58
+
59
+
55
60
# The parser and evaluation model here are based on the eval_arith example
56
61
# in the pyparsing docs:
57
62
# https://github.com/pyparsing/pyparsing/blob/master/examples/eval_arith.py
@@ -92,13 +97,17 @@ def __init__(self, tokens):
92
97
raise UnsupportedFileReferenceError ()
93
98
94
99
100
+ class Function (EvaluationNode ):
101
+ def __init__ (self , tokens ):
102
+ raise UnsupportedFunctionsError ()
103
+
104
+
95
105
class Identifier (EvaluationNode ):
96
106
def __init__ (self , mapper , tokens ):
97
107
self .field_name = mapper (tokens [0 ])
98
108
if self .field_name .startswith ("call_" ):
99
109
raise UnsupportedSampleFilteringError ()
100
110
logger .debug (f"Mapped { tokens [0 ]} to { self .field_name } " )
101
- # TODO add errors for unsupported things like call_ fields etc.
102
111
103
112
def eval (self , data ):
104
113
return data [self .field_name ]
@@ -250,9 +259,16 @@ def make_bcftools_filter_parser(all_fields=None, map_vcf_identifiers=True):
250
259
functools .partial (Identifier , name_mapper )
251
260
)
252
261
indexed_identifier = indexed_identifier .set_parse_action (IndexedIdentifier )
262
+
263
+ expr = pp .Forward ()
264
+ expr_list = pp .delimited_list (pp .Group (expr ))
265
+ lpar , rpar = map (pp .Suppress , "()" )
266
+ function = pp .common .identifier () + lpar - pp .Group (expr_list ) + rpar
267
+ function = function .set_parse_action (Function )
268
+
253
269
comp_op = pp .oneOf ("< = == > >= <= !=" )
254
270
filter_expression = pp .infix_notation (
255
- constant | indexed_identifier | identifier | file_expr ,
271
+ function | constant | indexed_identifier | identifier | file_expr ,
256
272
[
257
273
("-" , 1 , pp .OpAssoc .RIGHT , UnaryMinus ),
258
274
(pp .one_of ("* /" ), 2 , pp .OpAssoc .LEFT , BinaryOperator ),
@@ -267,7 +283,8 @@ def make_bcftools_filter_parser(all_fields=None, map_vcf_identifiers=True):
267
283
(pp .one_of ("~ !~" ), 2 , pp .OpAssoc .LEFT , RegexOperator ),
268
284
],
269
285
)
270
- return filter_expression
286
+ expr <<= filter_expression
287
+ return expr
271
288
272
289
273
290
class FilterExpression :
0 commit comments