math_spec.expression_parser
pyparsing-based expression parser for math expressions.
Parses strings like sum(p * cost, over=generator) == load into an AST
that can be evaluated against a namespace of linopy variables and xarray
parameters.
ArithmeticNode is the arithmetic-only union: every nested expression
position (operands, args, kwargs) accepts it and nothing else, and
ComparisonNode appears only at the top of a parsed expression.
ArithmeticNode = NumberNode | NameNode | NameListNode | VariableNode | ParameterNode | DimensionNode | LookupNode | EdgeNode | KeywordNode | UnaryOperatorNode | BinaryOperatorNode | FunctionCallNode
module-attribute
#
BranchNode = UnaryOperatorNode | BinaryOperatorNode | ComparisonNode | FunctionCallNode
module-attribute
#
ComparisonOperator = Literal['<=', '>=', '==']
module-attribute
#
ExpressionNode = ArithmeticNode | ComparisonNode
module-attribute
#
KwargNode = DimensionNode | LookupNode | EdgeNode
module-attribute
#
LeafNode = NumberNode | VariableNode | ParameterNode | KwargNode | UnresolvedNode
module-attribute
#
REAL = '\\d+\\.\\d*([eE][+-]?\\d+)?|\\d+[eE][+-]?\\d+'
module-attribute
#
UnresolvedNode = NameNode | NameListNode | KeywordNode
module-attribute
#
BinaryOperatorNode(op, left, right)
dataclass
#
ComparisonNode(op, left, right)
dataclass
#
DimensionNode(name)
dataclass
#
A resolved reference to a declared dimension.
Only legal in operator kwarg values (sum(x, over=generator)), never as
a value in arithmetic — a dimension is a coordinate space, not data.
name
instance-attribute
#
EdgeNode(policy)
dataclass
#
A resolved edge policy, legal only as an edge= value.
A number in the same position stays a :class:NumberNode: the value the
vacated positions contribute.
policy
instance-attribute
#
FunctionCallNode(name, args=list(), kwargs=dict())
dataclass
#
KeywordNode(value)
dataclass
#
A quoted closed keyword in a kwarg value — shift(..., edge='wrap').
Unresolved: which keywords the kwarg accepts is the operator's business.
value
instance-attribute
#
LookupNode(names, dimension, into)
dataclass
#
A resolved reference to one or more declared lookups, legal only in a kwarg value.
dimension is the one every lookup is over — what sum consumes and
at produces — and into the targets, one per name in the order
written; sum(x, by=[gen_bus, gen_tech]) is one grouping, not two.
NameListNode(names)
dataclass
#
NameNode(name)
dataclass
#
An unresolved token — a name whose kind is not yet known.
The parser cannot know whether p is a variable, a parameter or a
dimension; only the schema knows. resolution.py rewrites every one of
these into one of the typed nodes below, so a NameNode never reaches a
backend. If you find one there, resolution was skipped.
name
instance-attribute
#
ParameterNode(name)
dataclass
#
A resolved reference to a declared parameter.
name
instance-attribute
#
VariableNode(name)
dataclass
#
A resolved reference to a declared decision variable.
name
instance-attribute
#
children(node)
#
The sub-expressions of node — the structural half of any walk.
Every pass that recurses the whole tree and acts only at certain leaves
goes through here, so a node added later reaches all of them. A pass whose
answer differs per node type dispatches itself and keeps its
assert_never; this is for the ones that only need to get everywhere.
An operator's kwargs are children too — a dimension or coordinate is an ordinary node in a kwarg value, which is what lets a macro bind a formal.
Source code in src/math_spec/expression_parser.py
parse_expression(text)
#
Parse a math expression string into an AST.
| RAISES | DESCRIPTION |
|---|---|
SchemaError
|
If text is not an expression of the language. |
Source code in src/math_spec/expression_parser.py
shown(names)
#
Names as a kwarg value is written: bare when one, bracketed when several.