bidsschematools.expressions

Parsing utilities for BIDS Schema expression language

Classes

class bidsschematools.expressions.ASTNode

Bases: object

AST superclass

Defines basic repr. Subclasses should define __str__ with enough parentheses to make associations unambiguous.

class bidsschematools.expressions.Array(tokens)

Bases: ASTNode

Array literal

class bidsschematools.expressions.BinOp(tokens)

Bases: ASTNode

Binary operator

classmethod maybe(tokens)

Construct class if not degenerate

  • Right-associative: outer <<= inner + (op + outer)[...]

  • Left-associative: outer = inner + (op + inner)[...]

In the right-associative case, we get [inner, op, BinOp(outer)], so we loop once and are done.

In the left-associative case, we get [inner, op, inner, op, ...], convert to [BinOp(inner, op, inner), op, inner, ...]

class bidsschematools.expressions.Element(name, index)

Bases: ASTNode

Array element lookup

class bidsschematools.expressions.Function(name, args)

Bases: ASTNode

Function call

class bidsschematools.expressions.Object(tokens)

Bases: ASTNode

Object literal, unused outside tests, so degenerate

class bidsschematools.expressions.Property(name, field)

Bases: ASTNode

Object property lookup

class bidsschematools.expressions.RightOp(tokens)

Bases: ASTNode

Right-associative unary operator

classmethod maybe(tokens)

Construct class only if not degenerate

Functions

bidsschematools.expressions.atomize(tokens)
bidsschematools.expressions.parse(expression_string: str) ASTNode

Convert a BIDS schema expression into an abstract syntax tree

EBNF-ish grammar:

# In order of binding (loosest to tightest)
orOp  :: '||'
andOp :: '&&'
notOp :: '!'
cmpOp :: '==' | '!=' | '<' | '<=' | '>' | '>=' | 'in'
addOp :: '+' | '-'
mulOp :: '*' | '/' | '%'
expOp :: '**'

item    :: '(' test ')' | '[' [testList] '] | '{' '}' | NAME | NUMBER | STRING
trailer :: '(' [testList] ') | '[' test ']' | '.' NAME
atom    :: item trailer*

factor :: atom [ expOp factor ]*
term   :: factor [ mulOp factor ]*
expr   :: term [ addOp term ]*

comparison :: expr [ compOp expr ]*
notTest    :: not notTest | comparison
andTest    :: notTest [ '&&' andTest ]*
test       :: andTest [ '||' test ]*

testList   :: test [ ',' test ]*

expression :: ^ test $