diff --git a/applications/test/dictionary/testDictCalc1 b/applications/test/dictionary/testDictCalc1 new file mode 100644 index 0000000000000000000000000000000000000000..93b52a9fb8e7d990799a2e3068b09b32e950cfb9 --- /dev/null +++ b/applications/test/dictionary/testDictCalc1 @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: Any | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object testDictCalc1; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +calc1 #calc #{ degToRad() * + constant::mathematical::pi * + cos(100.0) * mag(19) + 1 * constant::mathematical::pi + + + // Skip comments + constant::mathematical::pi * 15 + hypot(3.0,4.0) #}; + +calc3 (#calc"hypot(3.0,4.0)", #calc"sqrt(2.0)", #calc"constant::mathematical::pi"); + +calc4 #calc"$calc1 * 10"; + +pi() #calc #{ constant::mathematical::pi #}; + +sinh(0.1) #calc #{ sinh(0.1) #}; +cosh(0.1) #calc #{ cosh(0.1) #}; + +sqrt100 #calc #{((sqrt(100.0)))#}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/test/dictionary/testDictEval1 b/applications/test/dictionary/testDictEval1 new file mode 100644 index 0000000000000000000000000000000000000000..2fccaa7f418906d8c5e7f5a191ac668a7e437549 --- /dev/null +++ b/applications/test/dictionary/testDictEval1 @@ -0,0 +1,44 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: Any | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object testDictEval1; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +eval1 #eval #{ degToRad() * + pi() * + cos(100) * mag(19) + 1 * pi() + + + // Skip comments + pi() * 15 + hypot(3,4) #}; + +eval2 #eval{ degToRad() * + pi() * + cos(100) * mag(19) + 1 * pi() + + + // Skip comments + pi() * 15 + hypot(3,4) }; + +eval3 (#eval{hypot(3,4)}, #eval{sqrt(2)}, #eval{pi()}); + +eval4 #eval{$eval1 * 10}; + +pi() #eval{pi()}; + +rand() #eval{100*rand(123456)}; + +sinh(0.1) #eval{sinh(0.1)}; +cosh(0.1) #eval{cosh(0.1)}; + +sqrt100 #eval{((sqrt(100)))}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 92e60ba056263404263a94b4ca9feb3b2dd15569..c8e5d89eb0d200c6c65720c764ea253df00b3352 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -130,9 +130,13 @@ $(strings)/wordRe/wordRe.C $(strings)/wordRes/wordRes.C $(strings)/lists/CStringList.C $(strings)/lists/hashedWordList.C +$(strings)/parsing/parsing.C +$(strings)/parsing/genericRagelLemonDriver.C $(strings)/stringOps/stringOps.C $(strings)/stringOps/stringOpsSort.C -$(strings)/parsing/parsing.C +$(strings)/stringOps/toScalar/evalStringToScalarDriver.C +$(strings)/stringOps/toScalar/evalStringToScalarLemonParser.lyy +$(strings)/stringOps/toScalar/evalStringToScalarScanner.cc ops = primitives/ops $(ops)/flipOp.C @@ -248,6 +252,7 @@ $(dictionaryListEntry)/dictionaryListEntryIO.C functionEntries = $(dictionary)/functionEntries $(functionEntries)/calcEntry/calcEntry.C $(functionEntries)/codeStream/codeStream.C +$(functionEntries)/evalEntry/evalEntry.C $(functionEntries)/functionEntry/functionEntry.C $(functionEntries)/includeEntry/includeEntry.C $(functionEntries)/includeEtcEntry/includeEtcEntry.C diff --git a/src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.C new file mode 100644 index 0000000000000000000000000000000000000000..5599f771a83b57318fd96e32e992a558159a24d5 --- /dev/null +++ b/src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.C @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "evalEntry.H" +#include "dictionary.H" +#include "stringOps.H" +#include "addToMemberFunctionSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionEntries +{ + addNamedToMemberFunctionSelectionTable + ( + functionEntry, + evalEntry, + execute, + dictionaryIstream, + eval + ); + + addNamedToMemberFunctionSelectionTable + ( + functionEntry, + evalEntry, + execute, + primitiveEntryIstream, + eval + ); + +} // End namespace functionEntry +} // End namespace Foam + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::scalar Foam::functionEntries::evalEntry::evaluate +( + const dictionary& parentDict, + Istream& is +) +{ + DetailInfo + << "Using #eval at line " << is.lineNumber() + << " in file " << parentDict.name() << nl; + + // String to evaluate + string s; + + token tok(is); + + if (!tok.good()) + { + FatalIOErrorInFunction(is) + << "Bad token - could not get string to evaluate" + << exit(FatalIOError); + return 0; + } + + if (tok.isString()) + { + s = tok.stringToken(); + } + else if (tok == token::BEGIN_BLOCK) + { + dynamic_cast<ISstream&>(is).getLine(s, token::END_BLOCK); + } + else + { + is.putBack(tok); + + FatalIOErrorInFunction(is) + << "Invalid input for #eval" << nl + << exit(FatalIOError); + } + + #ifdef FULLDEBUG + DetailInfo + << "input: " << s << endl; + #endif + + stringOps::inplaceRemoveComments(s); + stringOps::inplaceExpand(s, parentDict); + + #ifdef FULLDEBUG + DetailInfo + << "expanded: " << s << endl; + #endif + + return stringOps::toScalar(s); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionEntries::evalEntry::execute +( + const dictionary& parentDict, + primitiveEntry& entry, + Istream& is +) +{ + const scalar value = evaluate(parentDict, is); + + // The result as terminated token entry + ITstream result + ( + "eval", + tokenList({token(value), token(token::END_STATEMENT)}) + ); + + entry.read(parentDict, result); + + return true; +} + + +bool Foam::functionEntries::evalEntry::execute +( + dictionary& parentDict, + Istream& is +) +{ + const scalar value = evaluate(parentDict, is); + + // The result as terminated token entry + ITstream result + ( + "eval", + tokenList({token(value), token(token::END_STATEMENT)}) + ); + + parentDict.read(result); + + return true; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.H new file mode 100644 index 0000000000000000000000000000000000000000..ce19a2f8b8ac8e351279d2bf6474681daaee6003 --- /dev/null +++ b/src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.H @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Class + Foam::functionEntries::evalEntry + +Description + Uses stringOps::toScalar to evaluate mathematical expressions. + + The input can any form of string or, for convenience, + a '{}' delimited string literal. In all cases, C/C++ comment stripping + is also performed. + + For example, + + \verbatim + a 1; + b 3; + c #eval "sin(pi()*$a/$b)"; + + d #eval{ + // ignore: sin(pi()*$a/$b) + sin(degToRad(45)) + }; + \endverbatim + +SourceFiles + evalEntry.C + +\*---------------------------------------------------------------------------*/ + +#ifndef evalEntry_H +#define evalEntry_H + +#include "functionEntry.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionEntries +{ + +/*---------------------------------------------------------------------------*\ + Class evalEntry Declaration +\*---------------------------------------------------------------------------*/ + +class evalEntry +: + public functionEntry +{ + + //- Evaluate and return a scalar + static scalar evaluate(const dictionary& parentDict, Istream& is); + + +public: + + //- Execute in a primitiveEntry context + static bool execute + ( + const dictionary& parentDict, + primitiveEntry& thisEntry, + Istream& is + ); + + //- Execute in a sub-dict context + static bool execute(dictionary& parentDict, Istream& is); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace functionEntries +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C new file mode 100644 index 0000000000000000000000000000000000000000..1ce3749cfde2a2794a760f5b537acba614259b65 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C @@ -0,0 +1,192 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "genericRagelLemonDriver.H" +#include "evalStringToScalarDriver.H" +#include "error.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::parsing::genericRagelLemonDriver::genericRagelLemonDriver() +: + content_(std::cref<std::string>(string::null)), + position_(0) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::Ostream& Foam::parsing::genericRagelLemonDriver::printBuffer +( + Ostream& os +) const +{ + const std::string& s = content_.get(); + + for (char c : s) + { + // if (!c) break; + + if (c == '\t') + { + // Flatten tab to single space for better alignment + os << ' '; + } + else + { + os << c; + } + } + + return os; +} + + +void Foam::parsing::genericRagelLemonDriver::reportFatal +( + const std::string& msg +) const +{ + if (position_) + { + reportFatal(msg, position_); + } + else + { + auto& os = FatalIOError + ( + FUNCTION_NAME, + __FILE__, + __LINE__, + "" + ); + + os << nl << msg.c_str() << " in expression\n" + << "<<<<\n"; + + printBuffer(os) + << "\n>>>>\n" + << exit(Foam::FatalIOError); + } +} + + +void Foam::parsing::genericRagelLemonDriver::reportFatal +( + const std::string& msg, + size_t pos +) const +{ + auto& os = Foam::FatalIOError + ( + FUNCTION_NAME, + __FILE__, + __LINE__, + "" + ); + + os << nl << msg.c_str() + << " in expression at position:" << long(pos) << nl + << "<<<<\n"; + + const auto begIter = content().cbegin(); + const auto endIter = content().cend(); + + size_t newline0 = 0, newline1 = 0; + + auto iter = begIter; + + for (/*nil*/; iter != endIter; ++iter) + { + char c(*iter); + + if ('\t' == c) + { + // Flatten tab to single space for better alignment + os << ' '; + } + else if ('\n' == c) + { + os << c; + + newline1 = (iter-begIter); + + if (newline1 < pos) + { + newline0 = newline1; + } + else + { + ++iter; + break; + } + } + else + { + os << c; + } + } + + if (newline0 == newline1 || newline1 == pos) + { + os << '\n'; + } + + size_t col = std::min(newline0, newline1); + if (col < pos) + { + col = pos - col; + if (col) --col; + + for (/*nil*/; col; --col) + { + os << ' '; + } + } + + os << "^^^^ near here\n"; + + // Finish output + for (/*nil*/; iter != endIter; ++iter) + { + char c(*iter); + + if ('\t' == c) + { + // Flatten tab to single space for better alignment + os << ' '; + } + else + { + os << c; + } + } + + os << "\n>>>>\n" + << exit(Foam::FatalIOError); +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H new file mode 100644 index 0000000000000000000000000000000000000000..b093178f165cd9d6751cadfab7e948c15ca43be1 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Class + Foam::parsing::genericRagelLemonDriver + +Description + Generic interface code for Ragel/Lemon combination + Subclasses should implement the process() method. + + The scanner will often be implemented as localized lexer class. + The parser may be embedded into the scanner as file-scope, or + use a separate interface class. + +SourceFiles + genericRagelLemonDriver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef genericRagelLemonDriver_H +#define genericRagelLemonDriver_H + +#include "error.H" +#include "className.H" +#include <functional> + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace parsing +{ + +/*---------------------------------------------------------------------------*\ + Class genericRagelLemonDriver Declaration +\*---------------------------------------------------------------------------*/ + +class genericRagelLemonDriver +{ +protected: + + // Protected Data + + //- Reference to the input string + std::reference_wrapper<const std::string> content_; + + //- The last known parser position + size_t position_; + + +public: + + // Public Typedefs + + //- Type for linear addressing within parse content + // Naming as per bison + typedef size_t location_type; + + + // Constructors + + //- Construct null + genericRagelLemonDriver(); + + //- Copy construct + genericRagelLemonDriver(const genericRagelLemonDriver& rhs) = default; + + //- Move construct + genericRagelLemonDriver(genericRagelLemonDriver&& rhs) = default; + + + //- Destructor + virtual ~genericRagelLemonDriver() = default; + + + // Member Functions + + //- Reset references + void clear() + { + content_ = std::cref<std::string>(string::null); + position_ = 0; + } + + //- Get reference to the input buffer content + const std::string& content() const + { + return content_.get(); + } + + //- Set reference to the input buffer content + void content(const std::string& s) + { + content_ = std::cref<std::string>(s); + position_ = 0; + } + + //- The last parse position + size_t parsePosition() const + { + return position_; + } + + //- The last parse position + size_t& parsePosition() + { + return position_; + } + + //- Output the input buffer string content + Ostream& printBuffer(Ostream& os) const; + + //- Report FatalError + void reportFatal(const std::string& msg) const; + + //- Report FatalError at parser position + void reportFatal(const std::string& msg, size_t pos) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace parsing +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/parsing/parsing.H b/src/OpenFOAM/primitives/strings/parsing/parsing.H index ee069c5d017636b2f14027bad075c5f98f65c487..cc25fb67bd7b922fa1b8e6f838cf7b2ec60a72d8 100644 --- a/src/OpenFOAM/primitives/strings/parsing/parsing.H +++ b/src/OpenFOAM/primitives/strings/parsing/parsing.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,6 +26,7 @@ Namespace Description Collection of static functions and data related to parsing + and an isolated namespace for lexers, parsers, scanners. SourceFiles parsing.C diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H index 6eb2499f9a6c951c61eac4ebf4880b679e402f55..516b00d0cf48ae594624cdbec01388a6b3b2e5f5 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H @@ -38,6 +38,7 @@ SourceFiles #ifndef stringOps_H #define stringOps_H +#include "scalar.H" #include "string.H" #include "SubStrings.H" #include "word.H" @@ -46,6 +47,8 @@ SourceFiles #include "stringOpsSort.H" #include "wordRes.H" +#include "evalStringToScalar.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/createCode b/src/OpenFOAM/primitives/strings/stringOps/toScalar/createCode new file mode 100755 index 0000000000000000000000000000000000000000..3be1331c8d92433d3876f5732c14928019251fe7 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/createCode @@ -0,0 +1,11 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory + +# Manually create ragel scanner and the lemon parser header + +"$WM_PROJECT_DIR/wmake/scripts/makeParser" \ + -scanner=evalStringToScalarScanner.rl \ + -parser=evalStringToScalarLemonParser.lyy \ + ; + +#------------------------------------------------------------------------------ diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H new file mode 100644 index 0000000000000000000000000000000000000000..2415a2248c6643031a1bb420eb0794b9383e57a9 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H @@ -0,0 +1,69 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Namespace + Foam::parsing::evalStringToScalar + +Description + Parsing encapsulation for stringOps::toScalar + +\*---------------------------------------------------------------------------*/ +#ifndef evalStringToScalar_H +#define evalStringToScalar_H + +#include "scalar.H" +#include "string.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace stringOps +{ + + //- A simple string to scalar evaluation that handles various basic + //- expressions. For trivial input, use readScalar instead (faster). + // + // The evaluation supports the following: + // - operations: - + * / + // - functions: exp, log, log10, pow, sqrt, cbrt, sqr, mag, magSqr + // - trigonometric: sin, cos, tan, asin, acos, atan, atan2, hypot + // - hyperbolic: sinh, cosh, tanh + // - conversions: degToRad, radToDeg + // - constants: pi() + // - misc: rand(), rand(seed) + // + // \note The rand() function returns a uniform scalar on [0-1] interval + scalar toScalar(const std::string& s); + +} // End namespace stringOps + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C new file mode 100644 index 0000000000000000000000000000000000000000..f6bbf9be44a7f89af92cc0b1013ffa3fac77454a --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C @@ -0,0 +1,72 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Description + Ragel lexer interface for lemon grammar of a simple string to + scalar evaluation + +\*---------------------------------------------------------------------------*/ + +#include "evalStringToScalar.H" +#include "evalStringToScalarDriver.H" +#include "evalStringToScalarScanner.H" +#include "error.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::parsing::evalStringToScalar::parseDriver::parseDriver() +: + genericRagelLemonDriver(), + value_(0) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::scalar Foam::parsing::evalStringToScalar::parseDriver::execute +( + const std::string& s +) +{ + // scanner::debug = 1; + + scanner().process(s, *this); + + return value_; +} + + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +Foam::scalar Foam::stringOps::toScalar(const std::string& s) +{ + Foam::parsing::evalStringToScalar::parseDriver driver; + + scalar val = driver.execute(s); + // val = driver.value(); + + return val; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H new file mode 100644 index 0000000000000000000000000000000000000000..58ed93e163195eab53752358bdbe24f6b5b954f0 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H @@ -0,0 +1,120 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Class + Foam::parsing::evalStringToScalar::parseDriver + +Description + Driver for stringOps::toScalar parsing + +SourceFiles + evalStringToScalarDriver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef evalStringToScalarDriver_H +#define evalStringToScalarDriver_H + +#include "scalar.H" +#include "className.H" +#include "genericRagelLemonDriver.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace parsing +{ +namespace evalStringToScalar +{ + +/*---------------------------------------------------------------------------*\ + Class parseDriver Declaration +\*---------------------------------------------------------------------------*/ + +class parseDriver +: + public genericRagelLemonDriver +{ +protected: + + // Protected Data + + //- The result + scalar value_; + + + // Protected Member Functions + + // No copy copy construct + parseDriver(const parseDriver&) = delete; + + // No copy assignment + void operator=(const parseDriver&) = delete; + + +public: + + ClassName("evalStringToScalar::driver"); + + // Constructors + + //- Construct null + parseDriver(); + + + //- Destructor + virtual ~parseDriver() = default; + + + // Member Functions + + // Perform parsing on string + scalar execute(const std::string& s); + + //- Get value + scalar value() const + { + return value_; + } + + //- Set value + void setValue(scalar val) + { + value_ = val; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace evalStringToScalar +} // End namespace parsing +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h new file mode 100644 index 0000000000000000000000000000000000000000..e068ad5c1d96e578de0a7c3945a30d8315bc11e0 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h @@ -0,0 +1,35 @@ +#define TOK_PLUS 1 +#define TOK_MINUS 2 +#define TOK_TIMES 3 +#define TOK_DIVIDE 4 +#define TOK_NEGATE 5 +#define TOK_NUMBER 6 +#define TOK_LPAREN 7 +#define TOK_RPAREN 8 +#define TOK_PI 9 +#define TOK_DEG_TO_RAD 10 +#define TOK_RAD_TO_DEG 11 +#define TOK_EXP 12 +#define TOK_LOG 13 +#define TOK_LOG10 14 +#define TOK_POW 15 +#define TOK_COMMA 16 +#define TOK_SQR 17 +#define TOK_SQRT 18 +#define TOK_CBRT 19 +#define TOK_SIN 20 +#define TOK_COS 21 +#define TOK_TAN 22 +#define TOK_ASIN 23 +#define TOK_ACOS 24 +#define TOK_ATAN 25 +#define TOK_ATAN2 26 +#define TOK_HYPOT 27 +#define TOK_SINH 28 +#define TOK_COSH 29 +#define TOK_TANH 30 +#define TOK_MIN 31 +#define TOK_MAX 32 +#define TOK_MAG 33 +#define TOK_MAGSQR 34 +#define TOK_RAND 35 diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy new file mode 100644 index 0000000000000000000000000000000000000000..2b89c8998639683b5bcb1566754c33dbed3a1fa8 --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy @@ -0,0 +1,290 @@ +%include { +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Description + Lemon grammar of a simple string to scalar evaluation. + + The generated parser is localized in an anonymous namespace. + Interface code wrapping is near the bottom of the file. + +\*---------------------------------------------------------------------------*/ + +#include "evalStringToScalarDriver.H" +#include "evalStringToScalarParser.H" +#include "unitConversion.H" +#include "Random.H" +#include "error.H" + +#pragma GCC diagnostic ignored "-Wold-style-cast" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wsign-compare" +} + +%namespace {} + +// Use extra argument for the return value +%extra_context { Foam::parsing::evalStringToScalar::parseDriver* driver } +%parse_failure { driver->reportFatal("Parse failure, giving up..."); } +%syntax_error { driver->reportFatal("Syntax error"); } + +%token_prefix TOK_ + +%token_type { Foam::scalar } + +%left PLUS MINUS. +%left TIMES DIVIDE. +%left NEGATE. + + +eval(lhs) ::= exp(a). +{ + lhs = a; + driver->setValue(lhs); +} + +exp(lhs) ::= NUMBER(a). +{ + lhs = a; +} + +exp(lhs) ::= MINUS exp(a). +{ + lhs = -a; +} + +exp(lhs) ::= exp(a) PLUS exp(b). +{ + lhs = a + b; +} + +exp(lhs) ::= exp(a) MINUS exp(b). +{ + lhs = a - b; +} + +exp(lhs) ::= exp(a) TIMES exp(b). +{ + lhs = a * b; +} + +exp(lhs) ::= exp(a) DIVIDE exp(b). +{ + lhs = a / b; +} + +exp(lhs) ::= LPAREN exp(a) RPAREN. +{ + lhs = a; +} + + +// Functions + +exp(lhs) ::= PI LPAREN RPAREN. +{ + lhs = Foam::constant::mathematical::pi; +} + +exp(lhs) ::= DEG_TO_RAD LPAREN RPAREN. +{ + lhs = Foam::degToRad(); +} + +exp(lhs) ::= RAD_TO_DEG LPAREN RPAREN. +{ + lhs = Foam::radToDeg(); +} + +exp(lhs) ::= DEG_TO_RAD LPAREN exp(a) RPAREN. +{ + lhs = Foam::degToRad(a); +} + +exp(lhs) ::= RAD_TO_DEG LPAREN exp(a) RPAREN. +{ + lhs = Foam::radToDeg(a); +} + +exp(lhs) ::= EXP LPAREN exp(a) RPAREN. +{ + lhs = Foam::exp(a); +} + +exp(lhs) ::= LOG LPAREN exp(a) RPAREN. +{ + lhs = Foam::log(a); +} + +exp(lhs) ::= LOG10 LPAREN exp(a) RPAREN. +{ + lhs = Foam::log10(a); +} + +exp(lhs) ::= POW LPAREN exp(a) COMMA exp(b) RPAREN. +{ + lhs = Foam::pow(a, b); +} + +exp(lhs) ::= SQR LPAREN exp(a) RPAREN. +{ + lhs = Foam::sqr(a); +} + +exp(lhs) ::= SQRT LPAREN exp(a) RPAREN. +{ + lhs = Foam::sqrt(a); +} + +exp(lhs) ::= CBRT LPAREN exp(a) RPAREN. +{ + lhs = Foam::cbrt(a); +} + +exp(lhs) ::= SIN LPAREN exp(a) RPAREN. +{ + lhs = Foam::sin(a); +} + +exp(lhs) ::= COS LPAREN exp(a) RPAREN. +{ + lhs = Foam::cos(a); +} + +exp(lhs) ::= TAN LPAREN exp(a) RPAREN. +{ + lhs = Foam::tan(a); +} + +exp(lhs) ::= ASIN LPAREN exp(a) RPAREN. +{ + lhs = Foam::asin(a); +} + +exp(lhs) ::= ACOS LPAREN exp(a) RPAREN. +{ + lhs = Foam::acos(a); +} + +exp(lhs) ::= ATAN LPAREN exp(a) RPAREN. +{ + lhs = Foam::atan(a); +} + +exp(lhs) ::= ATAN2 LPAREN exp(a) COMMA exp(b) RPAREN. +{ + lhs = Foam::atan2(a, b); +} + +exp(lhs) ::= HYPOT LPAREN exp(a) COMMA exp(b) RPAREN. +{ + lhs = Foam::hypot(a, b); +} + +exp(lhs) ::= SINH LPAREN exp(a) RPAREN. +{ + lhs = Foam::sinh(a); +} + +exp(lhs) ::= COSH LPAREN exp(a) RPAREN. +{ + lhs = Foam::cosh(a); +} + +exp(lhs) ::= TANH LPAREN exp(a) RPAREN. +{ + lhs = Foam::tanh(a); +} + +exp(lhs) ::= MIN LPAREN exp(a) COMMA exp(b) RPAREN. +{ + lhs = Foam::min(a, b); +} + +exp(lhs) ::= MAX LPAREN exp(a) COMMA exp(b) RPAREN. +{ + lhs = Foam::max(a, b); +} + +exp(lhs) ::= MAG LPAREN exp(a) RPAREN. +{ + lhs = Foam::mag(a); +} + +exp(lhs) ::= MAGSQR LPAREN exp(a) RPAREN. +{ + lhs = Foam::magSqr(a); +} + +exp(lhs) ::= RAND LPAREN RPAREN. +{ + lhs = Foam::Random().sample01<Foam::scalar>(); +} + +exp(lhs) ::= RAND LPAREN exp(seed) RPAREN. +{ + lhs = Foam::Random(seed).sample01<Foam::scalar>(); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +%code +{ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::parsing::evalStringToScalar::parser::stop() +{ + if (lemon_) + { + ParseFree(lemon_, ::operator delete); + lemon_ = nullptr; + } +} + + +void Foam::parsing::evalStringToScalar::parser::start(parseDriver& driver) +{ + this->stop(); + lemon_ = ParseAlloc(::operator new, &driver); +} + + +void Foam::parsing::evalStringToScalar::parser::parse +( + int tokenId, + Foam::scalar val /* The value for the token */ +) +{ + Parse(lemon_, tokenId, val); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // Code + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarParser.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarParser.H new file mode 100644 index 0000000000000000000000000000000000000000..a82a8791f1cc0e3fff3bfff68bfcf4f23d11b7ef --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarParser.H @@ -0,0 +1,96 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Class + Foam::parsing::evalStringToScalar::parser + +Description + Interface to lemon parser to simple string to scalar evaluation, which + is used by stringOps::toScalar + +\*---------------------------------------------------------------------------*/ + +#ifndef evalStringToScalarParser_H +#define evalStringToScalarParser_H + +namespace Foam +{ +namespace parsing +{ +namespace evalStringToScalar +{ + +// Forward Declarations +class parseDriver; + + +/*---------------------------------------------------------------------------*\ + Class parser Declaration +\*---------------------------------------------------------------------------*/ + +class parser +{ + // Private Data + + //- The lemon parser (demand-driven) + void* lemon_; + +public: + + // Constructors + + //- Construct null + parser() : lemon_(nullptr) {} + + + //- Destructor, delete lemon parser + ~parser() + { + stop(); + } + + + // Member Functions + + //- Start parsing, with given driver context + void start(parseDriver& driver); + + //- Stop parsing, freeing the allocated parser + void stop(); + + //- Push token/value to parser + void parse(int tokenId, Foam::scalar val); +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace evalStringToScalar +} // End namespace parsing +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H new file mode 100644 index 0000000000000000000000000000000000000000..84e4492f3380a3dca3ae748e12c56eb30a17e51b --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H @@ -0,0 +1,99 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Class + Foam::parsing::evalStringToScalar::scanner + +Description + Ragel lexer interface for lemon grammar of a simple string to + scalar evaluation, which is used by stringOps::toScalar + +Note + Ragel code generated with the ./createCode script. + +\*---------------------------------------------------------------------------*/ + +#ifndef evalStringToScalarScanner_H +#define evalStringToScalarScanner_H + +#include <string> + +namespace Foam +{ +namespace parsing +{ +namespace evalStringToScalar +{ + +// Forward Declarations +class parser; +class parseDriver; + +/*---------------------------------------------------------------------------*\ + Class scanner Declaration +\*---------------------------------------------------------------------------*/ + +class scanner +{ + // Private Data + + //- Wrapped lemon parser + parser* parser_; + + // Ragel code state, action + int cs, act; + +public: + + //- Debug/tracing of scan + static int debug; + + + // Constructors + + //- Construct null + scanner() : parser_(nullptr) {} + + + //- Destructor, deletes parser + ~scanner(); + + + // Member Functions + + //- Evaluate string + bool process(const std::string& str, parseDriver& driver); +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace evalStringToScalar +} // End namespace parsing +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc new file mode 100644 index 0000000000000000000000000000000000000000..4548dd8dd6534786e8fe9832edcc076c1f2d9bdf --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc @@ -0,0 +1,1426 @@ + +#line 1 "evalStringToScalarScanner.rl" +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Description + Ragel lexer interface for lemon grammar of a simple string to + scalar evaluation + +\*---------------------------------------------------------------------------*/ + +#include "evalStringToScalarScanner.H" +#include "evalStringToScalarDriver.H" +#include "evalStringToScalarLemonParser.h" +#include "evalStringToScalarParser.H" +#include "error.H" + +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#pragma GCC diagnostic ignored "-Wold-style-cast" + +#ifndef FULLDEBUG +#define NDEBUG +#endif + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::parsing::evalStringToScalar::scanner::debug = 0; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Ragel lexer with lemon parser integration + +// 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 + + +#line 61 "evalStringToScalarScanner.cc" +static const int evalScanner_start = 86; +static const int evalScanner_first_final = 86; +static const int evalScanner_error = 0; + +static const int evalScanner_en_main = 86; + + +#line 60 "evalStringToScalarScanner.rl" + + +#define TOKEN_OF(T) TOK_##T +#define EMIT_TOKEN(T) \ + /* Inform driver of last position */ \ + driver.parsePosition() = (p-buf); \ + DebugInfo<< "TOKEN_" #T << " at " << driver.parsePosition() << nl; \ + parser_->parse(TOKEN_OF(T), 0) + + + +#line 163 "evalStringToScalarScanner.rl" + + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::parsing::evalStringToScalar::scanner::~scanner() +{ + if (parser_) + { + delete parser_; + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +bool Foam::parsing::evalStringToScalar::scanner::process +( + const std::string& str, + parseDriver& driver +) +{ + if (!parser_) + { + parser_ = new parser(); + } + + driver.content(str); + parser_->start(driver); + + // 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[0]); + const char* eof = &(str[str.length()]); + const char* p = buf; + const char* pe = eof; + + // Initialize FSM variables + +#line 127 "evalStringToScalarScanner.cc" + { + cs = evalScanner_start; + ts = 0; + te = 0; + act = 0; + } + +#line 207 "evalStringToScalarScanner.rl" + /* ^^^ FSM initialization here ^^^ */; + + +#line 139 "evalStringToScalarScanner.cc" + { + if ( p == pe ) + goto _test_eof; + switch ( cs ) + { +tr2: +#line 86 "evalStringToScalarScanner.rl" + {{p = ((te))-1;}{ + // Inform driver of last position + driver.parsePosition() = (p-buf); + + DebugInfo + << "NUMBER:" << std::string(ts, te-ts).c_str() + << " at " << driver.parsePosition() << nl; + + scalar val; + + if (readScalar(std::string(ts, te-ts), val)) + { + // Emit number + parser_->parse(TOKEN_OF(NUMBER), val); + } + else + { + driver.reportFatal("Error reading scalar value"); + } + }} + goto st86; +tr5: +#line 157 "evalStringToScalarScanner.rl" + {{p = ((te))-1;}} + goto st86; +tr8: +#line 74 "evalStringToScalarScanner.rl" + { + // Inform driver of last position + driver.parsePosition() = (p-buf); + } +#line 159 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr14: +#line 127 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(ACOS); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr17: +#line 126 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(ASIN); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr21: +#line 128 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(ATAN); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr23: +#line 129 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(ATAN2); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr28: +#line 122 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(CBRT); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr31: +#line 124 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(COS); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr33: +#line 132 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(COSH); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr41: +#line 114 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(DEG_TO_RAD); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr44: +#line 116 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(EXP); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr49: +#line 130 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(HYPOT); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr53: +#line 117 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(LOG); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr56: +#line 118 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(LOG10); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr62: +#line 136 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(MAG); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr66: +#line 137 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(MAGSQR); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr67: +#line 135 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(MAX); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr69: +#line 134 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(MIN); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr72: +#line 113 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(PI); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr74: +#line 119 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(POW); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr83: +#line 115 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(RAD_TO_DEG); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr85: +#line 138 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(RAND); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr90: +#line 123 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(SIN); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr92: +#line 131 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(SINH); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr95: +#line 120 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(SQR); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr97: +#line 121 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(SQRT); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr101: +#line 125 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(TAN); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr103: +#line 133 "evalStringToScalarScanner.rl" + { p--; EMIT_TOKEN(TANH); } +#line 156 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr105: +#line 142 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(LPAREN); } +#line 157 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr106: +#line 143 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(RPAREN); } +#line 157 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr107: +#line 146 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(TIMES); } +#line 157 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr108: +#line 144 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(PLUS); } +#line 157 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr109: +#line 148 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(COMMA); } +#line 157 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr110: +#line 145 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(MINUS); } +#line 157 "evalStringToScalarScanner.rl" + {te = p+1;} + goto st86; +tr125: +#line 153 "evalStringToScalarScanner.rl" + {te = p;p--;} + goto st86; +tr126: +#line 86 "evalStringToScalarScanner.rl" + {te = p;p--;{ + // Inform driver of last position + driver.parsePosition() = (p-buf); + + DebugInfo + << "NUMBER:" << std::string(ts, te-ts).c_str() + << " at " << driver.parsePosition() << nl; + + scalar val; + + if (readScalar(std::string(ts, te-ts), val)) + { + // Emit number + parser_->parse(TOKEN_OF(NUMBER), val); + } + else + { + driver.reportFatal("Error reading scalar value"); + } + }} + goto st86; +tr128: +#line 157 "evalStringToScalarScanner.rl" + {te = p;p--;} + goto st86; +tr130: +#line 160 "evalStringToScalarScanner.rl" + {te = p;p--;} + goto st86; +st86: +#line 1 "NONE" + {ts = 0;} + if ( ++p == pe ) + goto _test_eof86; +case 86: +#line 1 "NONE" + {ts = p;} +#line 416 "evalStringToScalarScanner.cc" + switch( (*p) ) { + case 32: goto st87; + case 40: goto tr105; + case 41: goto tr106; + case 42: goto tr107; + case 43: goto tr108; + case 44: goto tr109; + case 45: goto tr110; + case 46: goto st1; + case 47: goto tr112; + case 97: goto st6; + case 99: goto st18; + case 100: goto st26; + case 101: goto st34; + case 104: goto st37; + case 108: goto st42; + case 109: goto st48; + case 112: goto st58; + case 114: goto st62; + case 115: goto st72; + case 116: goto st81; + } + if ( (*p) > 13 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr113; + } else if ( (*p) >= 9 ) + goto st87; + goto st0; +st0: +cs = 0; + goto _out; +st87: + if ( ++p == pe ) + goto _test_eof87; +case 87: + if ( (*p) == 32 ) + goto st87; + if ( 9 <= (*p) && (*p) <= 13 ) + goto st87; + goto tr125; +st1: + if ( ++p == pe ) + goto _test_eof1; +case 1: + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr0; + goto st0; +tr0: +#line 1 "NONE" + {te = p+1;} + goto st88; +st88: + if ( ++p == pe ) + goto _test_eof88; +case 88: +#line 472 "evalStringToScalarScanner.cc" + switch( (*p) ) { + case 69: goto st2; + case 101: goto st2; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr0; + goto tr126; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + switch( (*p) ) { + case 43: goto st3; + case 45: goto st3; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto st89; + goto tr2; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st89; + goto tr2; +st89: + if ( ++p == pe ) + goto _test_eof89; +case 89: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st89; + goto tr126; +tr112: +#line 1 "NONE" + {te = p+1;} +#line 147 "evalStringToScalarScanner.rl" + { EMIT_TOKEN(DIVIDE); } + goto st90; +st90: + if ( ++p == pe ) + goto _test_eof90; +case 90: +#line 515 "evalStringToScalarScanner.cc" + switch( (*p) ) { + case 42: goto st4; + case 47: goto st91; + } + goto tr128; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + if ( (*p) == 42 ) + goto st5; + goto st4; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + switch( (*p) ) { + case 42: goto st5; + case 47: goto tr8; + } + goto st4; +st91: + if ( ++p == pe ) + goto _test_eof91; +case 91: + if ( (*p) == 10 ) + goto tr131; + goto st91; +tr131: +#line 74 "evalStringToScalarScanner.rl" + { + // Inform driver of last position + driver.parsePosition() = (p-buf); + } + goto st92; +st92: + if ( ++p == pe ) + goto _test_eof92; +case 92: +#line 555 "evalStringToScalarScanner.cc" + if ( (*p) == 10 ) + goto tr131; + goto tr130; +tr113: +#line 1 "NONE" + {te = p+1;} + goto st93; +st93: + if ( ++p == pe ) + goto _test_eof93; +case 93: +#line 567 "evalStringToScalarScanner.cc" + switch( (*p) ) { + case 46: goto tr0; + case 69: goto st2; + case 101: goto st2; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr113; + goto tr126; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: + switch( (*p) ) { + case 99: goto st7; + case 115: goto st10; + case 116: goto st13; + } + goto st0; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) == 111 ) + goto st8; + goto st0; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + if ( (*p) == 115 ) + goto st9; + goto st0; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + switch( (*p) ) { + case 32: goto st9; + case 40: goto tr14; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st9; + goto st0; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + if ( (*p) == 105 ) + goto st11; + goto st0; +st11: + if ( ++p == pe ) + goto _test_eof11; +case 11: + if ( (*p) == 110 ) + goto st12; + goto st0; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + switch( (*p) ) { + case 32: goto st12; + case 40: goto tr17; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st12; + goto st0; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + if ( (*p) == 97 ) + goto st14; + goto st0; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: + if ( (*p) == 110 ) + goto st15; + goto st0; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + switch( (*p) ) { + case 32: goto st16; + case 40: goto tr21; + case 50: goto st17; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st16; + goto st0; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: + switch( (*p) ) { + case 32: goto st16; + case 40: goto tr21; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st16; + goto st0; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: + switch( (*p) ) { + case 32: goto st17; + case 40: goto tr23; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st17; + goto st0; +st18: + if ( ++p == pe ) + goto _test_eof18; +case 18: + switch( (*p) ) { + case 98: goto st19; + case 111: goto st22; + } + goto st0; +st19: + if ( ++p == pe ) + goto _test_eof19; +case 19: + if ( (*p) == 114 ) + goto st20; + goto st0; +st20: + if ( ++p == pe ) + goto _test_eof20; +case 20: + if ( (*p) == 116 ) + goto st21; + goto st0; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: + switch( (*p) ) { + case 32: goto st21; + case 40: goto tr28; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st21; + goto st0; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: + if ( (*p) == 115 ) + goto st23; + goto st0; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: + switch( (*p) ) { + case 32: goto st24; + case 40: goto tr31; + case 104: goto st25; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st24; + goto st0; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: + switch( (*p) ) { + case 32: goto st24; + case 40: goto tr31; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st24; + goto st0; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: + switch( (*p) ) { + case 32: goto st25; + case 40: goto tr33; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st25; + goto st0; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: + if ( (*p) == 101 ) + goto st27; + goto st0; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: + if ( (*p) == 103 ) + goto st28; + goto st0; +st28: + if ( ++p == pe ) + goto _test_eof28; +case 28: + if ( (*p) == 84 ) + goto st29; + goto st0; +st29: + if ( ++p == pe ) + goto _test_eof29; +case 29: + if ( (*p) == 111 ) + goto st30; + goto st0; +st30: + if ( ++p == pe ) + goto _test_eof30; +case 30: + if ( (*p) == 82 ) + goto st31; + goto st0; +st31: + if ( ++p == pe ) + goto _test_eof31; +case 31: + if ( (*p) == 97 ) + goto st32; + goto st0; +st32: + if ( ++p == pe ) + goto _test_eof32; +case 32: + if ( (*p) == 100 ) + goto st33; + goto st0; +st33: + if ( ++p == pe ) + goto _test_eof33; +case 33: + switch( (*p) ) { + case 32: goto st33; + case 40: goto tr41; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st33; + goto st0; +st34: + if ( ++p == pe ) + goto _test_eof34; +case 34: + if ( (*p) == 120 ) + goto st35; + goto st0; +st35: + if ( ++p == pe ) + goto _test_eof35; +case 35: + if ( (*p) == 112 ) + goto st36; + goto st0; +st36: + if ( ++p == pe ) + goto _test_eof36; +case 36: + switch( (*p) ) { + case 32: goto st36; + case 40: goto tr44; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st36; + goto st0; +st37: + if ( ++p == pe ) + goto _test_eof37; +case 37: + if ( (*p) == 121 ) + goto st38; + goto st0; +st38: + if ( ++p == pe ) + goto _test_eof38; +case 38: + if ( (*p) == 112 ) + goto st39; + goto st0; +st39: + if ( ++p == pe ) + goto _test_eof39; +case 39: + if ( (*p) == 111 ) + goto st40; + goto st0; +st40: + if ( ++p == pe ) + goto _test_eof40; +case 40: + if ( (*p) == 116 ) + goto st41; + goto st0; +st41: + if ( ++p == pe ) + goto _test_eof41; +case 41: + switch( (*p) ) { + case 32: goto st41; + case 40: goto tr49; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st41; + goto st0; +st42: + if ( ++p == pe ) + goto _test_eof42; +case 42: + if ( (*p) == 111 ) + goto st43; + goto st0; +st43: + if ( ++p == pe ) + goto _test_eof43; +case 43: + if ( (*p) == 103 ) + goto st44; + goto st0; +st44: + if ( ++p == pe ) + goto _test_eof44; +case 44: + switch( (*p) ) { + case 32: goto st45; + case 40: goto tr53; + case 49: goto st46; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st45; + goto st0; +st45: + if ( ++p == pe ) + goto _test_eof45; +case 45: + switch( (*p) ) { + case 32: goto st45; + case 40: goto tr53; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st45; + goto st0; +st46: + if ( ++p == pe ) + goto _test_eof46; +case 46: + if ( (*p) == 48 ) + goto st47; + goto st0; +st47: + if ( ++p == pe ) + goto _test_eof47; +case 47: + switch( (*p) ) { + case 32: goto st47; + case 40: goto tr56; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st47; + goto st0; +st48: + if ( ++p == pe ) + goto _test_eof48; +case 48: + switch( (*p) ) { + case 97: goto st49; + case 105: goto st56; + } + goto st0; +st49: + if ( ++p == pe ) + goto _test_eof49; +case 49: + switch( (*p) ) { + case 103: goto st50; + case 120: goto st55; + } + goto st0; +st50: + if ( ++p == pe ) + goto _test_eof50; +case 50: + switch( (*p) ) { + case 32: goto st51; + case 40: goto tr62; + case 83: goto st52; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st51; + goto st0; +st51: + if ( ++p == pe ) + goto _test_eof51; +case 51: + switch( (*p) ) { + case 32: goto st51; + case 40: goto tr62; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st51; + goto st0; +st52: + if ( ++p == pe ) + goto _test_eof52; +case 52: + if ( (*p) == 113 ) + goto st53; + goto st0; +st53: + if ( ++p == pe ) + goto _test_eof53; +case 53: + if ( (*p) == 114 ) + goto st54; + goto st0; +st54: + if ( ++p == pe ) + goto _test_eof54; +case 54: + switch( (*p) ) { + case 32: goto st54; + case 40: goto tr66; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st54; + goto st0; +st55: + if ( ++p == pe ) + goto _test_eof55; +case 55: + switch( (*p) ) { + case 32: goto st55; + case 40: goto tr67; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st55; + goto st0; +st56: + if ( ++p == pe ) + goto _test_eof56; +case 56: + if ( (*p) == 110 ) + goto st57; + goto st0; +st57: + if ( ++p == pe ) + goto _test_eof57; +case 57: + switch( (*p) ) { + case 32: goto st57; + case 40: goto tr69; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st57; + goto st0; +st58: + if ( ++p == pe ) + goto _test_eof58; +case 58: + switch( (*p) ) { + case 105: goto st59; + case 111: goto st60; + } + goto st0; +st59: + if ( ++p == pe ) + goto _test_eof59; +case 59: + switch( (*p) ) { + case 32: goto st59; + case 40: goto tr72; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st59; + goto st0; +st60: + if ( ++p == pe ) + goto _test_eof60; +case 60: + if ( (*p) == 119 ) + goto st61; + goto st0; +st61: + if ( ++p == pe ) + goto _test_eof61; +case 61: + switch( (*p) ) { + case 32: goto st61; + case 40: goto tr74; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st61; + goto st0; +st62: + if ( ++p == pe ) + goto _test_eof62; +case 62: + if ( (*p) == 97 ) + goto st63; + goto st0; +st63: + if ( ++p == pe ) + goto _test_eof63; +case 63: + switch( (*p) ) { + case 100: goto st64; + case 110: goto st70; + } + goto st0; +st64: + if ( ++p == pe ) + goto _test_eof64; +case 64: + if ( (*p) == 84 ) + goto st65; + goto st0; +st65: + if ( ++p == pe ) + goto _test_eof65; +case 65: + if ( (*p) == 111 ) + goto st66; + goto st0; +st66: + if ( ++p == pe ) + goto _test_eof66; +case 66: + if ( (*p) == 68 ) + goto st67; + goto st0; +st67: + if ( ++p == pe ) + goto _test_eof67; +case 67: + if ( (*p) == 101 ) + goto st68; + goto st0; +st68: + if ( ++p == pe ) + goto _test_eof68; +case 68: + if ( (*p) == 103 ) + goto st69; + goto st0; +st69: + if ( ++p == pe ) + goto _test_eof69; +case 69: + switch( (*p) ) { + case 32: goto st69; + case 40: goto tr83; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st69; + goto st0; +st70: + if ( ++p == pe ) + goto _test_eof70; +case 70: + if ( (*p) == 100 ) + goto st71; + goto st0; +st71: + if ( ++p == pe ) + goto _test_eof71; +case 71: + switch( (*p) ) { + case 32: goto st71; + case 40: goto tr85; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st71; + goto st0; +st72: + if ( ++p == pe ) + goto _test_eof72; +case 72: + switch( (*p) ) { + case 105: goto st73; + case 113: goto st77; + } + goto st0; +st73: + if ( ++p == pe ) + goto _test_eof73; +case 73: + if ( (*p) == 110 ) + goto st74; + goto st0; +st74: + if ( ++p == pe ) + goto _test_eof74; +case 74: + switch( (*p) ) { + case 32: goto st75; + case 40: goto tr90; + case 104: goto st76; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st75; + goto st0; +st75: + if ( ++p == pe ) + goto _test_eof75; +case 75: + switch( (*p) ) { + case 32: goto st75; + case 40: goto tr90; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st75; + goto st0; +st76: + if ( ++p == pe ) + goto _test_eof76; +case 76: + switch( (*p) ) { + case 32: goto st76; + case 40: goto tr92; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st76; + goto st0; +st77: + if ( ++p == pe ) + goto _test_eof77; +case 77: + if ( (*p) == 114 ) + goto st78; + goto st0; +st78: + if ( ++p == pe ) + goto _test_eof78; +case 78: + switch( (*p) ) { + case 32: goto st79; + case 40: goto tr95; + case 116: goto st80; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st79; + goto st0; +st79: + if ( ++p == pe ) + goto _test_eof79; +case 79: + switch( (*p) ) { + case 32: goto st79; + case 40: goto tr95; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st79; + goto st0; +st80: + if ( ++p == pe ) + goto _test_eof80; +case 80: + switch( (*p) ) { + case 32: goto st80; + case 40: goto tr97; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st80; + goto st0; +st81: + if ( ++p == pe ) + goto _test_eof81; +case 81: + if ( (*p) == 97 ) + goto st82; + goto st0; +st82: + if ( ++p == pe ) + goto _test_eof82; +case 82: + if ( (*p) == 110 ) + goto st83; + goto st0; +st83: + if ( ++p == pe ) + goto _test_eof83; +case 83: + switch( (*p) ) { + case 32: goto st84; + case 40: goto tr101; + case 104: goto st85; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st84; + goto st0; +st84: + if ( ++p == pe ) + goto _test_eof84; +case 84: + switch( (*p) ) { + case 32: goto st84; + case 40: goto tr101; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st84; + goto st0; +st85: + if ( ++p == pe ) + goto _test_eof85; +case 85: + switch( (*p) ) { + case 32: goto st85; + case 40: goto tr103; + } + if ( 9 <= (*p) && (*p) <= 13 ) + goto st85; + goto st0; + } + _test_eof86: cs = 86; goto _test_eof; + _test_eof87: cs = 87; goto _test_eof; + _test_eof1: cs = 1; goto _test_eof; + _test_eof88: cs = 88; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof89: cs = 89; goto _test_eof; + _test_eof90: cs = 90; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; 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_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; 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_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_eof: {} + if ( p == eof ) + { + switch ( cs ) { + case 87: goto tr125; + case 88: goto tr126; + case 2: goto tr2; + case 3: goto tr2; + case 89: goto tr126; + case 90: goto tr128; + case 4: goto tr5; + case 5: goto tr5; + case 91: goto tr130; + case 92: goto tr130; + case 93: goto tr126; + } + } + + _out: {} + } + +#line 209 "evalStringToScalarScanner.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, 0); + parser_->stop(); + + return true; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl new file mode 100644 index 0000000000000000000000000000000000000000..5f540dee34bdabbe69eff7d8c0934a630acc8abc --- /dev/null +++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl @@ -0,0 +1,229 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 <http://www.gnu.org/licenses/>. + +Description + Ragel lexer interface for lemon grammar of a simple string to + scalar evaluation + +\*---------------------------------------------------------------------------*/ + +#include "evalStringToScalarScanner.H" +#include "evalStringToScalarDriver.H" +#include "evalStringToScalarLemonParser.h" +#include "evalStringToScalarParser.H" +#include "error.H" + +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#pragma GCC diagnostic ignored "-Wold-style-cast" + +#ifndef FULLDEBUG +#define NDEBUG +#endif + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::parsing::evalStringToScalar::scanner::debug = 0; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Ragel lexer with lemon parser integration + +// 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 + +%%{ + machine evalScanner; + write data; +}%% + +#define TOKEN_OF(T) TOK_##T +#define EMIT_TOKEN(T) \ + /* Inform driver of last position */ \ + driver.parsePosition() = (p-buf); \ + DebugInfo<< "TOKEN_" #T << " at " << driver.parsePosition() << nl; \ + parser_->parse(TOKEN_OF(T), 0) + + +%%{ + machine evalScanner; + + action setPosition + { + // Inform driver of last position + driver.parsePosition() = (p-buf); + } + + action truncated + { + // Inform driver of last position + driver.parsePosition() = 0; + driver.reportFatal("Truncated input"); + } + + action emit_number { + // Inform driver of last position + driver.parsePosition() = (p-buf); + + DebugInfo + << "NUMBER:" << std::string(ts, te-ts).c_str() + << " at " << driver.parsePosition() << nl; + + scalar val; + + if (readScalar(std::string(ts, te-ts), val)) + { + // Emit number + parser_->parse(TOKEN_OF(NUMBER), val); + } + else + { + driver.reportFatal("Error reading scalar value"); + } + } + + decimal = ((digit* '.' digit+) | (digit+ '.'?)) ; + number = (digit+ | decimal) ([Ee][\-+]? digit+)? ; + dnl = (any* -- '\n') '\n'; # Discard up to and including newline + lfunc = space* '('; # Require functions to have '(' + + functions = ( + 'pi' lfunc @{ fhold; EMIT_TOKEN(PI); } + | 'degToRad' lfunc @{ fhold; EMIT_TOKEN(DEG_TO_RAD); } + | 'radToDeg' lfunc @{ fhold; EMIT_TOKEN(RAD_TO_DEG); } + | 'exp' lfunc @{ fhold; EMIT_TOKEN(EXP); } + | 'log' lfunc @{ fhold; EMIT_TOKEN(LOG); } + | 'log10' lfunc @{ fhold; EMIT_TOKEN(LOG10); } + | 'pow' lfunc @{ fhold; EMIT_TOKEN(POW); } + | 'sqr' lfunc @{ fhold; EMIT_TOKEN(SQR); } + | 'sqrt' lfunc @{ fhold; EMIT_TOKEN(SQRT); } + | 'cbrt' lfunc @{ fhold; EMIT_TOKEN(CBRT); } + | 'sin' lfunc @{ fhold; EMIT_TOKEN(SIN); } + | 'cos' lfunc @{ fhold; EMIT_TOKEN(COS); } + | 'tan' lfunc @{ fhold; EMIT_TOKEN(TAN); } + | 'asin' lfunc @{ fhold; EMIT_TOKEN(ASIN); } + | 'acos' lfunc @{ fhold; EMIT_TOKEN(ACOS); } + | 'atan' lfunc @{ fhold; EMIT_TOKEN(ATAN); } + | 'atan2' lfunc @{ fhold; EMIT_TOKEN(ATAN2); } + | 'hypot' lfunc @{ fhold; EMIT_TOKEN(HYPOT); } + | 'sinh' lfunc @{ fhold; EMIT_TOKEN(SINH); } + | 'cosh' lfunc @{ fhold; EMIT_TOKEN(COSH); } + | 'tanh' lfunc @{ fhold; EMIT_TOKEN(TANH); } + | 'min' lfunc @{ fhold; EMIT_TOKEN(MIN); } + | 'max' lfunc @{ fhold; EMIT_TOKEN(MAX); } + | 'mag' lfunc @{ fhold; EMIT_TOKEN(MAG); } + | 'magSqr' lfunc @{ fhold; EMIT_TOKEN(MAGSQR); } + | 'rand' lfunc @{ fhold; EMIT_TOKEN(RAND); } + ); + + operators = ( + '(' @{ EMIT_TOKEN(LPAREN); } + | ')' @{ EMIT_TOKEN(RPAREN); } + | '+' @{ EMIT_TOKEN(PLUS); } + | '-' @{ EMIT_TOKEN(MINUS); } + | '*' @{ EMIT_TOKEN(TIMES); } + | '/' @{ EMIT_TOKEN(DIVIDE); } + | ',' @{ EMIT_TOKEN(COMMA); } + ); + + + main := |* + space*; + + number => emit_number; + functions; + operators; + + '/*' any* :>> '*/' @setPosition; # Multi-line comment + '//' (any* -- '\n') '\n'* @setPosition; # (sloppy) 1-line comment + space*; + *|; +}%% + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::parsing::evalStringToScalar::scanner::~scanner() +{ + if (parser_) + { + delete parser_; + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +bool Foam::parsing::evalStringToScalar::scanner::process +( + const std::string& str, + parseDriver& driver +) +{ + if (!parser_) + { + parser_ = new parser(); + } + + driver.content(str); + parser_->start(driver); + + // 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[0]); + const char* eof = &(str[str.length()]); + 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, 0); + parser_->stop(); + + return true; +} + + +// ************************************************************************* //