diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 20497d102d..5ef761d151 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -258,6 +258,13 @@ $(expr)/base/fvExprDriverFields.C $(expr)/base/fvExprDriverIO.C $(expr)/base/fvExprDriverNew.C +patchExpr = $(expr)/patch +$(patchExpr)/patchExpr.C +$(patchExpr)/patchExprDriver.C +$(patchExpr)/patchExprDriverFields.C +$(patchExpr)/patchExprLemonParser.lyy-m4 +$(patchExpr)/patchExprScanner.cc + fvMatrices/fvMatrices.C fvMatrices/fvScalarMatrix/fvScalarMatrix.C diff --git a/src/finiteVolume/expressions/patch/createCode b/src/finiteVolume/expressions/patch/createCode new file mode 100755 index 0000000000..3aab7655b8 --- /dev/null +++ b/src/finiteVolume/expressions/patch/createCode @@ -0,0 +1,13 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +# Manually create ragel scanner and lemon parser header + +prefix=patchExpr + +"${WM_PROJECT_DIR:?}/wmake/scripts/makeParser" \ + -prefix="$prefix" \ + -scanner=Scanner.rl \ + -parser=LemonParser.lyy-m4 \ + "$@" + +#------------------------------------------------------------------------------ diff --git a/src/finiteVolume/expressions/patch/patchExpr.C b/src/finiteVolume/expressions/patch/patchExpr.C new file mode 100644 index 0000000000..e5a4c54ccc --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExpr.C @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "patchExprFwd.H" +#include "defineDebugSwitch.H" + +// * * * * * * * * * * * * * * * * Globals * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace expressions +{ + +defineDebugSwitchWithName(patchExpr, "patchExpr", 0); +registerDebugSwitchWithName(patchExpr, patchExpr, "patchExpr"); + +} // End namespace expressions +} // End namespace Foam + + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprDriver.C b/src/finiteVolume/expressions/patch/patchExprDriver.C new file mode 100644 index 0000000000..5f22efe3e0 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprDriver.C @@ -0,0 +1,188 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "patchExprDriver.H" +#include "patchExprScanner.H" +#include "error.H" +#include "fvPatch.H" +#include "fvMesh.H" +#include "className.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace expressions +{ +namespace patchExpr +{ + +defineTypeNameAndDebug(parseDriver, 0); + +addNamedToRunTimeSelectionTable +( + fvExprDriver, + parseDriver, + dictionary, + patch +); + +addNamedToRunTimeSelectionTable +( + fvExprDriver, + parseDriver, + idName, + patch +); + +} // End namespace patchExpr +} // End namespace expressions +} // End namespace Foam + + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + static label getPatchID(const fvMesh& mesh, const word& patchName) + { + const auto& bMesh = mesh.boundaryMesh(); + + const label patchId = bMesh.findPatchID(patchName); + + if (patchId < 0) + { + FatalErrorInFunction + << "No patch " << patchName << " found in " + << flatOutput(bMesh.names()) << nl + << exit(FatalError); + } + return patchId; + } + + + static inline const fvPatch& findFvPatch + ( + const fvMesh& mesh, + const word& patchName + ) + { + return mesh.boundary()[getPatchID(mesh, patchName)]; + } + +} // End namespace Foam + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +const Foam::fvPatch& Foam::expressions::patchExpr::parseDriver::getFvPatch +( + const fvMesh& fvm, + const dictionary& dict +) +{ + return findFvPatch + ( + regionMesh(dict, fvm, true), + dict.get("patch") + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::expressions::patchExpr::parseDriver::parseDriver(const fvPatch& p) +: + parsing::genericRagelLemonDriver(), + expressions::fvExprDriver(), + patch_(p) +{} + + +Foam::expressions::patchExpr::parseDriver::parseDriver +( + const fvPatch& p, + const dictionary& dict +) +: + parsing::genericRagelLemonDriver(), + expressions::fvExprDriver(dict), + patch_(p) +{} + + +Foam::expressions::patchExpr::parseDriver::parseDriver +( + const fvPatch& p, + const parseDriver& driver_ +) +: + parsing::genericRagelLemonDriver(), + expressions::fvExprDriver(driver_), + patch_(p) +{} + + +Foam::expressions::patchExpr::parseDriver::parseDriver +( + const word& patchName, + const fvMesh& mesh +) +: + parseDriver(findFvPatch(mesh, patchName)) +{} + + +Foam::expressions::patchExpr::parseDriver::parseDriver +( + const dictionary& dict, + const fvMesh& mesh +) +: + parseDriver(getFvPatch(mesh, dict), dict) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +unsigned Foam::expressions::patchExpr::parseDriver::parse +( + const std::string& expr, + size_t pos, + size_t len +) +{ + scanner scan(this->debugScanner()); + + scan.process(expr, pos, len, *this); + + return 0; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprDriver.H b/src/finiteVolume/expressions/patch/patchExprDriver.H new file mode 100644 index 0000000000..294c902cf4 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprDriver.H @@ -0,0 +1,305 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::expressions::patchExpr::parseDriver + +Description + Driver for patch expressions + + In addition to the standard mathematical functions, operations and + logical and relational operations, the volume expression support the + following driver-specific functions: + + Functions + \table + Function | Description | Number of arguments | + vol | The cell volumes | 0 | + pos | The face centres | 0 | + pts | The face points | 0 | + area | The face area magnitudes | 0 | + weightAverage| Area weighted average | 1 | + weightSum | Area weighted sum | 1 | + face | The face areaNormal vectors | 0 | + point | A point-field point value | 1 | + faceToPoint | Interpolate face values onto points | 1 | + pointToFace | Interpolate point values onto faces | 1 | + rand | Random field | 0/1 | + \endtable + +SourceFiles + patchExprDriver.C + patchExprDriverFields.C + patchExprDriverTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef expressions_patchExprDriver_H +#define expressions_patchExprDriver_H + +#include "patchExprFwd.H" +#include "fvExprDriver.H" +#include "Enum.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "pointFields.H" +#include "genericRagelLemonDriver.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace expressions +{ +namespace patchExpr +{ + +/*---------------------------------------------------------------------------*\ + Class parseDriver Declaration +\*---------------------------------------------------------------------------*/ + +class parseDriver +: + public parsing::genericRagelLemonDriver, + public expressions::fvExprDriver +{ + // Private Member Functions + + static const fvPatch& getFvPatch + ( + const fvMesh& fvm, + const dictionary& dict + ); + + +protected: + + // Protected Data + + //- The referenced patch + const fvPatch& patch_; + + + // Protected Member Functions + + // No copy copy construct + parseDriver(const parseDriver&) = delete; + + // No copy assignment + void operator=(const parseDriver&) = delete; + + +public: + + ClassName("patchExpr::driver"); + + // Constructors + + //- Construct for specified patch + explicit parseDriver(const fvPatch& p); + + //- Construct for specified patch with given dictionary + parseDriver(const fvPatch& p, const dictionary& dict); + + //- Construct for specified patch with copy of driver context + parseDriver(const fvPatch& p, const parseDriver& driver_); + + //- Construct with patchName for the given mesh + parseDriver(const word& patchName, const fvMesh& mesh); + + //- Construct with "patch" (mandatory) and "region" (optional) + //- specified in dictionary + parseDriver(const dictionary& dict, const fvMesh& mesh); + + //- Clone + virtual autoPtr clone() const + { + return autoPtr + ( + new parseDriver(this->patch_, *this) + ); + } + + + //- Destructor + virtual ~parseDriver() = default; + + + // Public Member Functions + + //- The mesh we are attached to + virtual const fvMesh& mesh() const + { + return patch_.boundaryMesh().mesh(); + } + + //- The underlying field size for the expression + virtual label size() const + { + return patch_.patch().size(); + } + + //- The underlying point field size for the expression + virtual label pointSize() const + { + return patch_.patch().nPoints(); + } + + //- Field size associated with different geometric field types + inline label size(const FieldAssociation geoType) const; + + + // Evaluation + + //- Perform parsing on (sub) string + using genericRagelLemonDriver::content; + + //- Execute the parser + virtual unsigned parse + ( + const std::string& expr, + size_t pos = 0, + size_t len = std::string::npos + ); + + + // Field Information + + // Fields + + //- Set result + template + void setResult(Field* ptr, bool pointVal = false) + { + result().setResult(ptr, pointVal); + } + + + //- Retrieve variable as field if possible. + // Test tmp for validity to determine success of the operation. + template + tmp> getVariableIfAvailable(const word& fldName) const; + + //- Retrieve field (vol field) + template + tmp> + getVolField(const word& fldName); + + //- Retrieve field (surface field) + template + tmp> + getSurfaceField(const word& fldName); + + //- Retrieve field (point field) + template + tmp> + getPointField(const word& fldName); + + //- Return named field + template + tmp> getField(const word& fldName); + + + // Field "shape" conversions + + //- Interpolate face to point + template + tmp> faceToPoint(const Field& field) const; + + //- Interpolate point to face values + template + tmp> pointToFace(const Field& field) const; + + + // Custom Field Functions + + //- The area-weighted average of a field + template + Type areaAverage(const Field& fld) const + { + return weightedAverage(patch_.magSf(), fld); + } + + //- The area-weighted sum of a field + template + Type areaSum(const Field& fld) const + { + return weightedSum(patch_.magSf(), fld); + } + + //- The face area magnitudes [magSf] - (swak = area) + tmp field_faceArea() const; + + //- The face centres - (swak = pos) + tmp field_faceCentre() const; + + //- The face areas with their vector direction [Sf] - (swak = face) + tmp field_areaNormal() const; + + //- The patch point locations - (swak = pts) + tmp field_pointField() const; + + //- A uniform random field + tmp field_rand(label seed=0, bool gaussian=false) const; + + //- A Gaussian random field + tmp field_randGaussian(label seed=0) const + { + return field_rand(seed, true); + } +}; + + +// Template specializations + +//- Retrieve field (surface field: bool) +template<> +tmp> parseDriver::getSurfaceField(const word& fldName); + +//- Retrieve field (point field: bool) +template<> +tmp> parseDriver::getPointField(const word& fldName); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace patchExpr +} // End namespace expressions +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "patchExprDriverI.H" + +#ifdef NoRepository + #include "patchExprDriverTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprDriverFields.C b/src/finiteVolume/expressions/patch/patchExprDriverFields.C new file mode 100644 index 0000000000..690a4c2376 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprDriverFields.C @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "patchExprDriver.H" +#include "fvPatch.H" +#include "error.H" + +// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * // + +template<> +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getSurfaceField +( + const word& name +) +{ + return getVariable(name, this->size()); +} + + +template<> +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getPointField +( + const word& name +) +{ + return getVariable(name, this->pointSize()); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::tmp +Foam::expressions::patchExpr::parseDriver::field_faceArea() const +{ + return patch_.magSf(); +} + + +Foam::tmp +Foam::expressions::patchExpr::parseDriver::field_faceCentre() const +{ + return patch_.Cf(); +} + + +Foam::tmp +Foam::expressions::patchExpr::parseDriver::field_areaNormal() const +{ + return patch_.Sf(); +} + + +Foam::tmp +Foam::expressions::patchExpr::parseDriver::field_pointField() const +{ + return patch_.patch().localPoints(); +} + + +Foam::tmp +Foam::expressions::patchExpr::parseDriver::field_rand +( + label seed, + bool gaussian +) const +{ + auto tresult = tmp::New(this->size()); + fill_random(tresult.ref(), seed, gaussian); + + return tresult; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprDriverI.H b/src/finiteVolume/expressions/patch/patchExprDriverI.H new file mode 100644 index 0000000000..b4ae95c4ea --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprDriverI.H @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline Foam::label Foam::expressions::patchExpr::parseDriver::size +( + const FieldAssociation geoType +) const +{ + switch (geoType) + { + case FieldAssociation::POINT_DATA : + return patch_.patch().nPoints(); + break; + case FieldAssociation::SURFACE_DATA : + return patch_.patch().size(); + break; + default: + break; + } + return 0; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C b/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C new file mode 100644 index 0000000000..7fafffbc50 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "primitivePatchInterpolation.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getVariableIfAvailable +( + const word& name +) const +{ + bool isPointVal = false; + bool isUniformVal = false; + + tmp> tfield; + + if (hasVariable(name) && variable(name).isType()) + { + const expressions::exprResult& var = variable(name); + + isPointVal = var.isPointValue(); + isUniformVal = var.isUniform(); + + tfield = var.cref().clone(); + } + else if (isGlobalVariable(name, false)) + { + const expressions::exprResult& var = lookupGlobal(name); + + isUniformVal = var.isUniform(); + + tfield = var.cref().clone(); + } + + if (tfield.valid()) + { + const label fldLen = tfield().size(); + const label len = (isPointVal ? this->pointSize() : this->size()); + + if (returnReduce((fldLen == len), andOp())) + { + return tfield; + } + + if (!isUniformVal) + { + WarningInFunction + << "Variable " << name + << " does not fit the size and is not a uniform value." << nl + << "Using average value" << endl; + } + + return tmp>::New(this->size(), gAverage(tfield)); + } + + return tfield; +} + + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getVolField(const word& name) +{ + return getField(name); +} + + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getSurfaceField(const word& name) +{ + return getField(name); +} + + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getPointField(const word& name) +{ + return getField(name); +} + + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::getField(const word& name) +{ + tmp> tfield = getVariableIfAvailable(name); + + if (tfield.valid()) + { + return tfield; + } + + + typedef GeometricField vfieldType; + typedef GeometricField sfieldType; + typedef GeometricField pfieldType; + + const objectRegistry& obr = this->mesh().thisDb(); + + const vfieldType* vfield = obr.findObject(name); + const sfieldType* sfield = obr.findObject(name); + const pfieldType* pfield = obr.findObject(name); + + // Local, temporary storage + tmp t_vfield; + tmp t_sfield; + tmp t_pfield; + + if (searchFiles() && !vfield && !sfield && !pfield) + { + const word fldType = this->getTypeOfField(name); + + if (fldType == vfieldType::typeName) + { + t_vfield = this->readAndRegister(name, mesh()); + vfield = t_vfield.get(); + } + else if (fldType == sfieldType::typeName) + { + t_sfield = this->readAndRegister(name, mesh()); + sfield = t_sfield.get(); + } + else if (fldType == pfieldType::typeName) + { + t_pfield = this->readAndRegister + ( + name, + pointMesh::New(mesh()) + ); + pfield = t_pfield.get(); + } + } + + const label patchIndex = patch_.index(); + + if (vfield) + { + return tmp>::New + ( + vfield->boundaryField()[patchIndex] + ); + } + + if (sfield) + { + return tmp>::New + ( + sfield->boundaryField()[patchIndex] + ); + } + + if (pfield) + { + return pfield->boundaryField()[patchIndex].patchInternalField(); + } + + + FatalErrorInFunction + << "No field '" << name << "' of type " + << pTraits::typeName << nl << nl + << vfieldType::typeName << " Fields: " + << flatOutput(obr.sortedNames()) << nl + << sfieldType::typeName << " Fields: " + << flatOutput(obr.sortedNames()) << nl + << pfieldType::typeName << " Fields: " + << flatOutput(obr.sortedNames()) << nl + << exit(FatalError); + + return tmp>::New(); +} + + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::faceToPoint +( + const Field& field +) const +{ + primitivePatchInterpolation interp(patch_.patch()); + + return interp.pointToFaceInterpolate(field); +} + + +template +Foam::tmp> +Foam::expressions::patchExpr::parseDriver::pointToFace +( + const Field& field +) const +{ + primitivePatchInterpolation interp(patch_.patch()); + + return interp.faceToPointInterpolate(field); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprFwd.H b/src/finiteVolume/expressions/patch/patchExprFwd.H new file mode 100644 index 0000000000..5682b896fb --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprFwd.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Namespace + Foam::expressions::patchExpr + +Description + Namespace for patch expressions parsing and evaluation + +\*---------------------------------------------------------------------------*/ + +#ifndef expressions_patchExprFwd_H +#define expressions_patchExprFwd_H + +namespace Foam +{ +namespace expressions +{ +namespace patchExpr +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Forward Declarations +class parser; +class scanner; +class parseDriver; +union scanToken; + +//- Static debugging option +extern int debug; + + +//- The field association for patch expressions (mutually exclusive) +enum FieldAssociation : unsigned char +{ + NO_DATA = 0, //!< No data + POINT_DATA = 1, //!< Point data + SURFACE_DATA = 2 //!< Surface data +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace patchExpr + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//- Typedef for patchExpr parseDriver +typedef patchExpr::parseDriver patchExprDriver; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace expressions +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParser.h b/src/finiteVolume/expressions/patch/patchExprLemonParser.h new file mode 100644 index 0000000000..8a84326c4d --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprLemonParser.h @@ -0,0 +1,110 @@ +#define TOK_QUESTION 1 +#define TOK_COLON 2 +#define TOK_LOR 3 +#define TOK_LAND 4 +#define TOK_BIT_XOR 5 +#define TOK_BIT_AND 6 +#define TOK_EQUAL 7 +#define TOK_NOT_EQUAL 8 +#define TOK_LESS_EQ 9 +#define TOK_GREATER_EQ 10 +#define TOK_LESS 11 +#define TOK_GREATER 12 +#define TOK_PLUS 13 +#define TOK_MINUS 14 +#define TOK_TIMES 15 +#define TOK_DIVIDE 16 +#define TOK_PERCENT 17 +#define TOK_NEGATE 18 +#define TOK_NOT 19 +#define TOK_DOT 20 +#define TOK_NUMBER 21 +#define TOK_ZERO 22 +#define TOK_PI 23 +#define TOK_LPAREN 24 +#define TOK_RPAREN 25 +#define TOK_DEG_TO_RAD 26 +#define TOK_RAD_TO_DEG 27 +#define TOK_TIME 28 +#define TOK_SCALAR_ID 29 +#define TOK_SSCALAR_ID 30 +#define TOK_MIN 31 +#define TOK_COMMA 32 +#define TOK_MAX 33 +#define TOK_SUM 34 +#define TOK_AVERAGE 35 +#define TOK_EXP 36 +#define TOK_LOG 37 +#define TOK_LOG10 38 +#define TOK_SQR 39 +#define TOK_SQRT 40 +#define TOK_CBRT 41 +#define TOK_SIN 42 +#define TOK_COS 43 +#define TOK_TAN 44 +#define TOK_ASIN 45 +#define TOK_ACOS 46 +#define TOK_ATAN 47 +#define TOK_SINH 48 +#define TOK_COSH 49 +#define TOK_TANH 50 +#define TOK_POW 51 +#define TOK_ATAN2 52 +#define TOK_POS 53 +#define TOK_NEG 54 +#define TOK_POS0 55 +#define TOK_NEG0 56 +#define TOK_SIGN 57 +#define TOK_FLOOR 58 +#define TOK_CEIL 59 +#define TOK_ROUND 60 +#define TOK_HYPOT 61 +#define TOK_RAND 62 +#define TOK_VECTOR_ID 63 +#define TOK_SVECTOR_ID 64 +#define TOK_SPH_TENSOR_ID 65 +#define TOK_SSPH_TENSOR_ID 66 +#define TOK_SYM_TENSOR_ID 67 +#define TOK_SSYM_TENSOR_ID 68 +#define TOK_UNIT_TENSOR 69 +#define TOK_TENSOR_ID 70 +#define TOK_STENSOR_ID 71 +#define TOK_LTRUE 72 +#define TOK_LFALSE 73 +#define TOK_BOOL 74 +#define TOK_SBOOL_ID 75 +#define TOK_FACE_AREA 76 +#define TOK_FACE_EXPR 77 +#define TOK_WEIGHT_AVERAGE 78 +#define TOK_WEIGHT_SUM 79 +#define TOK_POINT_EXPR 80 +#define TOK_PSCALAR_ID 81 +#define TOK_PVECTOR_ID 82 +#define TOK_PSPH_TENSOR_ID 83 +#define TOK_PSYM_TENSOR_ID 84 +#define TOK_PTENSOR_ID 85 +#define TOK_PBOOL_ID 86 +#define TOK_POINTS 87 +#define TOK_MAG 88 +#define TOK_MAGSQR 89 +#define TOK_VECTOR 90 +#define TOK_TENSOR 91 +#define TOK_SYM_TENSOR 92 +#define TOK_SPH_TENSOR 93 +#define TOK_CMPT_X 94 +#define TOK_CMPT_Y 95 +#define TOK_CMPT_Z 96 +#define TOK_CMPT_XX 97 +#define TOK_CMPT_XY 98 +#define TOK_CMPT_XZ 99 +#define TOK_CMPT_YX 100 +#define TOK_CMPT_YY 101 +#define TOK_CMPT_YZ 102 +#define TOK_CMPT_ZX 103 +#define TOK_CMPT_ZY 104 +#define TOK_CMPT_ZZ 105 +#define TOK_CMPT_II 106 +#define TOK_TRANSPOSE 107 +#define TOK_DIAG 108 +#define TOK_POINT_TO_FACE 109 +#define TOK_FACE_TO_POINT 110 diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 b/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 new file mode 100644 index 0000000000..477cc7ea46 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 @@ -0,0 +1,565 @@ +%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 "error.H" +#include "volFields.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) + + +// ************************************************************************* // + +dnl/* Standard m4 quoting +changequote([`],['])dnl +dnl*/ + +%code +{ + +// * * * * * * * * * * * * * * * 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); +} + + +Foam::word Foam::expressions::patchExpr::parser::nameOfToken +( + int tokenId +) const +{ + #ifndef NDEBUG + if + ( + tokenId > 0 + && unsigned(tokenId) < (sizeof(yyTokenName) / sizeof(char*)) + ) + { + return yyTokenName[tokenId]; + } + return ""; + #else + return word(); + #endif +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End of %code + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4 b/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4 new file mode 100644 index 0000000000..aa183dfeb6 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4 @@ -0,0 +1,109 @@ +divert(-1)dnl +#-----------------------------------*- m4 -*----------------------------------- +# ========= | +# \\ / 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, licensed under GNU General Public License +# . +# +# Description +# Driver-specific m4/lemon macros for patch expressions. +# +#------------------------------------------------------------------------------ + +include(`m4/lemon/base-setup.m4')dnl +include([m4/lemon/operator-precedence.m4])dnl +dnl +include([m4/lemon/rules-standard.m4])dnl +include([m4/lemon/rules-operations.m4])dnl +include([m4/lemon/rules-functions.m4])dnl +include([m4/lemon/rules-components.m4])dnl +include([m4/lemon/rules-fields-components.m4])dnl +include([m4/lemon/rules-scalar-logic.m4])dnl +dnl +divert(-1)dnl + +use_bool_logic()dnl # Use boolField directly + +#------------------------------------------------------------------------------- +# Driver rules +#------------------------------------------------------------------------------- + +define([rules_driver_surface_functions], +[dnl +rule_driver_nullary(_scalar_, FACE_AREA, field_faceArea)dnl +rule_driver_nullary(_vector_, POS, field_faceCentre)dnl FACE_CENTRE +rule_driver_nullary(_vector_, FACE_EXPR, field_areaNormal)dnl +dnl +rule_driver_inplace_unary(_scalar_, WEIGHT_AVERAGE, areaAverage)dnl +rule_driver_inplace_unary(_vector_, WEIGHT_AVERAGE, areaAverage)dnl +rule_driver_inplace_unary(_sphTensor_, WEIGHT_AVERAGE, areaAverage)dnl +rule_driver_inplace_unary(_symTensor_, WEIGHT_AVERAGE, areaAverage)dnl +rule_driver_inplace_unary(_tensor_, WEIGHT_AVERAGE, areaAverage)dnl +dnl +rule_driver_inplace_unary(_scalar_, WEIGHT_SUM, areaSum)dnl +rule_driver_inplace_unary(_vector_, WEIGHT_SUM, areaSum)dnl +rule_driver_inplace_unary(_sphTensor_, WEIGHT_SUM, areaSum)dnl +rule_driver_inplace_unary(_symTensor_, WEIGHT_SUM, areaSum)dnl +rule_driver_inplace_unary(_tensor_, WEIGHT_SUM, areaSum)dnl +dnl +]) + +define([rules_driver_point_functions], +[dnl +rule_driver_nullary(_vector_, POINTS, field_pointField)dnl +dnl +dnl NB use non-driver versions for points - ie, unweighted +dnl +rule_inplace_unary(_scalar_, WEIGHT_AVERAGE, Foam::gAverage)dnl +rule_inplace_unary(_vector_, WEIGHT_AVERAGE, Foam::gAverage)dnl +rule_inplace_unary(_sphTensor_, WEIGHT_AVERAGE, Foam::gAverage)dnl +rule_inplace_unary(_symTensor_, WEIGHT_AVERAGE, Foam::gAverage)dnl +rule_inplace_unary(_tensor_, WEIGHT_AVERAGE, Foam::gAverage)dnl +dnl +rule_inplace_unary(_scalar_, WEIGHT_SUM, Foam::gSum)dnl +rule_inplace_unary(_vector_, WEIGHT_SUM, Foam::gSum)dnl +rule_inplace_unary(_sphTensor_, WEIGHT_SUM, Foam::gSum)dnl +rule_inplace_unary(_symTensor_, WEIGHT_SUM, Foam::gSum)dnl +rule_inplace_unary(_tensor_, WEIGHT_SUM, Foam::gSum)dnl +dnl +]) + + +#------------------------------------------------------------------------------ +# rule_faceToPoint(out, in) +# rule_pointToFace(out, in) +# +# Description +# Production rules for driver faceToPoint, pointToFace, +# methods +#------------------------------------------------------------------------------ + +define([rule_faceToPoint], +[rule_driver_unary($1, $2, FACE_TO_POINT, faceToPoint)]) + +define([rule_pointToFace], +[rule_driver_unary($1, $2, POINT_TO_FACE, pointToFace)]) + + +#------------------------------------------------------------------------------ +# Standard rules for fields: declaration, new/get, driver functions etc. + +include([m4/lemon/rules-fields.m4])dnl +divert(-1)dnl + + +#------------------------------------------------------------------------------ + +# Additional safety measures + +undefine([substr])dnl # Avoid collision with C/C++ naming + +#------------------------------------------------------------------------------ +divert(0)dnl diff --git a/src/finiteVolume/expressions/patch/patchExprParser.H b/src/finiteVolume/expressions/patch/patchExprParser.H new file mode 100644 index 0000000000..a59fcdcca6 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprParser.H @@ -0,0 +1,106 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::expressions::patchExpr::parser + +Description + Lemon parser interface for patch expressions grammar + +\*---------------------------------------------------------------------------*/ + +#ifndef expressions_patchExprParser_H +#define expressions_patchExprParser_H + +#include "patchExprFwd.H" + +namespace Foam +{ +namespace expressions +{ +namespace patchExpr +{ + +/*---------------------------------------------------------------------------*\ + Class parser Declaration +\*---------------------------------------------------------------------------*/ + +class parser +{ + // Private Data + + //- Prompt for parser tracing + static constexpr const char* const prompt_ = "patchExpr:"; + + //- The lemon parser (demand-driven) + void* lemon_; + + +public: + + //- Local object debugging + int debug; + + + // Constructors + + //- Construct null + parser() : lemon_(nullptr), debug(patchExpr::debug) {} + + + //- Destructor, deletes parser backend + ~parser() + { + stop(); + } + + + // Member Functions + + //- Start parsing, with the given driver context + void start(parseDriver& driver_); + + //- Stop parsing, freeing the allocated parser + void stop(); + + //- Push token/value to parser + void parse(int tokenId, scanToken* tokenVal); + + //- Return the text name corresponding to the tokenId + word nameOfToken(int tokenId) const; +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace patchExpr +} // End namespace expressions +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.H b/src/finiteVolume/expressions/patch/patchExprScanner.H new file mode 100644 index 0000000000..3003b749bf --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprScanner.H @@ -0,0 +1,162 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::expressions::patchExpr::scanner + +Description + Ragel lexer/scanner interface for patch expressions. + +Note + Ragel code generated with the ./createCode script. + +\*---------------------------------------------------------------------------*/ + +#ifndef expressions_patchExprScanner_H +#define expressions_patchExprScanner_H + +#include "patchExprFwd.H" +#include "scalar.H" + +namespace Foam +{ +namespace expressions +{ +namespace patchExpr +{ + +/*---------------------------------------------------------------------------*\ + Class scanToken Declaration +\*---------------------------------------------------------------------------*/ + +union scanToken +{ + Foam::label ivalue; + Foam::scalar svalue; + Foam::word* name; + + //- Null construct, bit-wise zero for union content + scanToken() : ivalue(0) {} +}; + + +/*---------------------------------------------------------------------------*\ + Class scanner Declaration +\*---------------------------------------------------------------------------*/ + +class scanner +{ + // Private Data + + //- Wrapped lemon parser + parser* parser_; + + // Ragel code state, action + int cs, act; + + + // Private Member Functions + + //- Dispatch .method to parser (if known) or Fatal + bool dispatch_method + ( + const parseDriver& driver_, + scanToken& scanTok, + word&& ident + ) const; + + //- Dispatch identifier to parser (if possible) or Fatal + bool dispatch_ident + ( + const parseDriver& driver_, + scanToken& scanTok, + word&& ident + ) const; + + +public: + + //- Local debugging + int debug; + + + // Constructors + + //- Construct null, optionally setting debugging + explicit scanner(bool withDebug = false) + : + parser_(nullptr), + debug(patchExpr::debug) + { + if (withDebug) + { + debug |= 4; + } + } + + + //- Destructor, deletes parser + ~scanner(); + + + // Member Functions + + //- Evaluate sub-string + bool process + ( + const std::string& str, size_t pos, size_t len, + parseDriver& driver_ + ); + + //- Evaluate sub-string + bool process + ( + const std::string& str, size_t pos, + parseDriver& driver_ + ) + { + return process(str, pos, std::string::npos, driver_); + } + + //- Evaluate string + bool process(const std::string& str, parseDriver& driver_) + { + return process(str, 0, std::string::npos, driver_); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace patchExpr +} // End namespace expressions +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.cc b/src/finiteVolume/expressions/patch/patchExprScanner.cc new file mode 100644 index 0000000000..98fe2225e1 --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprScanner.cc @@ -0,0 +1,3836 @@ + +#line 1 "patchExprScanner.rl" +/*--------------------------------*- 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 + Ragel lexer interface for lemon grammar for patch expressions + +\*---------------------------------------------------------------------------*/ + +#include "patchExprScanner.H" +#include "patchExprDriver.H" +#include "patchExprLemonParser.h" +#include "patchExprParser.H" +#include "Enum.H" +#include "macros.H" + +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#pragma GCC diagnostic ignored "-Wold-style-cast" + +// Debugging to stderr +#undef DebugInfo +#define DebugInfo if (debug) InfoErr + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + +//- Paste token prefix +#define TOKEN_OF(T) TOK_##T + +//- An {int, c_str} enum pairing +#define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } + +#undef HAS_LOOKBEHIND_TOKENS + +// Special handling of predefined method types. Eg, .x(), .y(), ... +static const Enum fieldMethodEnums +({ + TOKEN_PAIR("x", CMPT_X), + TOKEN_PAIR("y", CMPT_Y), + TOKEN_PAIR("z", CMPT_Z), + TOKEN_PAIR("xx", CMPT_XX), + TOKEN_PAIR("xy", CMPT_XY), + TOKEN_PAIR("xz", CMPT_XZ), + TOKEN_PAIR("yx", CMPT_YX), + TOKEN_PAIR("yy", CMPT_YY), + TOKEN_PAIR("yz", CMPT_YZ), + TOKEN_PAIR("zx", CMPT_ZX), + TOKEN_PAIR("zy", CMPT_ZY), + TOKEN_PAIR("zz", CMPT_ZZ), + TOKEN_PAIR("ii", CMPT_II), + TOKEN_PAIR("diag", DIAG), /* tensors only */ + TOKEN_PAIR("T", TRANSPOSE), /* tensors only */ +}); + +// Known field-token types +static const Enum fieldTokenEnums +({ +#ifdef TOK_SCALAR_ID + TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID), + TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID), + TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID), + TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID), + TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID), +#else +#error TOK_SCALAR_ID not defined +#endif +#ifdef TOK_SSCALAR_ID + TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID), + TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID), + TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID), + TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID), + TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID), +#else +#error TOK_SSCALAR_ID not defined +#endif +#ifdef TOK_PSCALAR_ID + TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID), + TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID), + TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID), + TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID), + TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID), +#else +#warning TOK_PSCALAR_ID not defined +#endif +}); + + +// Simple compile-time function name declarations. +// Useful for handling driver-specific dispatching, or functions that +// are not universally available. +static const Enum funcTokenEnums +({ +#ifdef TOK_FLOOR + TOKEN_PAIR("floor", FLOOR), + TOKEN_PAIR("ceil", CEIL), + TOKEN_PAIR("round", ROUND), +#endif +#ifdef TOK_HYPOT /* Can use hypot? */ + TOKEN_PAIR("hypot", HYPOT), +#endif + + // Already parsed as function: TOKEN_PAIR("pos", FACE_CENTRE), + + TOKEN_PAIR("point", POINT_EXPR), // Point value + TOKEN_PAIR("face", FACE_EXPR), // Face areaNormal + + TOKEN_PAIR("faceToPoint", FACE_TO_POINT), + TOKEN_PAIR("pointToFace", POINT_TO_FACE), + + TOKEN_PAIR("area", FACE_AREA), + TOKEN_PAIR("pts", POINTS), +}); + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Classifying token type based on an identifier name is indeed ugly. +// +// 1) +// Handle special cases (eg, cellSet,...) first that have been tagged +// as expected content with the stashed "look-behind" token. +// Handle not-found errors here directly. +// +// 2) +// Fallback to determining which field-type (volScalarField etc) the name +// corresponds to. +// Handle not-found errors by return -1. +// +static int driverTokenType +( + const expressions::patchExpr::parseDriver& driver_, + const word& ident +) +{ +#if 0 + // Get stashed "look-behind" to decide what type of identifier we expect + const int lookBehind = driver_.resetStashedTokenId(); + + if (lookBehind && lookBehindTokenEnums.found(lookBehind)) + { + bool good = false; + + switch (lookBehind) + { + case TOK_CSET : good = driver_.isCellSet(ident); break; + case TOK_FSET : good = driver_.isFaceSet(ident); break; + case TOK_PSET : good = driver_.isPointSet(ident); break; + case TOK_CZONE : good = driver_.isCellZone(ident); break; + case TOK_FZONE : good = driver_.isFaceZone(ident); break; + case TOK_PZONE : good = driver_.isPointZone(ident); break; + } + + if (good) + { + return TOK_IDENTIFIER; + } + + // Fatal + driver_.reportFatal + ( + "Error no " + lookBehindTokenEnums.get(lookBehind) + ": " + ident + ); + + return -2; // Extra safety + } +#endif + + // Face variables + #ifdef TOK_SSCALAR_ID + { + #undef checkFieldToken + #define checkFieldToken(TokType, Type) \ + if (driver_.isVariable(ident, false)) \ + { \ + return TokType; \ + } + + checkFieldToken(TOK_SSCALAR_ID, scalar); + checkFieldToken(TOK_SVECTOR_ID, vector); + checkFieldToken(TOK_SSYM_TENSOR_ID, symmTensor); + checkFieldToken(TOK_SSPH_TENSOR_ID, sphericalTensor); + checkFieldToken(TOK_STENSOR_ID, tensor); + + // Not tested: checkFieldToken(TOK_SBOOL_ID, bool); + } + #endif + + // Point variables + #ifdef TOK_PSCALAR_ID + { + #undef checkFieldToken + #define checkFieldToken(TokType, Type) \ + if (driver_.isVariable(ident, true)) \ + { \ + return TokType; \ + } + + checkFieldToken(TOK_PSCALAR_ID, scalar); + checkFieldToken(TOK_PVECTOR_ID, vector); + checkFieldToken(TOK_PTENSOR_ID, tensor); + checkFieldToken(TOK_PTENSOR_ID, tensor); + checkFieldToken(TOK_PSYM_TENSOR_ID, symmTensor); + checkFieldToken(TOK_PSPH_TENSOR_ID, sphericalTensor); + + // Not tested: checkFieldToken(TOK_PBOOL_ID, bool); + } + #endif + + #undef checkFieldToken + + // Check registered fields and/or disk-files + { + const word fieldType(driver_.getFieldClassName(ident)); + + int tokType = fieldTokenEnums.get(fieldType, -1); + + if (tokType > 0) + { + return tokType; + } + } + + return -1; +} + +} // End anonymous namespace + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Ragel machine definition +// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later... +// +// Can use 'variable p xxx;' etc to change these names + +#define EMIT_TOKEN(T) \ + driver_.parsePosition() = (ts-buf); \ + DebugInfo<< STRINGIFY(T) << ": " << driver_.parsePosition() << nl; \ + parser_->parse(TOKEN_OF(T), nullptr); \ + driver_.parsePosition() = (p-buf); + + + +#line 276 "patchExprScanner.cc" +static const int patchExpr_start = 11; +static const int patchExpr_first_final = 11; +static const int patchExpr_error = 0; + +static const int patchExpr_en_main = 11; + + +#line 414 "patchExprScanner.rl" + + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::expressions::patchExpr::scanner::~scanner() +{ + if (parser_) + { + delete parser_; + } +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +bool Foam::expressions::patchExpr::scanner::dispatch_method +( + const parseDriver& driver_, + scanToken& scanTok, + word&& ident +) const +{ + if (ident[0] == '.') + { + ident.erase(0, 1); + } + + DebugInfo + << "Method:" << ident + << " at " << driver_.parsePosition() << nl; + + const int methType = fieldMethodEnums.get(ident, -1); + + if (methType > 0) + { + // Dispatch '.' and "method" separately + parser_->parse(TOK_DOT, nullptr); + parser_->parse(methType, nullptr); + + return true; + } + + driver_.reportFatal("Unknown method: " + ident); + return false; +} + + +bool Foam::expressions::patchExpr::scanner::dispatch_ident +( + const parseDriver& driver_, + scanToken& scanTok, + word&& ident +) const +{ + int tokType = -1; + + const bool quoted = + ( + (ident.front() == '"' || ident.front() == '\'') + && (ident.front() == ident.back()) + ); + + if (quoted) + { + ident.erase(ident.size()-1); + ident.erase(0, 1); + } + else + { + // Check for function name + tokType = funcTokenEnums.get(ident, -1); + + if (tokType > 0) + { + DebugInfo + << "Emit:" << ident << " function:" + << parser_->nameOfToken(tokType) << nl; + + parser_->parse(tokType, nullptr); + return true; + } + + #ifdef HAS_LOOKBEHIND_TOKENS + // Specials such "cset" also reset the look-behind + tokType = lookBehindTokenEnums.get(ident, -1); + + if (tokType > 0) + { + DebugInfo + << "Emit:" << ident << " as look-behind:" + << parser_->nameOfToken(tokType) << nl; + + driver_.resetStashedTokenId(tokType); + parser_->parse(tokType, nullptr); + return true; + } + #endif + } + + + // Can also peek at stashed "look-behind" + // const int lookBehind = driver_.stashedTokenId(); + + tokType = driverTokenType(driver_, ident); + + if (tokType > 0) + { + DebugInfo + << "Emit:" << ident << " token:" + << parser_->nameOfToken(tokType) << nl; + + scanTok.name = new Foam::word(std::move(ident)); + parser_->parse(tokType, &scanTok); + + return true; + } + + + // Not found? Attempt to strip off '.x' endings etc, + // but not when quoted + + const auto dot = ident.rfind('.'); + const int methType = + ( + quoted || dot == std::string::npos + ? -1 + : fieldMethodEnums.get(ident.substr(dot+1), -1) + ); + + if + ( + methType > 0 + && (tokType = driverTokenType(driver_, ident.substr(0, dot))) > 0 + ) + { + DebugInfo + << "Emit:" << ident.substr(0, dot).c_str() << " token:" + << parser_->nameOfToken(tokType) << " with " + << ident.substr(dot).c_str() << " token:" + << parser_->nameOfToken(methType) << nl; + + // The field (before the ".") + ident.erase(dot); + + scanTok.name = new Foam::word(std::move(ident)); + parser_->parse(tokType, &scanTok); + + // Dispatch '.' and "method" separately + parser_->parse(TOK_DOT, nullptr); + parser_->parse(methType, nullptr); + + return true; + } + + driver_.reportFatal + ( + "Object " + ident + " does not exist or wrong type" + ); + + return false; +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::expressions::patchExpr::scanner::process +( + const std::string& str, + size_t strBeg, + size_t strLen, + parseDriver& driver_ +) +{ + // Save debug value + const int oldDebug = debug; + + if (driver_.debugScanner()) + { + debug |= 4; + } + + if (!parser_) + { + parser_ = new parser(); + } + + driver_.content(str, strBeg, strLen); + + size_t strEnd = str.length(); + + if (strBeg > str.length()) + { + strBeg = str.length(); + } + else if (strLen != std::string::npos) + { + strLen += strBeg; + + if (strLen < str.length()) + { + strEnd = strLen; + } + } + + + parser_->start(driver_); + + // Scan token type + scanToken scanTok; + + // Ragel token start/end (required naming) + const char* ts; + const char* te; + + // Local buffer data. + // - p, pe, eof are required Ragel naming + // - buf is our own naming + + const char* buf = &(str[strBeg]); + const char* eof = &(str[strEnd]); + const char* p = buf; + const char* pe = eof; + + // Initialize FSM variables + +#line 511 "patchExprScanner.cc" + { + cs = patchExpr_start; + ts = 0; + te = 0; + act = 0; + } + +#line 639 "patchExprScanner.rl" + /* ^^^ FSM initialization here ^^^ */; + + +#line 523 "patchExprScanner.cc" + { + if ( p == pe ) + goto _test_eof; + switch ( cs ) + { +tr2: +#line 298 "patchExprScanner.rl" + {te = p+1;{ + driver_.parsePosition() = (ts-buf); + dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); + driver_.parsePosition() = (p-buf); + }} + goto st11; +tr4: +#line 298 "patchExprScanner.rl" + {te = p+1;{ + driver_.parsePosition() = (ts-buf); + dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); + driver_.parsePosition() = (p-buf); + }} + goto st11; +tr5: +#line 276 "patchExprScanner.rl" + {{p = ((te))-1;}{ + driver_.parsePosition() = (ts-buf); + + DebugInfo + << "Number:" << std::string(ts, te-ts).c_str() + << " at " << driver_.parsePosition() << nl; + + if (readScalar(std::string(ts, te-ts), scanTok.svalue)) + { + parser_->parse(TOKEN_OF(NUMBER), &scanTok); + } + else + { + driver_.reportFatal + ( + "Error parsing number: " + std::string(ts, te-ts) + ); + } + + driver_.parsePosition() = (p-buf); + }} + goto st11; +tr8: +#line 341 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(EQUAL); }} + goto st11; +tr9: +#line 395 "patchExprScanner.rl" + {{p = ((te))-1;}{ EMIT_TOKEN(TENSOR); }} + goto st11; +tr11: +#line 403 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(UNIT_TENSOR); }} + goto st11; +tr12: +#line 344 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(LOR); }} + goto st11; +tr16: +#line 326 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(PERCENT); }} + goto st11; +tr19: +#line 327 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(LPAREN); }} + goto st11; +tr20: +#line 328 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(RPAREN); }} + goto st11; +tr21: +#line 329 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(TIMES); }} + goto st11; +tr22: +#line 330 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(PLUS); }} + goto st11; +tr23: +#line 332 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(COMMA); }} + goto st11; +tr24: +#line 331 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(MINUS); }} + goto st11; +tr26: +#line 334 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(DIVIDE); }} + goto st11; +tr28: +#line 336 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(COLON); }} + goto st11; +tr32: +#line 335 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(QUESTION); }} + goto st11; +tr35: +#line 347 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(BIT_XOR); }} + goto st11; +tr52: +#line 320 "patchExprScanner.rl" + {te = p;p--;} + goto st11; +tr53: +#line 325 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(NOT); }} + goto st11; +tr54: +#line 342 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(NOT_EQUAL); }} + goto st11; +tr55: +#line 345 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(BIT_AND); }} + goto st11; +tr56: +#line 343 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(LAND); }} + goto st11; +tr57: +#line 333 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(DOT); }} + goto st11; +tr60: +#line 276 "patchExprScanner.rl" + {te = p;p--;{ + driver_.parsePosition() = (ts-buf); + + DebugInfo + << "Number:" << std::string(ts, te-ts).c_str() + << " at " << driver_.parsePosition() << nl; + + if (readScalar(std::string(ts, te-ts), scanTok.svalue)) + { + parser_->parse(TOKEN_OF(NUMBER), &scanTok); + } + else + { + driver_.reportFatal + ( + "Error parsing number: " + std::string(ts, te-ts) + ); + } + + driver_.parsePosition() = (p-buf); + }} + goto st11; +tr62: +#line 304 "patchExprScanner.rl" + {te = p;p--;{ + // Tokenized ".method" - dispatch '.' and "method" separately + driver_.parsePosition() = (ts-buf); + dispatch_method(driver_, scanTok, word(ts+1, te-ts-1, false)); + driver_.parsePosition() = (p-buf); + }} + goto st11; +tr63: +#line 337 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(LESS); }} + goto st11; +tr64: +#line 338 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(LESS_EQ); }} + goto st11; +tr65: +#line 339 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(GREATER); }} + goto st11; +tr66: +#line 340 "patchExprScanner.rl" + {te = p+1;{ EMIT_TOKEN(GREATER_EQ); }} + goto st11; +tr67: +#line 298 "patchExprScanner.rl" + {te = p;p--;{ + driver_.parsePosition() = (ts-buf); + dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); + driver_.parsePosition() = (p-buf); + }} + goto st11; +tr69: +#line 1 "NONE" + { switch( act ) { + case 26: + {{p = ((te))-1;} EMIT_TOKEN(PI); } + break; + case 27: + {{p = ((te))-1;} EMIT_TOKEN(DEG_TO_RAD); } + break; + case 28: + {{p = ((te))-1;} EMIT_TOKEN(RAD_TO_DEG); } + break; + case 29: + {{p = ((te))-1;} EMIT_TOKEN(EXP); } + break; + case 31: + {{p = ((te))-1;} EMIT_TOKEN(LOG10); } + break; + case 32: + {{p = ((te))-1;} EMIT_TOKEN(POW); } + break; + case 34: + {{p = ((te))-1;} EMIT_TOKEN(SQRT); } + break; + case 35: + {{p = ((te))-1;} EMIT_TOKEN(CBRT); } + break; + case 39: + {{p = ((te))-1;} EMIT_TOKEN(ASIN); } + break; + case 40: + {{p = ((te))-1;} EMIT_TOKEN(ACOS); } + break; + case 42: + {{p = ((te))-1;} EMIT_TOKEN(ATAN2); } + break; + case 43: + {{p = ((te))-1;} EMIT_TOKEN(SINH); } + break; + case 44: + {{p = ((te))-1;} EMIT_TOKEN(COSH); } + break; + case 45: + {{p = ((te))-1;} EMIT_TOKEN(TANH); } + break; + case 47: + {{p = ((te))-1;} EMIT_TOKEN(MAGSQR); } + break; + case 50: + {{p = ((te))-1;} EMIT_TOKEN(POS0); } + break; + case 51: + {{p = ((te))-1;} EMIT_TOKEN(NEG0); } + break; + case 52: + {{p = ((te))-1;} EMIT_TOKEN(SIGN); } + break; + case 53: + {{p = ((te))-1;} EMIT_TOKEN(MIN); } + break; + case 54: + {{p = ((te))-1;} EMIT_TOKEN(MAX); } + break; + case 55: + {{p = ((te))-1;} EMIT_TOKEN(AVERAGE); } + break; + case 56: + {{p = ((te))-1;} EMIT_TOKEN(SUM); } + break; + case 57: + {{p = ((te))-1;} EMIT_TOKEN(WEIGHT_AVERAGE); } + break; + case 58: + {{p = ((te))-1;} EMIT_TOKEN(WEIGHT_SUM); } + break; + case 59: + {{p = ((te))-1;} EMIT_TOKEN(RAND); } + break; + case 60: + {{p = ((te))-1;} EMIT_TOKEN(BOOL); } + break; + case 61: + {{p = ((te))-1;} EMIT_TOKEN(VECTOR); } + break; + case 63: + {{p = ((te))-1;} EMIT_TOKEN(SYM_TENSOR); } + break; + case 64: + {{p = ((te))-1;} EMIT_TOKEN(SPH_TENSOR); } + break; + case 65: + {{p = ((te))-1;} EMIT_TOKEN(ZERO); } + break; + case 66: + {{p = ((te))-1;} EMIT_TOKEN(LTRUE); } + break; + case 67: + {{p = ((te))-1;} EMIT_TOKEN(LFALSE); } + break; + case 69: + {{p = ((te))-1;} EMIT_TOKEN(TIME); } + break; + case 70: + {{p = ((te))-1;} + driver_.parsePosition() = (ts-buf); + dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); + driver_.parsePosition() = (p-buf); + } + break; + } + } + goto st11; +tr83: +#line 369 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(ATAN); }} + goto st11; +tr98: +#line 365 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(COS); }} + goto st11; +tr115: +#line 358 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(LOG); }} + goto st11; +tr122: +#line 374 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(MAG); }} + goto st11; +tr129: +#line 378 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(NEG); }} + goto st11; +tr135: +#line 377 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(POS); }} + goto st11; +tr154: +#line 364 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(SIN); }} + goto st11; +tr170: +#line 361 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(SQR); }} + goto st11; +tr186: +#line 366 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(TAN); }} + goto st11; +tr192: +#line 395 "patchExprScanner.rl" + {te = p;p--;{ EMIT_TOKEN(TENSOR); }} + goto st11; +st11: +#line 1 "NONE" + {ts = 0;} + if ( ++p == pe ) + goto _test_eof11; +case 11: +#line 1 "NONE" + {ts = p;} +#line 870 "patchExprScanner.cc" + switch( (*p) ) { + case 32: goto st12; + case 33: goto st13; + case 34: goto st1; + case 37: goto tr16; + case 38: goto st14; + case 39: goto st3; + case 40: goto tr19; + case 41: goto tr20; + case 42: goto tr21; + case 43: goto tr22; + case 44: goto tr23; + case 45: goto tr24; + case 46: goto st15; + case 47: goto tr26; + case 58: goto tr28; + case 60: goto st20; + case 61: goto st7; + case 62: goto st21; + case 63: goto tr32; + case 90: goto st24; + case 94: goto tr35; + case 95: goto st22; + case 97: goto st27; + case 98: goto st40; + case 99: goto st43; + case 100: goto st48; + case 101: goto st55; + case 102: goto st57; + case 108: goto st61; + case 109: goto st65; + case 110: goto st71; + case 112: goto st74; + case 114: goto st77; + case 115: goto st85; + case 116: goto st113; + case 118: goto st125; + case 119: goto st130; + case 124: goto st10; + } + if ( (*p) < 48 ) { + if ( 9 <= (*p) && (*p) <= 13 ) + goto st12; + } else if ( (*p) > 57 ) { + if ( (*p) > 89 ) { + if ( 103 <= (*p) && (*p) <= 122 ) + goto st22; + } else if ( (*p) >= 65 ) + goto st22; + } else + goto tr27; + goto st0; +st0: +cs = 0; + goto _out; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + if ( (*p) == 32 ) + goto st12; + if ( 9 <= (*p) && (*p) <= 13 ) + goto st12; + goto tr52; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + if ( (*p) == 61 ) + goto tr54; + goto tr53; +st1: + if ( ++p == pe ) + goto _test_eof1; +case 1: + if ( (*p) == 34 ) + goto st0; + goto st2; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + if ( (*p) == 34 ) + goto tr2; + goto st2; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: + if ( (*p) == 38 ) + goto tr56; + goto tr55; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( (*p) == 39 ) + goto st0; + goto st4; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + if ( (*p) == 39 ) + goto tr4; + goto st4; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr58; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st18; + } else + goto st18; + goto tr57; +tr58: +#line 1 "NONE" + {te = p+1;} + goto st16; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: +#line 998 "patchExprScanner.cc" + switch( (*p) ) { + case 69: goto st5; + case 101: goto st5; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr58; + goto tr60; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + switch( (*p) ) { + case 43: goto st6; + case 45: goto st6; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto st17; + goto tr5; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st17; + goto tr5; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st17; + goto tr60; +st18: + if ( ++p == pe ) + goto _test_eof18; +case 18: + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st18; + } else if ( (*p) >= 65 ) + goto st18; + goto tr62; +tr27: +#line 1 "NONE" + {te = p+1;} + goto st19; +st19: + if ( ++p == pe ) + goto _test_eof19; +case 19: +#line 1049 "patchExprScanner.cc" + switch( (*p) ) { + case 46: goto tr58; + case 69: goto st5; + case 101: goto st5; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr27; + goto tr60; +st20: + if ( ++p == pe ) + goto _test_eof20; +case 20: + if ( (*p) == 61 ) + goto tr64; + goto tr63; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) == 61 ) + goto tr8; + goto st0; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: + if ( (*p) == 61 ) + goto tr66; + goto tr65; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +tr68: +#line 1 "NONE" + {te = p+1;} +#line 298 "patchExprScanner.rl" + {act = 70;} + goto st23; +tr72: +#line 1 "NONE" + {te = p+1;} +#line 400 "patchExprScanner.rl" + {act = 65;} + goto st23; +tr78: +#line 1 "NONE" + {te = p+1;} +#line 368 "patchExprScanner.rl" + {act = 40;} + goto st23; +tr80: +#line 1 "NONE" + {te = p+1;} +#line 367 "patchExprScanner.rl" + {act = 39;} + goto st23; +tr84: +#line 1 "NONE" + {te = p+1;} +#line 370 "patchExprScanner.rl" + {act = 42;} + goto st23; +tr89: +#line 1 "NONE" + {te = p+1;} +#line 386 "patchExprScanner.rl" + {act = 55;} + goto st23; +tr92: +#line 1 "NONE" + {te = p+1;} +#line 393 "patchExprScanner.rl" + {act = 60;} + goto st23; +tr96: +#line 1 "NONE" + {te = p+1;} +#line 363 "patchExprScanner.rl" + {act = 35;} + goto st23; +tr99: +#line 1 "NONE" + {te = p+1;} +#line 372 "patchExprScanner.rl" + {act = 44;} + goto st23; +tr106: +#line 1 "NONE" + {te = p+1;} +#line 355 "patchExprScanner.rl" + {act = 27;} + goto st23; +tr108: +#line 1 "NONE" + {te = p+1;} +#line 357 "patchExprScanner.rl" + {act = 29;} + goto st23; +tr112: +#line 1 "NONE" + {te = p+1;} +#line 402 "patchExprScanner.rl" + {act = 67;} + goto st23; +tr117: +#line 1 "NONE" + {te = p+1;} +#line 359 "patchExprScanner.rl" + {act = 31;} + goto st23; +tr121: +#line 1 "NONE" + {te = p+1;} +#line 385 "patchExprScanner.rl" + {act = 54;} + goto st23; +tr125: +#line 1 "NONE" + {te = p+1;} +#line 375 "patchExprScanner.rl" + {act = 47;} + goto st23; +tr126: +#line 1 "NONE" + {te = p+1;} +#line 384 "patchExprScanner.rl" + {act = 53;} + goto st23; +tr130: +#line 1 "NONE" + {te = p+1;} +#line 380 "patchExprScanner.rl" + {act = 51;} + goto st23; +tr131: +#line 1 "NONE" + {te = p+1;} +#line 354 "patchExprScanner.rl" + {act = 26;} + goto st23; +tr134: +#line 1 "NONE" + {te = p+1;} +#line 360 "patchExprScanner.rl" + {act = 32;} + goto st23; +tr136: +#line 1 "NONE" + {te = p+1;} +#line 379 "patchExprScanner.rl" + {act = 50;} + goto st23; +tr144: +#line 1 "NONE" + {te = p+1;} +#line 356 "patchExprScanner.rl" + {act = 28;} + goto st23; +tr145: +#line 1 "NONE" + {te = p+1;} +#line 390 "patchExprScanner.rl" + {act = 59;} + goto st23; +tr153: +#line 1 "NONE" + {te = p+1;} +#line 381 "patchExprScanner.rl" + {act = 52;} + goto st23; +tr155: +#line 1 "NONE" + {te = p+1;} +#line 371 "patchExprScanner.rl" + {act = 43;} + goto st23; +tr168: +#line 1 "NONE" + {te = p+1;} +#line 397 "patchExprScanner.rl" + {act = 64;} + goto st23; +tr171: +#line 1 "NONE" + {te = p+1;} +#line 362 "patchExprScanner.rl" + {act = 34;} + goto st23; +tr172: +#line 1 "NONE" + {te = p+1;} +#line 387 "patchExprScanner.rl" + {act = 56;} + goto st23; +tr180: +#line 1 "NONE" + {te = p+1;} +#line 396 "patchExprScanner.rl" + {act = 63;} + goto st23; +tr187: +#line 1 "NONE" + {te = p+1;} +#line 373 "patchExprScanner.rl" + {act = 45;} + goto st23; +tr195: +#line 1 "NONE" + {te = p+1;} +#line 404 "patchExprScanner.rl" + {act = 69;} + goto st23; +tr197: +#line 1 "NONE" + {te = p+1;} +#line 401 "patchExprScanner.rl" + {act = 66;} + goto st23; +tr202: +#line 1 "NONE" + {te = p+1;} +#line 394 "patchExprScanner.rl" + {act = 61;} + goto st23; +tr215: +#line 1 "NONE" + {te = p+1;} +#line 388 "patchExprScanner.rl" + {act = 57;} + goto st23; +tr217: +#line 1 "NONE" + {te = p+1;} +#line 389 "patchExprScanner.rl" + {act = 58;} + goto st23; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: +#line 1304 "patchExprScanner.cc" + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr69; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st25; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto st26; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto tr72; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 99: goto st28; + case 115: goto st30; + case 116: goto st32; + case 118: goto st35; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st28: + if ( ++p == pe ) + goto _test_eof28; +case 28: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st29; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st29: + if ( ++p == pe ) + goto _test_eof29; +case 29: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto tr78; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st30: + if ( ++p == pe ) + goto _test_eof30; +case 30: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 105: goto st31; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st31: + if ( ++p == pe ) + goto _test_eof31; +case 31: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto tr80; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st32: + if ( ++p == pe ) + goto _test_eof32; +case 32: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st33; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st33: + if ( ++p == pe ) + goto _test_eof33; +case 33: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto st34; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st34: + if ( ++p == pe ) + goto _test_eof34; +case 34: + switch( (*p) ) { + case 46: goto tr68; + case 50: goto tr84; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr83; +st35: + if ( ++p == pe ) + goto _test_eof35; +case 35: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st36; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st36: + if ( ++p == pe ) + goto _test_eof36; +case 36: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto st37; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st37: + if ( ++p == pe ) + goto _test_eof37; +case 37: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st38; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st38: + if ( ++p == pe ) + goto _test_eof38; +case 38: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st39; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st39: + if ( ++p == pe ) + goto _test_eof39; +case 39: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto tr89; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st40: + if ( ++p == pe ) + goto _test_eof40; +case 40: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st41; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st41: + if ( ++p == pe ) + goto _test_eof41; +case 41: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st42; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st42: + if ( ++p == pe ) + goto _test_eof42; +case 42: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 108: goto tr92; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st43: + if ( ++p == pe ) + goto _test_eof43; +case 43: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 98: goto st44; + case 111: goto st46; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st44: + if ( ++p == pe ) + goto _test_eof44; +case 44: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto st45; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st45: + if ( ++p == pe ) + goto _test_eof45; +case 45: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 116: goto tr96; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st46: + if ( ++p == pe ) + goto _test_eof46; +case 46: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto st47; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st47: + if ( ++p == pe ) + goto _test_eof47; +case 47: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 104: goto tr99; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr98; +st48: + if ( ++p == pe ) + goto _test_eof48; +case 48: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st49; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st49: + if ( ++p == pe ) + goto _test_eof49; +case 49: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st50; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st50: + if ( ++p == pe ) + goto _test_eof50; +case 50: + switch( (*p) ) { + case 46: goto tr68; + case 84: goto st51; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st51: + if ( ++p == pe ) + goto _test_eof51; +case 51: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st52; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st52: + if ( ++p == pe ) + goto _test_eof52; +case 52: + switch( (*p) ) { + case 46: goto tr68; + case 82: goto st53; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st53: + if ( ++p == pe ) + goto _test_eof53; +case 53: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st54; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st54: + if ( ++p == pe ) + goto _test_eof54; +case 54: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 100: goto tr106; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st55: + if ( ++p == pe ) + goto _test_eof55; +case 55: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 120: goto st56; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st56: + if ( ++p == pe ) + goto _test_eof56; +case 56: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 112: goto tr108; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st57: + if ( ++p == pe ) + goto _test_eof57; +case 57: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st58; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st58: + if ( ++p == pe ) + goto _test_eof58; +case 58: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 108: goto st59; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st59: + if ( ++p == pe ) + goto _test_eof59; +case 59: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto st60; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st60: + if ( ++p == pe ) + goto _test_eof60; +case 60: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto tr112; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st61: + if ( ++p == pe ) + goto _test_eof61; +case 61: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st62; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st62: + if ( ++p == pe ) + goto _test_eof62; +case 62: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st63; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st63: + if ( ++p == pe ) + goto _test_eof63; +case 63: + switch( (*p) ) { + case 46: goto tr68; + case 49: goto st64; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr115; +st64: + if ( ++p == pe ) + goto _test_eof64; +case 64: + switch( (*p) ) { + case 46: goto tr68; + case 48: goto tr117; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 49 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st65: + if ( ++p == pe ) + goto _test_eof65; +case 65: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st66; + case 105: goto st70; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st66: + if ( ++p == pe ) + goto _test_eof66; +case 66: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st67; + case 120: goto tr121; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st67: + if ( ++p == pe ) + goto _test_eof67; +case 67: + switch( (*p) ) { + case 46: goto tr68; + case 83: goto st68; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr122; +st68: + if ( ++p == pe ) + goto _test_eof68; +case 68: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 113: goto st69; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st69: + if ( ++p == pe ) + goto _test_eof69; +case 69: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto tr125; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st70: + if ( ++p == pe ) + goto _test_eof70; +case 70: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto tr126; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st71: + if ( ++p == pe ) + goto _test_eof71; +case 71: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st72; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st72: + if ( ++p == pe ) + goto _test_eof72; +case 72: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st73; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st73: + if ( ++p == pe ) + goto _test_eof73; +case 73: + switch( (*p) ) { + case 46: goto tr68; + case 48: goto tr130; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 49 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr129; +st74: + if ( ++p == pe ) + goto _test_eof74; +case 74: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 105: goto tr131; + case 111: goto st75; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st75: + if ( ++p == pe ) + goto _test_eof75; +case 75: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto st76; + case 119: goto tr134; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st76: + if ( ++p == pe ) + goto _test_eof76; +case 76: + switch( (*p) ) { + case 46: goto tr68; + case 48: goto tr136; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 49 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr135; +st77: + if ( ++p == pe ) + goto _test_eof77; +case 77: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st78; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st78: + if ( ++p == pe ) + goto _test_eof78; +case 78: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 100: goto st79; + case 110: goto st84; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st79: + if ( ++p == pe ) + goto _test_eof79; +case 79: + switch( (*p) ) { + case 46: goto tr68; + case 84: goto st80; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st80: + if ( ++p == pe ) + goto _test_eof80; +case 80: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st81; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st81: + if ( ++p == pe ) + goto _test_eof81; +case 81: + switch( (*p) ) { + case 46: goto tr68; + case 68: goto st82; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st82: + if ( ++p == pe ) + goto _test_eof82; +case 82: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st83; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st83: + if ( ++p == pe ) + goto _test_eof83; +case 83: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto tr144; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st84: + if ( ++p == pe ) + goto _test_eof84; +case 84: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 100: goto tr145; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st85: + if ( ++p == pe ) + goto _test_eof85; +case 85: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 105: goto st86; + case 112: goto st89; + case 113: goto st102; + case 117: goto st104; + case 121: goto st105; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st86: + if ( ++p == pe ) + goto _test_eof86; +case 86: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st87; + case 110: goto st88; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st87: + if ( ++p == pe ) + goto _test_eof87; +case 87: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto tr153; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st88: + if ( ++p == pe ) + goto _test_eof88; +case 88: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 104: goto tr155; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr154; +st89: + if ( ++p == pe ) + goto _test_eof89; +case 89: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 104: goto st90; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st90: + if ( ++p == pe ) + goto _test_eof90; +case 90: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st91; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st91: + if ( ++p == pe ) + goto _test_eof91; +case 91: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto st92; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st92: + if ( ++p == pe ) + goto _test_eof92; +case 92: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 105: goto st93; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st93: + if ( ++p == pe ) + goto _test_eof93; +case 93: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 99: goto st94; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st94: + if ( ++p == pe ) + goto _test_eof94; +case 94: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st95; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st95: + if ( ++p == pe ) + goto _test_eof95; +case 95: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 108: goto st96; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st96: + if ( ++p == pe ) + goto _test_eof96; +case 96: + switch( (*p) ) { + case 46: goto tr68; + case 84: goto st97; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st97: + if ( ++p == pe ) + goto _test_eof97; +case 97: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st98; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st98: + if ( ++p == pe ) + goto _test_eof98; +case 98: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto st99; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st99: + if ( ++p == pe ) + goto _test_eof99; +case 99: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto st100; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st100: + if ( ++p == pe ) + goto _test_eof100; +case 100: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st101; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st101: + if ( ++p == pe ) + goto _test_eof101; +case 101: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto tr168; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st102: + if ( ++p == pe ) + goto _test_eof102; +case 102: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto st103; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st103: + if ( ++p == pe ) + goto _test_eof103; +case 103: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 116: goto tr171; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr170; +st104: + if ( ++p == pe ) + goto _test_eof104; +case 104: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 109: goto tr172; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st105: + if ( ++p == pe ) + goto _test_eof105; +case 105: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 109: goto st106; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st106: + if ( ++p == pe ) + goto _test_eof106; +case 106: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 109: goto st107; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st107: + if ( ++p == pe ) + goto _test_eof107; +case 107: + switch( (*p) ) { + case 46: goto tr68; + case 84: goto st108; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st108: + if ( ++p == pe ) + goto _test_eof108; +case 108: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st109; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st109: + if ( ++p == pe ) + goto _test_eof109; +case 109: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto st110; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st110: + if ( ++p == pe ) + goto _test_eof110; +case 110: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto st111; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st111: + if ( ++p == pe ) + goto _test_eof111; +case 111: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st112; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st112: + if ( ++p == pe ) + goto _test_eof112; +case 112: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto tr180; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st113: + if ( ++p == pe ) + goto _test_eof113; +case 113: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st114; + case 101: goto st116; + case 105: goto st121; + case 114: goto st123; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st114: + if ( ++p == pe ) + goto _test_eof114; +case 114: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto st115; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st115: + if ( ++p == pe ) + goto _test_eof115; +case 115: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 104: goto tr187; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr186; +st116: + if ( ++p == pe ) + goto _test_eof116; +case 116: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 110: goto st117; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st117: + if ( ++p == pe ) + goto _test_eof117; +case 117: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 115: goto st118; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st118: + if ( ++p == pe ) + goto _test_eof118; +case 118: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st119; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st119: + if ( ++p == pe ) + goto _test_eof119; +case 119: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto tr191; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +tr191: +#line 1 "NONE" + {te = p+1;} + goto st120; +st120: + if ( ++p == pe ) + goto _test_eof120; +case 120: +#line 3071 "patchExprScanner.cc" + switch( (*p) ) { + case 46: goto tr68; + case 58: goto st8; + case 95: goto tr68; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr192; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + if ( (*p) == 58 ) + goto st9; + goto tr9; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + if ( (*p) == 73 ) + goto tr11; + goto tr9; +st121: + if ( ++p == pe ) + goto _test_eof121; +case 121: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 109: goto st122; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st122: + if ( ++p == pe ) + goto _test_eof122; +case 122: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto tr195; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st123: + if ( ++p == pe ) + goto _test_eof123; +case 123: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 117: goto st124; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st124: + if ( ++p == pe ) + goto _test_eof124; +case 124: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto tr197; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st125: + if ( ++p == pe ) + goto _test_eof125; +case 125: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st126; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st126: + if ( ++p == pe ) + goto _test_eof126; +case 126: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 99: goto st127; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st127: + if ( ++p == pe ) + goto _test_eof127; +case 127: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 116: goto st128; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st128: + if ( ++p == pe ) + goto _test_eof128; +case 128: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 111: goto st129; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st129: + if ( ++p == pe ) + goto _test_eof129; +case 129: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto tr202; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st130: + if ( ++p == pe ) + goto _test_eof130; +case 130: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st131; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st131: + if ( ++p == pe ) + goto _test_eof131; +case 131: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 105: goto st132; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st132: + if ( ++p == pe ) + goto _test_eof132; +case 132: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st133; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st133: + if ( ++p == pe ) + goto _test_eof133; +case 133: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 104: goto st134; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st134: + if ( ++p == pe ) + goto _test_eof134; +case 134: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 116: goto st135; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st135: + if ( ++p == pe ) + goto _test_eof135; +case 135: + switch( (*p) ) { + case 46: goto tr68; + case 65: goto st136; + case 83: goto st142; + case 95: goto tr68; + } + if ( (*p) < 66 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st136: + if ( ++p == pe ) + goto _test_eof136; +case 136: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 118: goto st137; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st137: + if ( ++p == pe ) + goto _test_eof137; +case 137: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto st138; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st138: + if ( ++p == pe ) + goto _test_eof138; +case 138: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 114: goto st139; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st139: + if ( ++p == pe ) + goto _test_eof139; +case 139: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 97: goto st140; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 98 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st140: + if ( ++p == pe ) + goto _test_eof140; +case 140: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 103: goto st141; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st141: + if ( ++p == pe ) + goto _test_eof141; +case 141: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 101: goto tr215; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st142: + if ( ++p == pe ) + goto _test_eof142; +case 142: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 117: goto st143; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st143: + if ( ++p == pe ) + goto _test_eof143; +case 143: + switch( (*p) ) { + case 46: goto tr68; + case 95: goto tr68; + case 109: goto tr217; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr68; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr68; + } else + goto tr68; + goto tr67; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + if ( (*p) == 124 ) + goto tr12; + goto st0; + } + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof1: cs = 1; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof28: cs = 28; goto _test_eof; + _test_eof29: cs = 29; goto _test_eof; + _test_eof30: cs = 30; goto _test_eof; + _test_eof31: cs = 31; goto _test_eof; + _test_eof32: cs = 32; goto _test_eof; + _test_eof33: cs = 33; goto _test_eof; + _test_eof34: cs = 34; goto _test_eof; + _test_eof35: cs = 35; goto _test_eof; + _test_eof36: cs = 36; goto _test_eof; + _test_eof37: cs = 37; goto _test_eof; + _test_eof38: cs = 38; goto _test_eof; + _test_eof39: cs = 39; goto _test_eof; + _test_eof40: cs = 40; goto _test_eof; + _test_eof41: cs = 41; goto _test_eof; + _test_eof42: cs = 42; goto _test_eof; + _test_eof43: cs = 43; goto _test_eof; + _test_eof44: cs = 44; goto _test_eof; + _test_eof45: cs = 45; goto _test_eof; + _test_eof46: cs = 46; goto _test_eof; + _test_eof47: cs = 47; goto _test_eof; + _test_eof48: cs = 48; goto _test_eof; + _test_eof49: cs = 49; goto _test_eof; + _test_eof50: cs = 50; goto _test_eof; + _test_eof51: cs = 51; goto _test_eof; + _test_eof52: cs = 52; goto _test_eof; + _test_eof53: cs = 53; goto _test_eof; + _test_eof54: cs = 54; goto _test_eof; + _test_eof55: cs = 55; goto _test_eof; + _test_eof56: cs = 56; goto _test_eof; + _test_eof57: cs = 57; goto _test_eof; + _test_eof58: cs = 58; goto _test_eof; + _test_eof59: cs = 59; goto _test_eof; + _test_eof60: cs = 60; goto _test_eof; + _test_eof61: cs = 61; goto _test_eof; + _test_eof62: cs = 62; goto _test_eof; + _test_eof63: cs = 63; goto _test_eof; + _test_eof64: cs = 64; goto _test_eof; + _test_eof65: cs = 65; goto _test_eof; + _test_eof66: cs = 66; goto _test_eof; + _test_eof67: cs = 67; goto _test_eof; + _test_eof68: cs = 68; goto _test_eof; + _test_eof69: cs = 69; goto _test_eof; + _test_eof70: cs = 70; goto _test_eof; + _test_eof71: cs = 71; goto _test_eof; + _test_eof72: cs = 72; goto _test_eof; + _test_eof73: cs = 73; goto _test_eof; + _test_eof74: cs = 74; goto _test_eof; + _test_eof75: cs = 75; goto _test_eof; + _test_eof76: cs = 76; goto _test_eof; + _test_eof77: cs = 77; goto _test_eof; + _test_eof78: cs = 78; goto _test_eof; + _test_eof79: cs = 79; goto _test_eof; + _test_eof80: cs = 80; goto _test_eof; + _test_eof81: cs = 81; goto _test_eof; + _test_eof82: cs = 82; goto _test_eof; + _test_eof83: cs = 83; goto _test_eof; + _test_eof84: cs = 84; goto _test_eof; + _test_eof85: cs = 85; goto _test_eof; + _test_eof86: cs = 86; goto _test_eof; + _test_eof87: cs = 87; goto _test_eof; + _test_eof88: cs = 88; goto _test_eof; + _test_eof89: cs = 89; goto _test_eof; + _test_eof90: cs = 90; goto _test_eof; + _test_eof91: cs = 91; goto _test_eof; + _test_eof92: cs = 92; goto _test_eof; + _test_eof93: cs = 93; goto _test_eof; + _test_eof94: cs = 94; goto _test_eof; + _test_eof95: cs = 95; goto _test_eof; + _test_eof96: cs = 96; goto _test_eof; + _test_eof97: cs = 97; goto _test_eof; + _test_eof98: cs = 98; goto _test_eof; + _test_eof99: cs = 99; goto _test_eof; + _test_eof100: cs = 100; goto _test_eof; + _test_eof101: cs = 101; goto _test_eof; + _test_eof102: cs = 102; goto _test_eof; + _test_eof103: cs = 103; goto _test_eof; + _test_eof104: cs = 104; goto _test_eof; + _test_eof105: cs = 105; goto _test_eof; + _test_eof106: cs = 106; goto _test_eof; + _test_eof107: cs = 107; goto _test_eof; + _test_eof108: cs = 108; goto _test_eof; + _test_eof109: cs = 109; goto _test_eof; + _test_eof110: cs = 110; goto _test_eof; + _test_eof111: cs = 111; goto _test_eof; + _test_eof112: cs = 112; goto _test_eof; + _test_eof113: cs = 113; goto _test_eof; + _test_eof114: cs = 114; goto _test_eof; + _test_eof115: cs = 115; goto _test_eof; + _test_eof116: cs = 116; goto _test_eof; + _test_eof117: cs = 117; goto _test_eof; + _test_eof118: cs = 118; goto _test_eof; + _test_eof119: cs = 119; goto _test_eof; + _test_eof120: cs = 120; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof121: cs = 121; goto _test_eof; + _test_eof122: cs = 122; goto _test_eof; + _test_eof123: cs = 123; goto _test_eof; + _test_eof124: cs = 124; goto _test_eof; + _test_eof125: cs = 125; goto _test_eof; + _test_eof126: cs = 126; goto _test_eof; + _test_eof127: cs = 127; goto _test_eof; + _test_eof128: cs = 128; goto _test_eof; + _test_eof129: cs = 129; goto _test_eof; + _test_eof130: cs = 130; goto _test_eof; + _test_eof131: cs = 131; goto _test_eof; + _test_eof132: cs = 132; goto _test_eof; + _test_eof133: cs = 133; goto _test_eof; + _test_eof134: cs = 134; goto _test_eof; + _test_eof135: cs = 135; goto _test_eof; + _test_eof136: cs = 136; goto _test_eof; + _test_eof137: cs = 137; goto _test_eof; + _test_eof138: cs = 138; goto _test_eof; + _test_eof139: cs = 139; goto _test_eof; + _test_eof140: cs = 140; goto _test_eof; + _test_eof141: cs = 141; goto _test_eof; + _test_eof142: cs = 142; goto _test_eof; + _test_eof143: cs = 143; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + + _test_eof: {} + if ( p == eof ) + { + switch ( cs ) { + case 12: goto tr52; + case 13: goto tr53; + case 14: goto tr55; + case 15: goto tr57; + case 16: goto tr60; + case 5: goto tr5; + case 6: goto tr5; + case 17: goto tr60; + case 18: goto tr62; + case 19: goto tr60; + case 20: goto tr63; + case 21: goto tr65; + case 22: goto tr67; + case 23: goto tr69; + case 24: goto tr67; + case 25: goto tr67; + case 26: goto tr67; + case 27: goto tr67; + case 28: goto tr67; + case 29: goto tr67; + case 30: goto tr67; + case 31: goto tr67; + case 32: goto tr67; + case 33: goto tr67; + case 34: goto tr83; + case 35: goto tr67; + case 36: goto tr67; + case 37: goto tr67; + case 38: goto tr67; + case 39: goto tr67; + case 40: goto tr67; + case 41: goto tr67; + case 42: goto tr67; + case 43: goto tr67; + case 44: goto tr67; + case 45: goto tr67; + case 46: goto tr67; + case 47: goto tr98; + case 48: goto tr67; + case 49: goto tr67; + case 50: goto tr67; + case 51: goto tr67; + case 52: goto tr67; + case 53: goto tr67; + case 54: goto tr67; + case 55: goto tr67; + case 56: goto tr67; + case 57: goto tr67; + case 58: goto tr67; + case 59: goto tr67; + case 60: goto tr67; + case 61: goto tr67; + case 62: goto tr67; + case 63: goto tr115; + case 64: goto tr67; + case 65: goto tr67; + case 66: goto tr67; + case 67: goto tr122; + case 68: goto tr67; + case 69: goto tr67; + case 70: goto tr67; + case 71: goto tr67; + case 72: goto tr67; + case 73: goto tr129; + case 74: goto tr67; + case 75: goto tr67; + case 76: goto tr135; + case 77: goto tr67; + case 78: goto tr67; + case 79: goto tr67; + case 80: goto tr67; + case 81: goto tr67; + case 82: goto tr67; + case 83: goto tr67; + case 84: goto tr67; + case 85: goto tr67; + case 86: goto tr67; + case 87: goto tr67; + case 88: goto tr154; + case 89: goto tr67; + case 90: goto tr67; + case 91: goto tr67; + case 92: goto tr67; + case 93: goto tr67; + case 94: goto tr67; + case 95: goto tr67; + case 96: goto tr67; + case 97: goto tr67; + case 98: goto tr67; + case 99: goto tr67; + case 100: goto tr67; + case 101: goto tr67; + case 102: goto tr67; + case 103: goto tr170; + case 104: goto tr67; + case 105: goto tr67; + case 106: goto tr67; + case 107: goto tr67; + case 108: goto tr67; + case 109: goto tr67; + case 110: goto tr67; + case 111: goto tr67; + case 112: goto tr67; + case 113: goto tr67; + case 114: goto tr67; + case 115: goto tr186; + case 116: goto tr67; + case 117: goto tr67; + case 118: goto tr67; + case 119: goto tr67; + case 120: goto tr192; + case 8: goto tr9; + case 9: goto tr9; + case 121: goto tr67; + case 122: goto tr67; + case 123: goto tr67; + case 124: goto tr67; + case 125: goto tr67; + case 126: goto tr67; + case 127: goto tr67; + case 128: goto tr67; + case 129: goto tr67; + case 130: goto tr67; + case 131: goto tr67; + case 132: goto tr67; + case 133: goto tr67; + case 134: goto tr67; + case 135: goto tr67; + case 136: goto tr67; + case 137: goto tr67; + case 138: goto tr67; + case 139: goto tr67; + case 140: goto tr67; + case 141: goto tr67; + case 142: goto tr67; + case 143: goto tr67; + } + } + + _out: {} + } + +#line 641 "patchExprScanner.rl" + /* ^^^ FSM execution here ^^^ */; + + if (0 == cs) + { + driver_.reportFatal("Parse error while scanning", (p-buf)); + } + + if (p != eof) + { + driver_.reportFatal("Parsing failed with remaining content", (p-buf)); + } + + // Terminate parser execution + parser_->parse(0, nullptr); + parser_->stop(); + + // Restore debug value + debug = oldDebug; + + return true; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.rl b/src/finiteVolume/expressions/patch/patchExprScanner.rl new file mode 100644 index 0000000000..e26c621c3f --- /dev/null +++ b/src/finiteVolume/expressions/patch/patchExprScanner.rl @@ -0,0 +1,664 @@ +/*--------------------------------*- 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 + Ragel lexer interface for lemon grammar for patch expressions + +\*---------------------------------------------------------------------------*/ + +#include "patchExprScanner.H" +#include "patchExprDriver.H" +#include "patchExprLemonParser.h" +#include "patchExprParser.H" +#include "Enum.H" +#include "macros.H" + +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#pragma GCC diagnostic ignored "-Wold-style-cast" + +// Debugging to stderr +#undef DebugInfo +#define DebugInfo if (debug) InfoErr + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + +//- Paste token prefix +#define TOKEN_OF(T) TOK_##T + +//- An {int, c_str} enum pairing +#define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } + +#undef HAS_LOOKBEHIND_TOKENS + +// Special handling of predefined method types. Eg, .x(), .y(), ... +static const Enum fieldMethodEnums +({ + TOKEN_PAIR("x", CMPT_X), + TOKEN_PAIR("y", CMPT_Y), + TOKEN_PAIR("z", CMPT_Z), + TOKEN_PAIR("xx", CMPT_XX), + TOKEN_PAIR("xy", CMPT_XY), + TOKEN_PAIR("xz", CMPT_XZ), + TOKEN_PAIR("yx", CMPT_YX), + TOKEN_PAIR("yy", CMPT_YY), + TOKEN_PAIR("yz", CMPT_YZ), + TOKEN_PAIR("zx", CMPT_ZX), + TOKEN_PAIR("zy", CMPT_ZY), + TOKEN_PAIR("zz", CMPT_ZZ), + TOKEN_PAIR("ii", CMPT_II), + TOKEN_PAIR("diag", DIAG), /* tensors only */ + TOKEN_PAIR("T", TRANSPOSE), /* tensors only */ +}); + +// Known field-token types +static const Enum fieldTokenEnums +({ +#ifdef TOK_SCALAR_ID + TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID), + TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID), + TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID), + TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID), + TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID), +#else +#error TOK_SCALAR_ID not defined +#endif +#ifdef TOK_SSCALAR_ID + TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID), + TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID), + TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID), + TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID), + TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID), +#else +#error TOK_SSCALAR_ID not defined +#endif +#ifdef TOK_PSCALAR_ID + TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID), + TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID), + TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID), + TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID), + TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID), +#else +#warning TOK_PSCALAR_ID not defined +#endif +}); + + +// Simple compile-time function name declarations. +// Useful for handling driver-specific dispatching, or functions that +// are not universally available. +static const Enum funcTokenEnums +({ +#ifdef TOK_FLOOR + TOKEN_PAIR("floor", FLOOR), + TOKEN_PAIR("ceil", CEIL), + TOKEN_PAIR("round", ROUND), +#endif +#ifdef TOK_HYPOT /* Can use hypot? */ + TOKEN_PAIR("hypot", HYPOT), +#endif + + // Already parsed as function: TOKEN_PAIR("pos", FACE_CENTRE), + + TOKEN_PAIR("point", POINT_EXPR), // Point value + TOKEN_PAIR("face", FACE_EXPR), // Face areaNormal + + TOKEN_PAIR("faceToPoint", FACE_TO_POINT), + TOKEN_PAIR("pointToFace", POINT_TO_FACE), + + TOKEN_PAIR("area", FACE_AREA), + TOKEN_PAIR("pts", POINTS), +}); + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Classifying token type based on an identifier name is indeed ugly. +// +// 1) +// Handle special cases (eg, cellSet,...) first that have been tagged +// as expected content with the stashed "look-behind" token. +// Handle not-found errors here directly. +// +// 2) +// Fallback to determining which field-type (volScalarField etc) the name +// corresponds to. +// Handle not-found errors by return -1. +// +static int driverTokenType +( + const expressions::patchExpr::parseDriver& driver_, + const word& ident +) +{ +#if 0 + // Get stashed "look-behind" to decide what type of identifier we expect + const int lookBehind = driver_.resetStashedTokenId(); + + if (lookBehind && lookBehindTokenEnums.found(lookBehind)) + { + bool good = false; + + switch (lookBehind) + { + case TOK_CSET : good = driver_.isCellSet(ident); break; + case TOK_FSET : good = driver_.isFaceSet(ident); break; + case TOK_PSET : good = driver_.isPointSet(ident); break; + case TOK_CZONE : good = driver_.isCellZone(ident); break; + case TOK_FZONE : good = driver_.isFaceZone(ident); break; + case TOK_PZONE : good = driver_.isPointZone(ident); break; + } + + if (good) + { + return TOK_IDENTIFIER; + } + + // Fatal + driver_.reportFatal + ( + "Error no " + lookBehindTokenEnums.get(lookBehind) + ": " + ident + ); + + return -2; // Extra safety + } +#endif + + // Face variables + #ifdef TOK_SSCALAR_ID + { + #undef checkFieldToken + #define checkFieldToken(TokType, Type) \ + if (driver_.isVariable(ident, false)) \ + { \ + return TokType; \ + } + + checkFieldToken(TOK_SSCALAR_ID, scalar); + checkFieldToken(TOK_SVECTOR_ID, vector); + checkFieldToken(TOK_SSYM_TENSOR_ID, symmTensor); + checkFieldToken(TOK_SSPH_TENSOR_ID, sphericalTensor); + checkFieldToken(TOK_STENSOR_ID, tensor); + + // Not tested: checkFieldToken(TOK_SBOOL_ID, bool); + } + #endif + + // Point variables + #ifdef TOK_PSCALAR_ID + { + #undef checkFieldToken + #define checkFieldToken(TokType, Type) \ + if (driver_.isVariable(ident, true)) \ + { \ + return TokType; \ + } + + checkFieldToken(TOK_PSCALAR_ID, scalar); + checkFieldToken(TOK_PVECTOR_ID, vector); + checkFieldToken(TOK_PTENSOR_ID, tensor); + checkFieldToken(TOK_PTENSOR_ID, tensor); + checkFieldToken(TOK_PSYM_TENSOR_ID, symmTensor); + checkFieldToken(TOK_PSPH_TENSOR_ID, sphericalTensor); + + // Not tested: checkFieldToken(TOK_PBOOL_ID, bool); + } + #endif + + #undef checkFieldToken + + // Check registered fields and/or disk-files + { + const word fieldType(driver_.getFieldClassName(ident)); + + int tokType = fieldTokenEnums.get(fieldType, -1); + + if (tokType > 0) + { + return tokType; + } + } + + return -1; +} + +} // End anonymous namespace + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Ragel machine definition +// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later... +// +// Can use 'variable p xxx;' etc to change these names + +#define EMIT_TOKEN(T) \ + driver_.parsePosition() = (ts-buf); \ + DebugInfo<< STRINGIFY(T) << ": " << driver_.parsePosition() << nl; \ + parser_->parse(TOKEN_OF(T), nullptr); \ + driver_.parsePosition() = (p-buf); + + +%%{ + machine patchExpr; + write data; + + action emit_number { + driver_.parsePosition() = (ts-buf); + + DebugInfo + << "Number:" << std::string(ts, te-ts).c_str() + << " at " << driver_.parsePosition() << nl; + + if (readScalar(std::string(ts, te-ts), scanTok.svalue)) + { + parser_->parse(TOKEN_OF(NUMBER), &scanTok); + } + else + { + driver_.reportFatal + ( + "Error parsing number: " + std::string(ts, te-ts) + ); + } + + driver_.parsePosition() = (p-buf); + } + + action emit_ident { + driver_.parsePosition() = (ts-buf); + dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); + driver_.parsePosition() = (p-buf); + } + + action emit_method { + // Tokenized ".method" - dispatch '.' and "method" separately + driver_.parsePosition() = (ts-buf); + dispatch_method(driver_, scanTok, word(ts+1, te-ts-1, false)); + driver_.parsePosition() = (p-buf); + } + + decimal = ((digit* '.' digit+) | (digit+ '.'?)) ; + number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ; + ident = ((alpha|'_') . ((alnum|[._])**)) ; + dquoted = '"' [^\"]+ '"' ; + squoted = "'" [^\']+ "'" ; + + + ## The scanner + main := |* + space*; + + number => emit_number; + + ## operators + '!' =>{ EMIT_TOKEN(NOT); }; + '%' =>{ EMIT_TOKEN(PERCENT); }; + '(' =>{ EMIT_TOKEN(LPAREN); }; + ')' =>{ EMIT_TOKEN(RPAREN); }; + '*' =>{ EMIT_TOKEN(TIMES); }; + '+' =>{ EMIT_TOKEN(PLUS); }; + '-' =>{ EMIT_TOKEN(MINUS); }; + ',' =>{ EMIT_TOKEN(COMMA); }; + '.' =>{ EMIT_TOKEN(DOT); }; + '/' =>{ EMIT_TOKEN(DIVIDE); }; + '?' =>{ EMIT_TOKEN(QUESTION); }; + ':' =>{ EMIT_TOKEN(COLON); }; + '<' =>{ EMIT_TOKEN(LESS); }; + '<=' =>{ EMIT_TOKEN(LESS_EQ); }; + '>' =>{ EMIT_TOKEN(GREATER); }; + '>=' =>{ EMIT_TOKEN(GREATER_EQ); }; + '==' =>{ EMIT_TOKEN(EQUAL); }; + '!=' =>{ EMIT_TOKEN(NOT_EQUAL); }; + '&&' =>{ EMIT_TOKEN(LAND); }; + '||' =>{ EMIT_TOKEN(LOR); }; + '&' =>{ EMIT_TOKEN(BIT_AND); }; +## Not needed? '|' =>{ EMIT_TOKEN(BIT_OK); }; + '^' =>{ EMIT_TOKEN(BIT_XOR); }; + + ## Some '.method' - Error if unknown + '.' alpha+ => emit_method; + + + ## Regular functions + "pi" =>{ EMIT_TOKEN(PI); }; + "degToRad" =>{ EMIT_TOKEN(DEG_TO_RAD); }; + "radToDeg" =>{ EMIT_TOKEN(RAD_TO_DEG); }; + "exp" =>{ EMIT_TOKEN(EXP); }; + "log" =>{ EMIT_TOKEN(LOG); }; + "log10" =>{ EMIT_TOKEN(LOG10); }; + "pow" =>{ EMIT_TOKEN(POW); }; + "sqr" =>{ EMIT_TOKEN(SQR); }; + "sqrt" =>{ EMIT_TOKEN(SQRT); }; + "cbrt" =>{ EMIT_TOKEN(CBRT); }; + "sin" =>{ EMIT_TOKEN(SIN); }; + "cos" =>{ EMIT_TOKEN(COS); }; + "tan" =>{ EMIT_TOKEN(TAN); }; + "asin" =>{ EMIT_TOKEN(ASIN); }; + "acos" =>{ EMIT_TOKEN(ACOS); }; + "atan" =>{ EMIT_TOKEN(ATAN); }; + "atan2" =>{ EMIT_TOKEN(ATAN2); }; + "sinh" =>{ EMIT_TOKEN(SINH); }; + "cosh" =>{ EMIT_TOKEN(COSH); }; + "tanh" =>{ EMIT_TOKEN(TANH); }; + "mag" =>{ EMIT_TOKEN(MAG); }; + "magSqr" =>{ EMIT_TOKEN(MAGSQR); }; + + "pos" =>{ EMIT_TOKEN(POS); }; + "neg" =>{ EMIT_TOKEN(NEG); }; + "pos0" =>{ EMIT_TOKEN(POS0); }; + "neg0" =>{ EMIT_TOKEN(NEG0); }; + "sign" =>{ EMIT_TOKEN(SIGN); }; + + ## Reductions, or other special functions + "min" =>{ EMIT_TOKEN(MIN); }; + "max" =>{ EMIT_TOKEN(MAX); }; + "average" =>{ EMIT_TOKEN(AVERAGE); }; + "sum" =>{ EMIT_TOKEN(SUM); }; + "weightAverage" =>{ EMIT_TOKEN(WEIGHT_AVERAGE); }; + "weightSum" =>{ EMIT_TOKEN(WEIGHT_SUM); }; + "rand" =>{ EMIT_TOKEN(RAND); }; + + ## Types + "bool" =>{ EMIT_TOKEN(BOOL); }; + "vector" =>{ EMIT_TOKEN(VECTOR); }; + "tensor" =>{ EMIT_TOKEN(TENSOR); }; + "symmTensor" =>{ EMIT_TOKEN(SYM_TENSOR); }; + "sphericalTensor" =>{ EMIT_TOKEN(SPH_TENSOR); }; + + ## Single value (constants, etc) + "Zero" =>{ EMIT_TOKEN(ZERO); }; + "true" =>{ EMIT_TOKEN(LTRUE); }; + "false" =>{ EMIT_TOKEN(LFALSE); }; + "tensor::I" =>{ EMIT_TOKEN(UNIT_TENSOR); }; + "time" =>{ EMIT_TOKEN(TIME); }; + + ## Identifier (field, etc - error if unknown) + ## Handle 'bare' names and single/double quoted ones + ident => emit_ident; + dquoted => emit_ident; + squoted => emit_ident; + + space*; + *|; +}%% + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::expressions::patchExpr::scanner::~scanner() +{ + if (parser_) + { + delete parser_; + } +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +bool Foam::expressions::patchExpr::scanner::dispatch_method +( + const parseDriver& driver_, + scanToken& scanTok, + word&& ident +) const +{ + if (ident[0] == '.') + { + ident.erase(0, 1); + } + + DebugInfo + << "Method:" << ident + << " at " << driver_.parsePosition() << nl; + + const int methType = fieldMethodEnums.get(ident, -1); + + if (methType > 0) + { + // Dispatch '.' and "method" separately + parser_->parse(TOK_DOT, nullptr); + parser_->parse(methType, nullptr); + + return true; + } + + driver_.reportFatal("Unknown method: " + ident); + return false; +} + + +bool Foam::expressions::patchExpr::scanner::dispatch_ident +( + const parseDriver& driver_, + scanToken& scanTok, + word&& ident +) const +{ + int tokType = -1; + + const bool quoted = + ( + (ident.front() == '"' || ident.front() == '\'') + && (ident.front() == ident.back()) + ); + + if (quoted) + { + ident.erase(ident.size()-1); + ident.erase(0, 1); + } + else + { + // Check for function name + tokType = funcTokenEnums.get(ident, -1); + + if (tokType > 0) + { + DebugInfo + << "Emit:" << ident << " function:" + << parser_->nameOfToken(tokType) << nl; + + parser_->parse(tokType, nullptr); + return true; + } + + #ifdef HAS_LOOKBEHIND_TOKENS + // Specials such "cset" also reset the look-behind + tokType = lookBehindTokenEnums.get(ident, -1); + + if (tokType > 0) + { + DebugInfo + << "Emit:" << ident << " as look-behind:" + << parser_->nameOfToken(tokType) << nl; + + driver_.resetStashedTokenId(tokType); + parser_->parse(tokType, nullptr); + return true; + } + #endif + } + + + // Can also peek at stashed "look-behind" + // const int lookBehind = driver_.stashedTokenId(); + + tokType = driverTokenType(driver_, ident); + + if (tokType > 0) + { + DebugInfo + << "Emit:" << ident << " token:" + << parser_->nameOfToken(tokType) << nl; + + scanTok.name = new Foam::word(std::move(ident)); + parser_->parse(tokType, &scanTok); + + return true; + } + + + // Not found? Attempt to strip off '.x' endings etc, + // but not when quoted + + const auto dot = ident.rfind('.'); + const int methType = + ( + quoted || dot == std::string::npos + ? -1 + : fieldMethodEnums.get(ident.substr(dot+1), -1) + ); + + if + ( + methType > 0 + && (tokType = driverTokenType(driver_, ident.substr(0, dot))) > 0 + ) + { + DebugInfo + << "Emit:" << ident.substr(0, dot).c_str() << " token:" + << parser_->nameOfToken(tokType) << " with " + << ident.substr(dot).c_str() << " token:" + << parser_->nameOfToken(methType) << nl; + + // The field (before the ".") + ident.erase(dot); + + scanTok.name = new Foam::word(std::move(ident)); + parser_->parse(tokType, &scanTok); + + // Dispatch '.' and "method" separately + parser_->parse(TOK_DOT, nullptr); + parser_->parse(methType, nullptr); + + return true; + } + + driver_.reportFatal + ( + "Object " + ident + " does not exist or wrong type" + ); + + return false; +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::expressions::patchExpr::scanner::process +( + const std::string& str, + size_t strBeg, + size_t strLen, + parseDriver& driver_ +) +{ + // Save debug value + const int oldDebug = debug; + + if (driver_.debugScanner()) + { + debug |= 4; + } + + if (!parser_) + { + parser_ = new parser(); + } + + driver_.content(str, strBeg, strLen); + + size_t strEnd = str.length(); + + if (strBeg > str.length()) + { + strBeg = str.length(); + } + else if (strLen != std::string::npos) + { + strLen += strBeg; + + if (strLen < str.length()) + { + strEnd = strLen; + } + } + + + parser_->start(driver_); + + // Scan token type + scanToken scanTok; + + // Ragel token start/end (required naming) + const char* ts; + const char* te; + + // Local buffer data. + // - p, pe, eof are required Ragel naming + // - buf is our own naming + + const char* buf = &(str[strBeg]); + const char* eof = &(str[strEnd]); + const char* p = buf; + const char* pe = eof; + + // Initialize FSM variables + %%{write init;}%% /* ^^^ FSM initialization here ^^^ */; + + %%{write exec;}%% /* ^^^ FSM execution here ^^^ */; + + if (%%{write error;}%% == cs) + { + driver_.reportFatal("Parse error while scanning", (p-buf)); + } + + if (p != eof) + { + driver_.reportFatal("Parsing failed with remaining content", (p-buf)); + } + + // Terminate parser execution + parser_->parse(0, nullptr); + parser_->stop(); + + // Restore debug value + debug = oldDebug; + + return true; +} + + +// ************************************************************************* //