mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add stringOps::toScalar and dictionary #eval directive
- the #eval directive is similar to the #calc directive, but for evaluating
string expressions into scalar values. It uses an internal parser for
the evaluation instead of dynamic code compilation. This can make it
more suitable for 'quick' evaluations.
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)
This commit is contained in:
committed by
Andrew Heather
parent
bd9992d0d5
commit
836d3a849f
@ -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
|
||||
|
||||
163
src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.C
Normal file
163
src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.C
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
101
src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.H
Normal file
101
src/OpenFOAM/db/dictionary/functionEntries/evalEntry/evalEntry.H
Normal file
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
11
src/OpenFOAM/primitives/strings/stringOps/toScalar/createCode
Executable file
11
src/OpenFOAM/primitives/strings/stringOps/toScalar/createCode
Executable file
@ -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 \
|
||||
;
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user