diff --git a/applications/test/dictionary/Make/files b/applications/test/dictionary/Make/files index 148f5fb1c9..ff7a3caad4 100644 --- a/applications/test/dictionary/Make/files +++ b/applications/test/dictionary/Make/files @@ -1,6 +1,7 @@ dictionaryTest.C calcEntry/calcEntry.C +calcEntry/calcEntryInternal.C calcEntry/calcEntryParser.cpp calcEntry/calcEntryScanner.cpp diff --git a/applications/test/dictionary/calcEntry/addToStaticMemberFunctionSelectionTable.H b/applications/test/dictionary/calcEntry/addToStaticMemberFunctionSelectionTable.H new file mode 100644 index 0000000000..572f93ae23 --- /dev/null +++ b/applications/test/dictionary/calcEntry/addToStaticMemberFunctionSelectionTable.H @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +@file Foam::addToStaticMemberFunctionSelectionTable + +Description + Macros for easy insertion into member function selection tables + +\*---------------------------------------------------------------------------*/ + +#ifndef addToStaticMemberFunctionSelectionTable_H +#define addToStaticMemberFunctionSelectionTable_H + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +// add to hash-table of functions with 'lookup' as the key +#define addNamedToStaticMemberFunctionSelectionTable\ +(baseType,thisType,memberFunction,argNames,lookup,functionPtr) \ + \ + /* Add the thisType memberFunction to the table, find by lookup name */ \ + baseType::add##memberFunction##argNames##StaticMemberFunctionToTable \ + add_##lookup##_##thisType##memberFunction##argNames##StaticMemberFunctionTo##baseType##Table_\ + (#lookup, functionPtr) + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif + +// ************************************************************************* // diff --git a/applications/test/dictionary/calcEntry/calcEntry.C b/applications/test/dictionary/calcEntry/calcEntry.C index 9810812308..7e634bc8b4 100644 --- a/applications/test/dictionary/calcEntry/calcEntry.C +++ b/applications/test/dictionary/calcEntry/calcEntry.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2009-2010 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/applications/test/dictionary/calcEntry/calcEntry.H b/applications/test/dictionary/calcEntry/calcEntry.H index 027c4b510b..3db7562161 100644 --- a/applications/test/dictionary/calcEntry/calcEntry.H +++ b/applications/test/dictionary/calcEntry/calcEntry.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2009-2010 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License diff --git a/applications/test/dictionary/calcEntry/calcEntry.atg b/applications/test/dictionary/calcEntry/calcEntry.atg index 90c0861143..57646c3cad 100644 --- a/applications/test/dictionary/calcEntry/calcEntry.atg +++ b/applications/test/dictionary/calcEntry/calcEntry.atg @@ -1,65 +1,72 @@ -/*------------------------------------------------------------------------- +/*---------------------------------*- C++ -*---------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2009-2010 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +@file calcEntry.atg + +Description + An attributed Coco/R grammar to parse simple arithmetic expressions + +SourceFiles + generated + +\*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*\ compile with: Coco \ -frames $WM_THIRD_PARTY_DIR/coco-r \ calcEntry.atg --------------------------------------------------------------------------*/ +\*---------------------------------------------------------------------------*/ #include "dictionary.H" #include "scalar.H" #include "error.H" #include "wchar.H" +#include "DynamicList.H" +#include "calcEntryInternal.H" COMPILER calcEntry -$prefix=calcEntry -$namespace=Foam::functionEntries::calcEntryInternal -$eof=true // grammar handles eof itself + // grammar pragmas: + $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 +private: + //- The parent dictionary mutable dictionary* dict_; - //! Track that parent dictionary was set - bool hasDict_; - - //! The calculation result + //- 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(&dict); - hasDict_ = true; - } - - - //! lookup dictionary entry + //- lookup dictionary entry scalar getDictLookup() const { scalar dictValue = 0; - if (!hasDict_) + if (!dict_) { FatalErrorIn ( @@ -70,19 +77,14 @@ $eof=true // grammar handles eof itself return 0; } - char* chars = coco_string_create_char + char* str = 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; - } + word keyword(str); + coco_string_delete(str); entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false); if (entryPtr && !entryPtr->isDict()) @@ -107,23 +109,35 @@ $eof=true // grammar handles eof itself << exit(FatalError); } - return dictValue; } + +public: + + //- attach a dictionary + void dict(const dictionary& dict) + { + dict_ = const_cast(&dict); + } + + //- Return the calculated result scalar Result() const { return val; } +INITIALIZE + dict_ = 0; + val = 0; + /*---------------------------------------------------------------------------*/ CHARACTERS - letter = 'A'..'Z' + 'a'..'z'. - qualifier = '_' + ':'. - dollar = '$'. + letter = 'A'..'Z' + 'a'..'z' + '_'. digit = "0123456789". + alphanum = letter + digit. sign = '+' + '-'. cr = '\r'. lf = '\n'. @@ -138,16 +152,16 @@ TOKENS // identifier ident = - letter { letter | digit | qualifier }. + letter { alphanum }. // string string = '"' { stringCh | '\\' printable } '"'. // dictionary lookup identifier -// starts with '$' and otherwise limited to a normal indentifier +// starts with '$' and otherwise limited to a normal identifier variable = - dollar letter { letter | digit | qualifier }. + '$' letter { alphanum }. // floating point and integer numbers number = @@ -167,63 +181,35 @@ IGNORE cr + lf + tab PRODUCTIONS -calcEntry (. val = 0; - if (debug){Info<<"start val pos:"<< t->pos << nl;} - .) +calcEntry (. val = 0; .) = - '{' Expr '}' (. - 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 '}' (. // reposition to immediately after the closing '}' + scanner->buffer->SetPos(t->pos + 1); .) - | ( Expr EOF ) + | ( Expr EOF ) . /*---------------------------------------------------------------------------*/ -Expr (. scalar val2 = 0; - if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;} - .) +Expr (. scalar val2 = 0; .) = Term { - "+" Term (. if (debug) {Info<<"+Term:"<pos << nl;} - val += val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - .) - | "-" Term (. if (debug) {Info<<"-Term:"<pos << nl;} - val -= val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - .) + "+" Term (. val += val2; .) + | "-" Term (. val -= val2; .) } . /*---------------------------------------------------------------------------*/ -Term (. scalar val2 = 0; - if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;} - .) +Term (. scalar val2 = 0; .) = Factor { - "*" Factor (. if (debug) {Info<<"*Factor:"<pos << nl;} - val *= val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - .) - | "/" Factor (. if (debug) {Info<<"/Factor:"<pos << nl;} - val /= val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - .) + "*" Factor (. val *= val2; .) + | "/" Factor (. val /= val2; .) } . @@ -231,17 +217,32 @@ Term (. scalar val2 = 0; /*---------------------------------------------------------------------------*/ Factor = - variable (. val = getDictLookup(); - if (debug) {Info<<"lookup:"<pos << nl;} - .) - | number (. val = getScalar(); - if (debug) {Info<<"got num:"<pos << nl;} - .) - | '-' '(' Expr ')' (. val = -val; - if (debug) {Info<<"inv:"<pos << nl;} - .) - | '(' Expr ')' (. if (debug){Info<<"got Expr:"<pos << nl;} + Func + | variable (. val = getDictLookup(); .) + | number (. val = coco_string_toDouble(t->val); .) + | '-' '(' Expr ')' (. val = -val; .) + | '(' Expr ')' +. + + +/*---------------------------------------------------------------------------*/ + +// functions like sin(x) or pow(x, y) etc. +Func += + ident (. + char* str = coco_string_create_char(t->val); + word funcName(str); + coco_string_delete(str); + DynamicList param(4); // hold parameter values .) + '(' + [ (. scalar x; .) + Expr (. param.append(x); .) + { ',' Expr (. param.append(x); .) + } + ] + ')' (. val = scalarFunctions::dispatch(funcName, param); .) . diff --git a/applications/test/dictionary/calcEntry/calcEntryInternal.C b/applications/test/dictionary/calcEntry/calcEntryInternal.C new file mode 100644 index 0000000000..888475cee6 --- /dev/null +++ b/applications/test/dictionary/calcEntry/calcEntryInternal.C @@ -0,0 +1,182 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "calcEntryInternal.H" +#include "addToMemberFunctionSelectionTable.H" +#include "addToStaticMemberFunctionSelectionTable.H" +#include "unitConversion.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionEntries +{ +namespace calcEntryInternal +{ + +defineStaticMemberFunctionSelectionTable(scalarFunctions,dispatch,ParamList); + + +scalar scalarFunctions::dispatch +( + const word& name, + const UList& param +) +{ + // create lookup name with parameter count + const word lookupName = name + '_' + Foam::name(param.size()); + + dispatchParamListMemberFunctionTable::iterator mfIter = + dispatchParamListMemberFunctionTablePtr_->find(lookupName); + + if (mfIter == dispatchParamListMemberFunctionTablePtr_->end()) + { + FatalErrorIn + ( + "calcEntryInternal::scalarFunctions::dispatch" + "(const word&, const UList&) : " + ) << "Unknown function " << name << nl << nl + << "Valid types are :" << endl + << dispatchParamListMemberFunctionTablePtr_->sortedToc() + << exit(FatalError); + } + + return mfIter()(param); +} + + +scalar scalarFunctions::pi_0(const UList& param) +{ + return constant::mathematical::pi; +} + +scalar scalarFunctions::degToRad_1(const UList& param) +{ + return degToRad(param[0]); +} + +scalar scalarFunctions::radToDeg_1(const UList& param) +{ + return radToDeg(param[0]); +} + +scalar scalarFunctions::sin_1(const UList& param) +{ + return Foam::sin(param[0]); +} + +scalar scalarFunctions::cos_1(const UList& param) +{ + return Foam::cos(param[0]); +} + +scalar scalarFunctions::pow_2(const UList& param) +{ + return Foam::pow(param[0], param[1]); +} + +scalar scalarFunctions::log_1(const UList& param) +{ + return Foam::log(param[0]); +} + +scalar scalarFunctions::log10_1(const UList& param) +{ + return Foam::log10(param[0]); +} + + + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + pi_0, + &scalarFunctions::pi_0 +); + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + degToRad_1, + &scalarFunctions::degToRad_1 +); + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + radToDeg_1, + &scalarFunctions::radToDeg_1 +); + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + sin_1, + &scalarFunctions::sin_1 +); + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + cos_1, + &scalarFunctions::cos_1 +); + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + pow_2, + &scalarFunctions::pow_2 +); + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + log_1, + &scalarFunctions::log_1 +); + + + +addNamedToStaticMemberFunctionSelectionTable +( + scalarFunctions,scalarFunctions,dispatch,ParamList, + log10_1, + &scalarFunctions::log10_1 +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace calcEntryInternal +} // End namespace functionEntries +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +// ************************************************************************* // diff --git a/applications/test/dictionary/calcEntry/calcEntryInternal.H b/applications/test/dictionary/calcEntry/calcEntryInternal.H new file mode 100644 index 0000000000..73ff08c7e4 --- /dev/null +++ b/applications/test/dictionary/calcEntry/calcEntryInternal.H @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Namespace + Foam::functionEntries::calcEntryInternal + +Description + This dictionary function entry may or may not do anything particularly + useful - depending upon what is currently being used to test. + +SourceFiles + calcEntryInternal.C + +\*---------------------------------------------------------------------------*/ + +#ifndef calcEntryInternal_H +#define calcEntryInternal_H + +#include "functionEntry.H" +#include "memberFunctionSelectionTables.H" +#include "staticMemberFunctionSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionEntries +{ +namespace calcEntryInternal +{ + +/*---------------------------------------------------------------------------*\ + Class calcEntryFunctions Declaration +\*---------------------------------------------------------------------------*/ + +class scalarFunctions +{ +public: + + // Member Function Selectors + + declareStaticMemberFunctionSelectionTable + ( + scalar, + scalarFunctions, + dispatch, + ParamList, + ( + const UList& param + ), + (param) + ); + + //- Calculate + static scalar dispatch(const word&, const UList&); + + + static scalar pi_0(const UList&); + static scalar degToRad_1(const UList&); + static scalar radToDeg_1(const UList&); + static scalar cos_1(const UList&); + static scalar sin_1(const UList&); + static scalar pow_2(const UList&); + static scalar log_1(const UList&); + static scalar log10_1(const UList&); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace calcEntryInternal +} // End namespace functionEntries +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/test/dictionary/calcEntry/calcEntryParser.cpp b/applications/test/dictionary/calcEntry/calcEntryParser.cpp index 1ff95b8ac9..4fc4016207 100644 --- a/applications/test/dictionary/calcEntry/calcEntryParser.cpp +++ b/applications/test/dictionary/calcEntry/calcEntryParser.cpp @@ -91,105 +91,93 @@ bool Parser::WeakSeparator(int n, int syFol, int repFol) { void Parser::calcEntry() { - val = 0; - if (debug){Info<<"start val pos:"<< t->pos << nl;} - + val = 0; if (la->kind == 5) { Get(); Expr(val); Expect(6); - 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) - ); + scanner->buffer->SetPos(t->pos + 1); } else if (StartOf(1)) { Expr(val); Expect(0); - } else SynErr(14); + } else SynErr(15); } void Parser::Expr(scalar& val) { - scalar val2 = 0; - if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;} - + scalar val2 = 0; Term(val); while (la->kind == 7 || la->kind == 8) { if (la->kind == 7) { Get(); Term(val2); - if (debug) {Info<<"+Term:"<pos << nl;} - val += val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - + val += val2; } else { Get(); Term(val2); - if (debug) {Info<<"-Term:"<pos << nl;} - val -= val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - + val -= val2; } } } void Parser::Term(scalar& val) { - scalar val2 = 0; - if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;} - + scalar val2 = 0; Factor(val); while (la->kind == 9 || la->kind == 10) { if (la->kind == 9) { Get(); Factor(val2); - if (debug) {Info<<"*Factor:"<pos << nl;} - val *= val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - + val *= val2; } else { Get(); Factor(val2); - if (debug) {Info<<"/Factor:"<pos << nl;} - val /= val2; - if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} - + val /= val2; } } } void Parser::Factor(scalar& val) { - if (la->kind == 3) { + if (la->kind == 1) { + Func(val); + } else if (la->kind == 3) { Get(); - val = getDictLookup(); - if (debug) {Info<<"lookup:"<pos << nl;} - + val = getDictLookup(); } else if (la->kind == 4) { Get(); - val = getScalar(); - if (debug) {Info<<"got num:"<pos << nl;} - + val = coco_string_toDouble(t->val); } else if (la->kind == 8) { Get(); Expect(11); Expr(val); Expect(12); - val = -val; - if (debug) {Info<<"inv:"<pos << nl;} - + val = -val; } else if (la->kind == 11) { Get(); Expr(val); Expect(12); - if (debug){Info<<"got Expr:"<pos << nl;} - - } else SynErr(15); + } else SynErr(16); +} + +void Parser::Func(scalar& val) { + Expect(1); + char* str = coco_string_create_char(t->val); + word funcName(str); + coco_string_delete(str); + DynamicList param(4); // hold parameter values + + Expect(11); + if (StartOf(1)) { + scalar x; + Expr(x); + param.append(x); + while (la->kind == 13) { + Get(); + Expr(x); + param.append(x); + } + } + Expect(12); + val = scalarFunctions::dispatch(funcName, param); } @@ -218,10 +206,16 @@ Parser::Parser(Scanner* scan, Errors* err) t(NULL), la(NULL) { - if (!errors) { // add in default error handling errors = new Errors(); } + // user-defined initialization: +dict_ = 0; + val = 0; + +/*---------------------------------------------------------------------------*/ + + } @@ -229,9 +223,9 @@ bool Parser::StartOf(int s) { const bool T = true; const bool x = false; - static bool set[2][15] = { - {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x}, - {x,x,x,T, T,x,x,x, T,x,x,T, x,x,x} + static const bool set[2][16] = { + {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, + {x,T,x,T, T,x,x,x, T,x,x,T, x,x,x,x} }; @@ -245,6 +239,8 @@ Parser::~Parser() { delete errors; } delete dummyToken; + // user-defined destruction: + } @@ -284,9 +280,10 @@ wchar_t* Errors::strerror(int n) case 10: s = coco_string_create(L"\"/\" expected"); break; case 11: s = coco_string_create(L"\"(\" expected"); break; case 12: s = coco_string_create(L"\")\" expected"); break; - case 13: s = coco_string_create(L"??? expected"); break; - case 14: s = coco_string_create(L"invalid calcEntry"); break; - case 15: s = coco_string_create(L"invalid Factor"); break; + case 13: s = coco_string_create(L"\",\" expected"); break; + case 14: s = coco_string_create(L"??? expected"); break; + case 15: s = coco_string_create(L"invalid calcEntry"); break; + case 16: s = coco_string_create(L"invalid Factor"); break; default: { diff --git a/applications/test/dictionary/calcEntry/calcEntryParser.h b/applications/test/dictionary/calcEntry/calcEntryParser.h index de12a3961e..afa25782a7 100644 --- a/applications/test/dictionary/calcEntry/calcEntryParser.h +++ b/applications/test/dictionary/calcEntry/calcEntryParser.h @@ -7,6 +7,8 @@ #include "scalar.H" #include "error.H" #include "wchar.H" +#include "DynamicList.H" +#include "calcEntryInternal.H" #include "calcEntryScanner.h" @@ -55,7 +57,7 @@ private: _variable=3, _number=4, }; - static const int maxT = 13; + static const int maxT = 14; static const int minErrDist = 2; //!< min. distance before reporting errors @@ -77,47 +79,19 @@ public: Token *t; //!< last recognized token Token *la; //!< lookahead token -static const int debug = 0; - - //! The parent dictionary +private: + //- The parent dictionary mutable dictionary* dict_; - //! Track that parent dictionary was set - bool hasDict_; - - //! The calculation result + //- 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(&dict); - hasDict_ = true; - } - - - //! lookup dictionary entry + //- lookup dictionary entry scalar getDictLookup() const { scalar dictValue = 0; - if (!hasDict_) + if (!dict_) { FatalErrorIn ( @@ -128,19 +102,14 @@ static const int debug = 0; return 0; } - char* chars = coco_string_create_char + char* str = 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; - } + word keyword(str); + coco_string_delete(str); entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false); if (entryPtr && !entryPtr->isDict()) @@ -165,18 +134,25 @@ static const int debug = 0; << exit(FatalError); } - return dictValue; } + +public: + + //- attach a dictionary + void dict(const dictionary& dict) + { + dict_ = const_cast(&dict); + } + + //- Return the calculated result scalar Result() const { return val; } -/*---------------------------------------------------------------------------*/ - //! Construct for the specified scanner @@ -185,13 +161,14 @@ static const int debug = 0; * handler, which will not be deleted upon destruction. */ Parser(Scanner* scan, Errors* err = 0); - ~Parser(); //!< Destructor - cleanup errors and dummyToken + ~Parser(); void SemErr(const wchar_t* msg); //!< Handle semantic error void calcEntry(); void Expr(scalar& val); void Term(scalar& val); void Factor(scalar& val); + void Func(scalar& val); void Parse(); //!< Execute the parse operation diff --git a/applications/test/dictionary/calcEntry/calcEntryScanner.cpp b/applications/test/dictionary/calcEntry/calcEntryScanner.cpp index b070bcf3f3..f475323086 100644 --- a/applications/test/dictionary/calcEntry/calcEntryScanner.cpp +++ b/applications/test/dictionary/calcEntry/calcEntryScanner.cpp @@ -21,7 +21,7 @@ namespace calcEntryInternal { // string handling, wide character wchar_t* coco_string_create(const wchar_t* str) { - int len = coco_string_length(str); + const int len = coco_string_length(str); wchar_t* dest = new wchar_t[len + 1]; if (len) { wcsncpy(dest, str, len); @@ -31,10 +31,7 @@ wchar_t* coco_string_create(const wchar_t* str) { } wchar_t* coco_string_create(const wchar_t* str, int index, int length) { - int len = coco_string_length(str); - if (len) { - len = length; - } + const int len = (str && *str) ? length : 0; wchar_t* dest = new wchar_t[len + 1]; if (len) { wcsncpy(dest, &(str[index]), len); @@ -69,8 +66,8 @@ wchar_t* coco_string_create_lower(const wchar_t* str, int index, int len) { wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t* str2) { - int str1Len = coco_string_length(str1); - int str2Len = coco_string_length(str2); + const int str1Len = coco_string_length(str1); + const int str2Len = coco_string_length(str2); wchar_t* dest = new wchar_t[str1Len + str2Len + 1]; @@ -82,7 +79,7 @@ wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t* str2) { } wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t ch) { - int len = coco_string_length(str1); + const int len = coco_string_length(str1); wchar_t* dest = new wchar_t[len + 2]; wcsncpy(dest, str1, len); // or use if (len) { wcscpy(dest, str1); } dest[len] = ch; @@ -100,8 +97,8 @@ int coco_string_length(const wchar_t* str) { } bool coco_string_endswith(const wchar_t* str, const wchar_t* endstr) { - int strLen = wcslen(str); - int endLen = wcslen(endstr); + const int strLen = wcslen(str); + const int endLen = wcslen(endstr); return (endLen <= strLen) && (wcscmp(str + strLen - endLen, endstr) == 0); } @@ -159,7 +156,7 @@ float coco_string_toFloat(const wchar_t* str) // wchar_t* coco_string_create(const char* str) { - int len = str ? strlen(str) : 0; + const int len = str ? strlen(str) : 0; wchar_t* dest = new wchar_t[len + 1]; for (int i = 0; i < len; ++i) { dest[i] = wchar_t(str[i]); @@ -169,7 +166,7 @@ wchar_t* coco_string_create(const char* str) { } wchar_t* coco_string_create(const char* str, int index, int length) { - int len = str ? length : 0; + const int len = str ? length : 0; wchar_t* dest = new wchar_t[len + 1]; for (int i = 0; i < len; ++i) { dest[i] = wchar_t(str[index + i]); @@ -180,8 +177,8 @@ wchar_t* coco_string_create(const char* str, int index, int length) { char* coco_string_create_char(const wchar_t* str) { - int len = coco_string_length(str); - char *dest = new char[len + 1]; + const int len = coco_string_length(str); + char* dest = new char[len + 1]; for (int i = 0; i < len; ++i) { dest[i] = char(str[i]); @@ -191,11 +188,8 @@ char* coco_string_create_char(const wchar_t* str) { } char* coco_string_create_char(const wchar_t* str, int index, int length) { - int len = coco_string_length(str); - if (len) { - len = length; - } - char *dest = new char[len + 1]; + const int len = (str && *str) ? length : 0; + char* dest = new char[len + 1]; for (int i = 0; i < len; ++i) { dest[i] = char(str[index + i]); } @@ -589,25 +583,29 @@ Scanner::~Scanner() { void Scanner::Init() { for (int i = 65; i <= 90; ++i) start.set(i, 1); + for (int i = 95; i <= 95; ++i) start.set(i, 1); for (int i = 97; i <= 122; ++i) start.set(i, 1); - for (int i = 36; i <= 36; ++i) start.set(i, 5); - start.set(45, 20); + start.set(45, 21); for (int i = 48; i <= 57; ++i) start.set(i, 9); start.set(34, 2); + start.set(36, 5); start.set(46, 7); start.set(123, 14); start.set(125, 15); - start.set(43, 21); + start.set(43, 22); start.set(42, 16); start.set(47, 17); start.set(40, 18); start.set(41, 19); + start.set(44, 20); start.set(Buffer::EoF, -1); tvalLength = 128; tval = new wchar_t[tvalLength]; // text of current token + tlen = 0; + tval[tlen] = 0; // HEAP_BLOCK_SIZE byte heap + pointer to next heap block heap = malloc(HEAP_BLOCK_SIZE + sizeof(void*)); @@ -813,7 +811,7 @@ Token* Scanner::NextToken() { case 0: { t->kind = noSym; break; } // NextCh already done case 1: case_1: - if ((ch >= L'0' && ch <= L':') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_1;} + if ((ch >= L'0' && ch <= L'9') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_1;} else {t->kind = 1; break;} case 2: case_2: @@ -829,11 +827,11 @@ Token* Scanner::NextToken() { case_4: {t->kind = 2; break;} case 5: - if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;} + if ((ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;} else {t->kind = noSym; break;} case 6: case_6: - if ((ch >= L'0' && ch <= L':') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;} + if ((ch >= L'0' && ch <= L'9') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;} else {t->kind = 3; break;} case 7: case_7: @@ -880,9 +878,11 @@ Token* Scanner::NextToken() { case 19: {t->kind = 12; break;} case 20: + {t->kind = 13; break;} + case 21: if (ch == L'.') {AddCh(); goto case_7;} else {t->kind = 8; break;} - case 21: + case 22: if (ch == L'.') {AddCh(); goto case_7;} else {t->kind = 7; break;} diff --git a/applications/test/dictionary/calcEntry/calcEntryScanner.h b/applications/test/dictionary/calcEntry/calcEntryScanner.h index fdebddeebe..9ea17302c6 100644 --- a/applications/test/dictionary/calcEntry/calcEntryScanner.h +++ b/applications/test/dictionary/calcEntry/calcEntryScanner.h @@ -219,7 +219,6 @@ public: //------------------------------------------------------------------------------ //! maps characters (integers) to start states of tokens class StartStates { -private: class Elem { public: int key, val; @@ -235,7 +234,7 @@ public: StartStates() : tab(new Elem*[128]) { - memset(tab, 0, 128 * sizeof(Elem*)); + memset(tab, 0, 128*sizeof(Elem*)); } virtual ~StartStates() { @@ -252,7 +251,7 @@ public: void set(int key, int val) { Elem *e = new Elem(key, val); - int k = unsigned(key) % 128; + const int k = unsigned(key) % 128; e->next = tab[k]; tab[k] = e; } @@ -270,7 +269,6 @@ public: //------------------------------------------------------------------------------ //! maps strings to integers (identifiers to keyword kinds) class KeywordMap { -private: class Elem { public: wchar_t *key; @@ -290,7 +288,7 @@ public: KeywordMap() : tab(new Elem*[128]) { - memset(tab, 0, 128 * sizeof(Elem*)); + memset(tab, 0, 128*sizeof(Elem*)); } virtual ~KeywordMap() { @@ -323,8 +321,8 @@ public: //! A Coco/R Scanner class Scanner { private: - static const int maxT = 13; - static const int noSym = 13; + static const int maxT = 14; + static const int noSym = 14; static const int eofSym = 0; //!< end-of-file token id static const char EOL = '\n'; //!< end-of-line character diff --git a/applications/test/dictionary/calcEntry/staticMemberFunctionSelectionTables.H b/applications/test/dictionary/calcEntry/staticMemberFunctionSelectionTables.H new file mode 100644 index 0000000000..3febd71e8a --- /dev/null +++ b/applications/test/dictionary/calcEntry/staticMemberFunctionSelectionTables.H @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +@file Foam::staticMemberFunctionSelectionTables + +Description + Macros to enable the easy declaration of member function selection tables. + +\*---------------------------------------------------------------------------*/ + +#ifndef staticMemberFunctionSelectionTables_H +#define staticMemberFunctionSelectionTables_H + +#include "memberFunctionSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +// external use: +// ~~~~~~~~~~~~~ +// declare a run-time selection: +#define declareStaticMemberFunctionSelectionTable\ +(returnType,baseType,memberFunction,argNames,argList,parList) \ + \ + /* Construct from argList function pointer type */ \ + typedef returnType (*memberFunction##argNames##MemberFunctionPtr)argList; \ + \ + /* Construct from argList function table type */ \ + typedef HashTable \ + \ + memberFunction##argNames##MemberFunctionTable; \ + \ + /* Construct from argList function pointer table pointer */ \ + static memberFunction##argNames##MemberFunctionTable* \ + memberFunction##argNames##MemberFunctionTablePtr_; \ + \ + /* Table memberFunction called from the table add function */ \ + static void construct##memberFunction##argNames##MemberFunctionTables(); \ + \ + /* Table destructor called from the table add function destructor */ \ + static void destroy##memberFunction##argNames##MemberFunctionTables(); \ + \ + /* Class to add constructor from argList to table */ \ + template \ + class add##memberFunction##argNames##StaticMemberFunctionToTable \ + { \ + public: \ + \ + add##memberFunction##argNames##StaticMemberFunctionToTable \ + ( \ + const word& lookup, \ + memberFunction##argNames##MemberFunctionPtr function \ + ) \ + { \ + construct##memberFunction##argNames##MemberFunctionTables(); \ + memberFunction##argNames##MemberFunctionTablePtr_->insert \ + ( \ + lookup, \ + function \ + ); \ + } \ + \ + ~add##memberFunction##argNames##StaticMemberFunctionToTable() \ + { \ + destroy##memberFunction##argNames##MemberFunctionTables(); \ + } \ + } + + +// internal use: +// constructor/destructor aid +#define defineStaticMemberFunctionSelectionTableConstructDestruct\ +(baseType,memberFunction,argNames) \ + \ + /* Table constructor called from the table add function constructor */ \ + void baseType::construct##memberFunction##argNames##MemberFunctionTables()\ + { \ + static bool constructed = false; \ + if (!constructed) \ + { \ + constructed = true; \ + baseType::memberFunction##argNames##MemberFunctionTablePtr_ \ + = new baseType::memberFunction##argNames##MemberFunctionTable;\ + } \ + }; \ + \ + /* Table destructor called from the table add function destructor */ \ + void baseType::destroy##memberFunction##argNames##MemberFunctionTables() \ + { \ + if (baseType::memberFunction##argNames##MemberFunctionTablePtr_) \ + { \ + delete baseType::memberFunction##argNames##MemberFunctionTablePtr_;\ + baseType::memberFunction##argNames##MemberFunctionTablePtr_ = NULL;\ + } \ + } + + +// internal use: +// create pointer to hash-table of functions +#define defineStaticMemberFunctionSelectionTablePtr\ +(baseType,memberFunction,argNames) \ + \ + /* Define the memberFunction table */ \ + baseType::memberFunction##argNames##MemberFunctionTable* \ + baseType::memberFunction##argNames##MemberFunctionTablePtr_ = NULL + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// external use: +// ~~~~~~~~~~~~~ +// define run-time selection table +#define defineStaticMemberFunctionSelectionTable\ +(baseType,memberFunction,argNames) \ + \ + defineStaticMemberFunctionSelectionTablePtr \ + (baseType,memberFunction,argNames); \ + defineStaticMemberFunctionSelectionTableConstructDestruct \ + (baseType,memberFunction,argNames) \ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif + +// ************************************************************************* // diff --git a/applications/test/dictionary/testDictCalc b/applications/test/dictionary/testDictCalc index f1d67650e8..6f2c38a51c 100644 --- a/applications/test/dictionary/testDictCalc +++ b/applications/test/dictionary/testDictCalc @@ -37,7 +37,13 @@ p this calculation #calc{ is done inplace; -flowRate #calc{ $flowRatePerHour / 3600}; +flowRate #calc{ $flowRatePerHour / 3600 }; + +sin45 #calc{ sin( 45*pi() / 180 ) }; +cos45 #calc{ cos( degToRad(45) ) }; +pow #calc{ pow( $x, $y ) }; +log10 #calc{ log( 1e6 ) }; +// list #calc{ list() }; xxx yyy; foo 30;