diff --git a/foamlib/_files/_parsing.py b/foamlib/_files/_parsing.py index 12db35e..8ee365e 100644 --- a/foamlib/_files/_parsing.py +++ b/foamlib/_files/_parsing.py @@ -1,6 +1,7 @@ from __future__ import annotations import array +import re import sys from typing import Tuple, Union, cast @@ -56,6 +57,21 @@ def _list_of(entry: ParserElement) -> ParserElement: ) +def _tensor(length: int, *, ignore: Regex) -> ParserElement: + spacing = rf"(?:(?:{ignore.re.pattern}|\s)+)" + float_ = r"([+-]?((\d+\.?\d*(e[+-]?\d+)?)|nan|inf(inity)?))" + + tensor = rf"\({spacing}?" + + tensor += spacing.join([float_] * length) + + tensor += rf"{spacing}?\)" + + return Regex(tensor, re.IGNORECASE).set_parse_action( + lambda tks: [[float(t) for t in re.sub(ignore.re, "", tks[0])[1:-1].split()]] + ) + + def _keyword_entry_of( keyword: ParserElement, data_entries: ParserElement, @@ -124,21 +140,19 @@ def _unpack_binary_field( _DIMENSIONS = ( Literal("[").suppress() + common.number[0, 7] + Literal("]").suppress() ).set_parse_action(lambda tks: DimensionSet(*tks)) -_TENSOR = common.ieee_float | ( - Literal("(").suppress() - + Group( - common.ieee_float[9] | common.ieee_float[6] | common.ieee_float[3], aslist=True - ) - + Literal(")").suppress() -) +_SCALAR = common.ieee_float +_VECTOR = _tensor(3, ignore=_COMMENT) +_SYMM_TENSOR = _tensor(6, ignore=_COMMENT) +_TENSOR = _tensor(9, ignore=_COMMENT) +_ANY_TENSOR = _SCALAR | _VECTOR | _SYMM_TENSOR | _TENSOR _IDENTIFIER = Combine( Word(_IDENTCHARS, _IDENTBODYCHARS, exclude_chars="()") + Opt(Literal("(") + Word(_IDENTBODYCHARS, exclude_chars="()") + Literal(")")) ) -_DIMENSIONED = (Opt(_IDENTIFIER) + _DIMENSIONS + _TENSOR).set_parse_action( +_DIMENSIONED = (Opt(_IDENTIFIER) + _DIMENSIONS + _ANY_TENSOR).set_parse_action( lambda tks: Dimensioned(*reversed(tks.as_list())) ) -_FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | ( +_FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _ANY_TENSOR) | ( Keyword("nonuniform", _IDENTBODYCHARS).suppress() + ( Literal("List").suppress() @@ -148,7 +162,7 @@ def _unpack_binary_field( Literal("scalar").suppress() + Literal(">").suppress() + ( - _list_of(common.ieee_float) + _list_of(_SCALAR) | ( ( ( @@ -172,11 +186,7 @@ def _unpack_binary_field( Literal("vector").suppress() + Literal(">").suppress() + ( - _list_of( - Literal("(").suppress() - + Group(common.ieee_float[3], aslist=True) - + Literal(")").suppress() - ) + _list_of(_VECTOR) | ( ( ( @@ -197,14 +207,10 @@ def _unpack_binary_field( ) ) | ( - Literal("vector").suppress() + Literal("symmTensor").suppress() + Literal(">").suppress() + ( - _list_of( - Literal("(").suppress() - + Group(common.ieee_float[6], aslist=True) - + Literal(")").suppress() - ) + _list_of(_SYMM_TENSOR) | ( ( ( @@ -228,11 +234,7 @@ def _unpack_binary_field( Literal("tensor").suppress() + Literal(">").suppress() + ( - _list_of( - Literal("(").suppress() - + Group(common.ieee_float[9], aslist=True) - + Literal(")").suppress() - ) + _list_of(_TENSOR) | ( ( (