%include { /*--------------------------------*- C++ -*----------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2019 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Description Lemon grammar for patch expressions. https://www.sqlite.org/src/doc/trunk/doc/lemon.html See detailed notes in the field expression parser. \*---------------------------------------------------------------------------*/ } // %include /* * include patchExprLemonParserMacros.m4 *include(`patchExprLemonParserMacros.m4')dnl !done in a comment since many editors have issues matching m4 quotes! */ %include { #include "patchExprDriver.H" #include "patchExprParser.H" #include "patchExprScanner.H" #include "unitConversion.H" #include "volFields.H" #include "error.H" #include "IOmanip.H" #include "exprOps.H" #include "exprDriverOps.H" #include "GeometricFieldOps.H" // Enable ParseTrace #undef NDEBUG compiler_pragmas() // Local Functions tmp_management() } // %include // ------------------------------------------------------------------------- // %namespace {} // Use extra argument for the return value %extra_context { Foam::expressions::patchExpr::parseDriver* driver } %parse_failure { driver->reportFatal("Parse failure, giving up..."); } %syntax_error { driver->reportFatal("Syntax error"); } %token_prefix TOK_ // Terminals %token_type {Foam::expressions::patchExpr::scanToken*} // Non-terminals %type ivalue { Foam::label } %type svalue { Foam::scalar } %type ident { Foam::word* } // Face fields declare_field(lfield, Foam::boolField, bool, newField, getSurfaceField) declare_field(sfield, Foam::scalarField, Foam::scalar, newField, getField) declare_field(vfield, Foam::vectorField, Foam::vector, newField, getField) declare_field(hfield, Foam::sphericalTensorField, Foam::sphericalTensor, newField, getField) declare_field(yfield, Foam::symmTensorField, Foam::symmTensor, newField, getField) declare_field(tfield, Foam::tensorField, Foam::tensor, newField, getField) // Point fields declare_field(plfield, Foam::boolField, bool, newPointField, getPointField) declare_field(psfield, Foam::scalarField, Foam::scalar, newPointField, getPointField) declare_field(pvfield, Foam::vectorField, Foam::vector, newPointField, getPointField) declare_field(phfield, Foam::sphericalTensorField, Foam::sphericalTensor, newPointField, getPointField) declare_field(pyfield, Foam::symmTensorField, Foam::symmTensor, newPointField, getPointField) declare_field(ptfield, Foam::tensorField, Foam::tensor, newPointField, getPointField) // For each rule action with code, destruction must be done by that code block // Lemon does not generate a destructor for that. // So do not use Lemon destructors for anything. operator_precedence() %start_symbol evaluate // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // /*---------------------------------------------------------------------------*\ * Productions (scalar) \*---------------------------------------------------------------------------*/ svalue (lhs) ::= NUMBER (a) . { lhs = (a)->svalue; } // From scanToken svalue (lhs) ::= ZERO . { lhs = Foam::Zero; } svalue (lhs) ::= PI LPAREN RPAREN . { lhs = Foam::constant::mathematical::pi; } svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); } svalue (lhs) ::= RAD_TO_DEG LPAREN RPAREN . { lhs = Foam::radToDeg(); } svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); } /* * * * * * * * * * * * * * * * * Face Fields * * * * * * * * * * * * * * * *\ dnl define([_logic_], [lfield])dnl define([_scalar_], [sfield])dnl define([_vector_], [vfield])dnl define([_sphTensor_], [hfield])dnl define([_symTensor_], [yfield])dnl define([_tensor_], [tfield])dnl dnl \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*---------------------------------------------------------------------------*\ * Productions (scalarField) dnl define([_target_], [sfield])dnl define([_value_type_], [Foam::scalar])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a); } rule_field_from_value(_target_, svalue) rule_get_field(_target_, SCALAR_ID) rule_get_field(_target_, SSCALAR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_scalar_operations() rules_scalar_functions() // Non-standard but manage via FieldOps::assign rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp()) rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp()) rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp()) // Non-standard but works directly for scalarField rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot) // Other functions _target_ (lhs) ::= RAND LPAREN RPAREN. { lhs = driver->field_rand().ptr(); } _target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN. { // Call with -ve seed to signal use of time index as seed lhs = driver->field_rand(std::round(-(seed)->svalue)).ptr(); } /*---------------------------------------------------------------------------*\ * Productions (vectorField) dnl define([_target_], [vfield])dnl define([_value_type_], [Foam::vector])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a); } rule_get_field(_target_, VECTOR_ID) rule_get_field(_target_, SVECTOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_vector_operations() rules_vector_functions() /*---------------------------------------------------------------------------*\ * Productions (sphericalTensorField) dnl define([_target_], [hfield])dnl define([_value_type_], [Foam::sphericalTensor])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a); } rule_get_field(_target_, SPH_TENSOR_ID) rule_get_field(_target_, SSPH_TENSOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_sphTensor_operations() rules_sphTensor_functions() /*---------------------------------------------------------------------------*\ * Productions (symmTensorField) dnl define([_target_], [yfield])dnl define([_value_type_], [Foam::symmTensor])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a); } rule_get_field(_target_, SYM_TENSOR_ID) rule_get_field(_target_, SSYM_TENSOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_symTensor_operations() rules_symTensor_functions() /*---------------------------------------------------------------------------*\ * Productions (tensorField) dnl define([_target_], [tfield])dnl define([_value_type_], [Foam::tensor])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a); } tfield (lhs) ::= UNIT_TENSOR . { lhs = _new_tfield(Foam::tensor::I); } rule_get_field(_target_, TENSOR_ID) rule_get_field(_target_, STENSOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_tensor_operations() rules_tensor_functions() // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // /*---------------------------------------------------------------------------*\ * Logic field productions (boolField) dnl define([_target_], [lfield])dnl define([_value_type_], [bool])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a); } _logic_ (lhs) ::= LTRUE . { lhs = _new_lfield(_logic_true_); } _logic_ (lhs) ::= LFALSE . { lhs = _new_lfield(_logic_false_); } rule_cast_logical(_target_, _target_) rule_cast_logical(_target_, _scalar_, Foam::scalar) dnl/* Handling of named logic fields not really tested (disable in scanner) */ rule_get_field(_target_, SBOOL_ID) rules_logical_operations(_logic_, _value_type_) /*---------------------------------------------------------------------------*\ * General Surface-related productions \*---------------------------------------------------------------------------*/ rules_driver_surface_functions() /* * * * * * * * * * * * * * * * Point Fields * * * * * * * * * * * * * * * *\ dnl define([_logic_], [plfield])dnl define([_scalar_], [psfield])dnl define([_vector_], [pvfield])dnl define([_sphTensor_], [phfield])dnl define([_symTensor_], [pyfield])dnl define([_tensor_], [ptfield])dnl dnl \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*---------------------------------------------------------------------------*\ * Productions (point scalarField) dnl define([_target_], [psfield])dnl define([_value_type_], [Foam::scalar])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ } rule_field_from_value(_target_, svalue, POINT_EXPR) rule_get_field(_target_, PSCALAR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_scalar_operations() rules_scalar_functions() // Non-standard but manage via FieldOps::assign rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp()) rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp()) rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp()) // Non-standard but works directly for scalarField rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot) /*---------------------------------------------------------------------------*\ * Productions (point vectorField) dnl define([_target_], [pvfield])dnl define([_value_type_], [Foam::vector])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ } rule_get_field(_target_, PVECTOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_vector_operations() rules_vector_functions() /*---------------------------------------------------------------------------*\ * Productions (point sphericalTensorField) dnl define([_target_], [phfield])dnl define([_value_type_], [Foam::sphericalTensor])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ } rule_get_field(_target_, PSPH_TENSOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_sphTensor_operations() rules_sphTensor_functions() /*---------------------------------------------------------------------------*\ * Productions (point symmTensorField) dnl define([_target_], [pyfield])dnl define([_value_type_], [Foam::symmTensor])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ } rule_get_field(_target_, PSYM_TENSOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_symTensor_operations() rules_symTensor_functions() /*---------------------------------------------------------------------------*\ * Productions (point tensorField) dnl define([_target_], [ptfield])dnl define([_value_type_], [Foam::tensor])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ } rule_get_field(_target_, PTENSOR_ID) rules_standard(_target_, _value_type_, _logic_) rules_inplace_gUnary(_target_) rules_tensor_operations() rules_tensor_functions() /*---------------------------------------------------------------------------*\ * Logic field productions (point boolField) dnl define([_target_], [plfield])dnl define([_value_type_], [bool])dnl dnl \*---------------------------------------------------------------------------*/ evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ } _logic_ (lhs) ::= POINT_EXPR LPAREN LTRUE RPAREN . { lhs = _new_plfield(_logic_true_); } _logic_ (lhs) ::= POINT_EXPR LPAREN LFALSE RPAREN . { lhs = _new_plfield(_logic_false_); } rule_cast_logical(_target_, _target_) rule_cast_logical(_target_, _scalar_, Foam::scalar) dnl/* Handling of named logic fields not really tested (disable in scanner) */ rule_get_field(_target_, PBOOL_ID) rules_logical_operations(_logic_, _value_type_) /*---------------------------------------------------------------------------*\ * General Point-related productions \*---------------------------------------------------------------------------*/ rules_driver_point_functions() // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // /*---------------------------------------------------------------------------*\ * Face field composition \*---------------------------------------------------------------------------*/ rule_mag_logical(sfield, lfield) rules_mag_functions(sfield, sfield) rules_mag_functions(sfield, vfield) rules_mag_functions(sfield, tfield) rules_mag_functions(sfield, yfield) rules_mag_functions(sfield, hfield) rule_vector_zip(vfield, sfield, VECTOR) rule_tensor_zip(tfield, sfield, TENSOR) rule_symTensor_zip(yfield, sfield, SYM_TENSOR) rule_sphTensor_zip(hfield, sfield, SPH_TENSOR) rule_vector_components(sfield, vfield) rule_tensor_components(sfield, tfield) rule_symTensor_components(sfield, yfield) rule_sphTensor_components(sfield, hfield) rule_tensor_transpose(tfield) rule_symTensor_transpose(yfield) rule_sphTensor_transpose(hfield) rule_tensor_unzipDiag(vfield, yfield) rule_tensor_unzipAll(vfield, tfield) rule_pointToFace(sfield, psfield) rule_pointToFace(vfield, pvfield) rule_pointToFace(tfield, ptfield) rule_pointToFace(yfield, pyfield) rule_pointToFace(hfield, phfield) /*---------------------------------------------------------------------------*\ * Point field composition \*---------------------------------------------------------------------------*/ rule_mag_logical(psfield, plfield) rules_mag_functions(psfield, psfield) rules_mag_functions(psfield, pvfield) rules_mag_functions(psfield, ptfield) rules_mag_functions(psfield, pyfield) rules_mag_functions(psfield, phfield) rule_vector_zip(pvfield, psfield, VECTOR) rule_tensor_zip(ptfield, psfield, TENSOR) rule_symTensor_zip(pyfield, psfield, SYM_TENSOR) rule_sphTensor_zip(phfield, psfield, SPH_TENSOR) rule_vector_components(psfield, pvfield) rule_tensor_components(psfield, ptfield) rule_symTensor_components(psfield, pyfield) rule_sphTensor_components(psfield, phfield) rule_tensor_transpose(ptfield) rule_symTensor_transpose(pyfield) rule_sphTensor_transpose(phfield) rule_tensor_unzipDiag(pvfield, pyfield) rule_tensor_unzipAll(pvfield, ptfield) rule_faceToPoint(psfield, sfield) rule_faceToPoint(pvfield, vfield) rule_faceToPoint(ptfield, tfield) rule_faceToPoint(pyfield, yfield) rule_faceToPoint(phfield, hfield) // ************************************************************************* // /* * include m4/lemon/parser-methods.m4 include([m4/lemon/parser-methods.m4])dnl dnl Can revert to standard m4 quoting dnl ... Or not changequote([`],['])dnl Revert to standard m4 quoting */ %code { // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // parser_code_static_methods(Foam::expressions::patchExpr::parser) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::expressions::patchExpr::parser::stop() { if (lemon_) { ParseFree(lemon_, ::operator delete); #ifndef NDEBUG ParseTrace(nullptr, nullptr); #endif lemon_ = nullptr; } } void Foam::expressions::patchExpr::parser::start(parseDriver& driver_) { this->stop(); lemon_ = ParseAlloc(::operator new, &driver_); if (debug || driver_.debugParser()) { #ifndef NDEBUG ParseTrace(stderr, const_cast(prompt_)); #endif } } void Foam::expressions::patchExpr::parser::parse ( int tokenId, scanToken* tokenVal ) { Parse(lemon_, tokenId, tokenVal); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End of %code // ************************************************************************* //