253 lines
7.3 KiB
Plaintext
253 lines
7.3 KiB
Plaintext
/*-------------------------------------------------------------------------
|
|
compile with:
|
|
Coco \
|
|
-frames $WM_THIRD_PARTY_DIR/coco-r \
|
|
calcEntry.atg
|
|
-------------------------------------------------------------------------*/
|
|
|
|
#include "dictionary.H"
|
|
#include "scalar.H"
|
|
#include "error.H"
|
|
#include "wchar.H"
|
|
|
|
|
|
COMPILER calcEntry
|
|
$prefix=calcEntry
|
|
$namespace=Foam::functionEntries::calcEntryInternal
|
|
$eof=true // grammar handles eof itself
|
|
|
|
// Simple four function calculator for OpenFOAM dictionaries
|
|
|
|
//! with debug
|
|
static const int debug = 0;
|
|
|
|
//! The parent dictionary
|
|
mutable dictionary* dict_;
|
|
|
|
//! Track that parent dictionary was set
|
|
bool hasDict_;
|
|
|
|
//! The calculation result
|
|
scalar val;
|
|
|
|
|
|
//! token -> scalar
|
|
scalar getScalar() const
|
|
{
|
|
return coco_string_toDouble(t->val);
|
|
}
|
|
|
|
//! token -> string
|
|
std::string getString() const
|
|
{
|
|
char* str = coco_string_create_char(t->val);
|
|
std::string s(str);
|
|
coco_string_delete(str);
|
|
return s;
|
|
}
|
|
|
|
//! attach a dictionary
|
|
void dict(const dictionary& dict)
|
|
{
|
|
dict_ = const_cast<dictionary*>(&dict);
|
|
hasDict_ = true;
|
|
}
|
|
|
|
|
|
//! lookup dictionary entry
|
|
scalar getDictLookup() const
|
|
{
|
|
scalar dictValue = 0;
|
|
|
|
if (!hasDict_)
|
|
{
|
|
FatalErrorIn
|
|
(
|
|
"calcEntry::getDictEntry() const"
|
|
) << "No dictionary attached!"
|
|
<< exit(FatalError);
|
|
|
|
return 0;
|
|
}
|
|
|
|
char* chars = coco_string_create_char
|
|
(
|
|
t->val,
|
|
1,
|
|
(coco_string_length(t->val) - 1)
|
|
);
|
|
word keyword(chars);
|
|
coco_string_delete(chars);
|
|
|
|
if (debug)
|
|
{
|
|
Info<<"lookup: " << keyword << nl;
|
|
}
|
|
|
|
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
|
|
if (entryPtr && !entryPtr->isDict())
|
|
{
|
|
if (entryPtr->stream().size() != 1)
|
|
{
|
|
FatalErrorIn
|
|
(
|
|
"calcEntry::getDictEntry() const"
|
|
) << "keyword " << keyword << " has "
|
|
<< entryPtr->stream().size() << " values in dictionary "
|
|
<< exit(FatalError);
|
|
}
|
|
entryPtr->stream() >> dictValue;
|
|
}
|
|
else
|
|
{
|
|
FatalErrorIn
|
|
(
|
|
"calcEntry::getDictEntry() const"
|
|
) << "keyword " << keyword << " is undefined in dictionary "
|
|
<< exit(FatalError);
|
|
}
|
|
|
|
|
|
return dictValue;
|
|
}
|
|
|
|
scalar Result() const
|
|
{
|
|
return val;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
CHARACTERS
|
|
letter = 'A'..'Z' + 'a'..'z'.
|
|
qualifier = '_' + ':'.
|
|
dollar = '$'.
|
|
digit = "0123456789".
|
|
sign = '+' + '-'.
|
|
cr = '\r'.
|
|
lf = '\n'.
|
|
tab = '\t'.
|
|
stringCh = ANY - '"' - '\\' - cr - lf.
|
|
printable = '\u0020' .. '\u007e'.
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * TOKENS * * * * * * * * * * * * * * * * * //
|
|
|
|
TOKENS
|
|
|
|
// identifier
|
|
ident =
|
|
letter { letter | digit | qualifier }.
|
|
|
|
// string
|
|
string =
|
|
'"' { stringCh | '\\' printable } '"'.
|
|
|
|
// dictionary lookup identifier
|
|
// starts with '$' and otherwise limited to a normal indentifier
|
|
variable =
|
|
dollar letter { letter | digit | qualifier }.
|
|
|
|
// floating point and integer numbers
|
|
number =
|
|
[sign] ('.' digit { digit } ) | ( digit { digit } [ '.' { digit } ])
|
|
[ ('E' | 'e') [sign] digit { digit } ].
|
|
|
|
|
|
// * * * * * * * * * * * PRAGMAS / COMMENTS / IGNORE * * * * * * * * * * * //
|
|
|
|
COMMENTS FROM "/*" TO "*/" NESTED
|
|
COMMENTS FROM "//" TO lf
|
|
|
|
IGNORE cr + lf + tab
|
|
|
|
|
|
// * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * //
|
|
|
|
PRODUCTIONS
|
|
|
|
calcEntry (. val = 0;
|
|
if (debug){Info<<"start val pos:"<< t->pos << nl;}
|
|
.)
|
|
=
|
|
'{' Expr<val> '}' (.
|
|
if (debug){
|
|
Info<<"end {} at pos:"<< t->pos
|
|
<<" val:"<< t->val
|
|
<<" len:"<< coco_string_length(t->val)
|
|
<<" la pos:"<< la->pos << nl;
|
|
}
|
|
// reposition to immediately after the closing '}'
|
|
scanner->buffer->SetPos
|
|
(
|
|
t->pos + coco_string_length(t->val)
|
|
);
|
|
.)
|
|
| ( Expr<val> EOF )
|
|
.
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
Expr<scalar& val> (. scalar val2 = 0;
|
|
if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
=
|
|
Term<val>
|
|
{
|
|
"+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
|
|
val += val2;
|
|
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
| "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
|
|
val -= val2;
|
|
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
}
|
|
.
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
Term<scalar& val> (. scalar val2 = 0;
|
|
if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
=
|
|
Factor<val>
|
|
{
|
|
"*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
|
|
val *= val2;
|
|
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
| "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
|
|
val /= val2;
|
|
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
}
|
|
.
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
Factor<scalar& val>
|
|
=
|
|
variable (. val = getDictLookup();
|
|
if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
| number (. val = getScalar();
|
|
if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
| '-' '(' Expr<val> ')' (. val = -val;
|
|
if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
|
|
.)
|
|
.
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
END calcEntry.
|
|
|
|
// ************************************************************************* //
|