From eb4fec371a72180c42011da4e6091e5a4acbf1a6 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 11 Dec 2019 13:32:36 +0100 Subject: [PATCH] ENH: unified some common parser static methods COMP: delay evaluation of fieldToken enumeration types - lazy evaluation at runTime instead of compile-time to make the code independent of initialization order. Otherwise triggers problems on gcc-4.8.5 on some systems where glibc is the same age, or older. --- applications/test/parserInfo/Make/files | 3 + applications/test/parserInfo/Make/options | 7 + .../test/parserInfo/Test-parserInfo.C | 131 +++++++++ applications/test/string2/Test-string2.C | 7 + .../fields/fieldExprLemonParser.lyy-m4 | 38 +-- .../expressions/fields/fieldExprParser.H | 15 +- .../expressions/fields/fieldExprScanner.cc | 181 ++++++------ .../expressions/fields/fieldExprScanner.rl | 15 +- .../include/m4/bison/named-characters.m4 | 4 +- src/OpenFOAM/include/m4/lemon/base-setup.m4 | 4 +- .../include/m4/lemon/operator-precedence.m4 | 4 +- .../include/m4/lemon/parser-methods.m4 | 83 ++++++ .../include/m4/lemon/rules-components.m4 | 4 +- .../m4/lemon/rules-fields-components.m4 | 15 +- src/OpenFOAM/include/m4/lemon/rules-fields.m4 | 4 +- .../include/m4/lemon/rules-functions.m4 | 4 +- .../include/m4/lemon/rules-operations.m4 | 4 +- .../include/m4/lemon/rules-scalar-logic.m4 | 4 +- .../include/m4/lemon/rules-standard.m4 | 4 +- .../patch/patchExprLemonParser.lyy-m4 | 40 +-- .../expressions/patch/patchExprParser.H | 15 +- .../expressions/patch/patchExprScanner.cc | 261 +++++++++--------- .../expressions/patch/patchExprScanner.rl | 89 +++--- .../volume/volumeExprLemonParser.lyy-m4 | 44 ++- .../expressions/volume/volumeExprParser.H | 15 +- .../expressions/volume/volumeExprScanner.cc | 260 ++++++++--------- .../expressions/volume/volumeExprScanner.rl | 88 +++--- 27 files changed, 818 insertions(+), 525 deletions(-) create mode 100644 applications/test/parserInfo/Make/files create mode 100644 applications/test/parserInfo/Make/options create mode 100644 applications/test/parserInfo/Test-parserInfo.C create mode 100644 src/OpenFOAM/include/m4/lemon/parser-methods.m4 diff --git a/applications/test/parserInfo/Make/files b/applications/test/parserInfo/Make/files new file mode 100644 index 0000000000..2b9262c86b --- /dev/null +++ b/applications/test/parserInfo/Make/files @@ -0,0 +1,3 @@ +Test-parserInfo.C + +EXE = $(FOAM_USER_APPBIN)/Test-parserInfo diff --git a/applications/test/parserInfo/Make/options b/applications/test/parserInfo/Make/options new file mode 100644 index 0000000000..d27c95d033 --- /dev/null +++ b/applications/test/parserInfo/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools diff --git a/applications/test/parserInfo/Test-parserInfo.C b/applications/test/parserInfo/Test-parserInfo.C new file mode 100644 index 0000000000..c9fdb8ba4e --- /dev/null +++ b/applications/test/parserInfo/Test-parserInfo.C @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Description + Output some (expressions) parser information + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "IOstreams.H" +#include "List.H" +#include "fieldExprParser.H" +#include "patchExprParser.H" +#include "volumeExprParser.H" + +using namespace Foam; + +template +void printInformation +( + Ostream& os, + const word& name, + const bool printNames, + const bool printRules +) +{ + if (printNames) + { + os << nl << name << " tokenNames:" << nl; + Parser::printTokenNames(os); + } + + if (printRules) + { + os << nl << name << " rules:" << nl; + Parser::printRules(os); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noBanner(); + argList::addNote + ( + "Display token names or rules for specified expression parser(s)." + " Without options, displays everything." + ); + + argList::addBoolOption("rules", "Print parser rules"); + argList::addBoolOption("tokens", "Print token names"); + + argList::addBoolOption("field", "Field expression parser"); + argList::addBoolOption("patch", "Patch expression parser"); + argList::addBoolOption("volume", "Volume expression parser"); + + argList args(argc, argv); + + // Defaults + const bool all = !args.count({"field", "patch", "volume"}); + const bool both = !args.count({"tokens", "rules"}); + + const bool printNames = both || args.found("tokens"); + const bool printRules = both || args.found("rules"); + + + if (all || args.found("field")) + { + printInformation + ( + Info, + "field", + printNames, + printRules + ); + } + + if (all || args.found("patch")) + { + printInformation + ( + Info, + "patch", + printNames, + printRules + ); + } + + if (all || args.found("volume")) + { + printInformation + ( + Info, + "volume", + printNames, + printRules + ); + } + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/string2/Test-string2.C b/applications/test/string2/Test-string2.C index 1ef7109805..f3f944893e 100644 --- a/applications/test/string2/Test-string2.C +++ b/applications/test/string2/Test-string2.C @@ -39,6 +39,7 @@ Description #include "fileName.H" #include "stringList.H" #include "stringOps.H" +#include "fieldExprFwd.H" using namespace Foam; @@ -122,6 +123,9 @@ int main(int argc, char *argv[]) // Test numeric { Info<< nl << "Test numeric evaluation" << nl; + + // expressions::fieldExpr::debug = 2; + for ( const auto& cstr @@ -135,6 +139,9 @@ int main(int argc, char *argv[]) "vector=${{ 5 * vector(1,2,3) }}=", "empty=${{ }}=", + + "vector=${{ 5 * vector(1, 2, 3) ^ vector(4, 5, 6) }}=", +// NOT YET WORKING: "vector=${{ 5 * [1 2 3 ] ^ [ 4 5 6 ] }}=", } ) { diff --git a/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4 b/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4 index b37814b7f9..63d6832a59 100644 --- a/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4 +++ b/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4 @@ -92,7 +92,7 @@ TBD } // %include /* - * include[fieldExprLemonParserMacros.m4] + * include fieldExprLemonParserMacros.m4 *include(`fieldExprLemonParserMacros.m4')dnl !done in a comment since many editors have issues matching m4 quotes! */ @@ -103,6 +103,7 @@ TBD #include "fieldExprScanner.H" #include "unitConversion.H" #include "error.H" +#include "IOmanip.H" #include "exprOps.H" #include "exprDriverOps.H" @@ -345,13 +346,21 @@ rule_tensor_unzipAll(vfield, tfield) // ************************************************************************* // -dnl/* Standard m4 quoting -changequote([`],['])dnl -dnl*/ +/* + * include m4/lemon/parser-methods.m4 +include([m4/lemon/parser-methods.m4])dnl +dnl Can revert to standard m4 quoting +dnl ... Or not changequote([`],['])dnl Revert to standard m4 quoting + */ %code { +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +parser_code_static_methods(Foam::expressions::fieldExpr::parser) + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::expressions::fieldExpr::parser::stop() @@ -391,27 +400,6 @@ void Foam::expressions::fieldExpr::parser::parse } -Foam::word Foam::expressions::fieldExpr::parser::nameOfToken -( - int tokenId -) const -{ - #ifndef NDEBUG - if - ( - tokenId > 0 - && unsigned(tokenId) < (sizeof(yyTokenName) / sizeof(char*)) - ) - { - return yyTokenName[tokenId]; - } - return ""; - #else - return word(); - #endif -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End of %code diff --git a/src/OpenFOAM/expressions/fields/fieldExprParser.H b/src/OpenFOAM/expressions/fields/fieldExprParser.H index b8dbb6378a..b8f902eb7f 100644 --- a/src/OpenFOAM/expressions/fields/fieldExprParser.H +++ b/src/OpenFOAM/expressions/fields/fieldExprParser.H @@ -77,6 +77,18 @@ public: } + // Static Member Functions + + //- Return the text name corresponding to the tokenId + static word tokenName(int tokenId); + + //- Print all token names + static void printTokenNames(Ostream& os); + + //- Print all rules + static void printRules(Ostream& os); + + // Member Functions //- Start parsing, with the given driver context @@ -87,9 +99,6 @@ public: //- Push token/value to parser void parse(int tokenId, scanToken* tokenVal); - - //- Return the text name corresponding to the tokenId - word nameOfToken(int tokenId) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/expressions/fields/fieldExprScanner.cc b/src/OpenFOAM/expressions/fields/fieldExprScanner.cc index b6b730372d..04f92caf69 100644 --- a/src/OpenFOAM/expressions/fields/fieldExprScanner.cc +++ b/src/OpenFOAM/expressions/fields/fieldExprScanner.cc @@ -56,6 +56,9 @@ namespace Foam //- An {int, c_str} enum pairing #define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } +//- An {int, c_str} enum pairing for field types +#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() } + #undef HAS_LOOKBEHIND_TOKENS // Special handling of predefined method types. Eg, .x(), .y(), ... @@ -89,7 +92,7 @@ static const Enum funcTokenEnums TOKEN_PAIR("ceil", CEIL), TOKEN_PAIR("round", ROUND), #endif -#ifdef TOK_HYPOT /* Can use hypot? */ +#ifdef TOK_HYPOT TOKEN_PAIR("hypot", HYPOT), #endif }); @@ -160,7 +163,7 @@ static int driverTokenType -#line 164 "fieldExprScanner.cc" +#line 167 "fieldExprScanner.cc" static const int fieldExpr_start = 11; static const int fieldExpr_first_final = 11; static const int fieldExpr_error = 0; @@ -168,7 +171,7 @@ static const int fieldExpr_error = 0; static const int fieldExpr_en_main = 11; -#line 300 "fieldExprScanner.rl" +#line 303 "fieldExprScanner.rl" @@ -246,7 +249,7 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " function:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; parser_->parse(tokType, nullptr); return true; @@ -260,7 +263,7 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " as look-behind:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; driver_.resetStashedTokenId(tokType); parser_->parse(tokType, nullptr); @@ -279,7 +282,7 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " token:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; scanTok.name = new Foam::word(std::move(ident)); parser_->parse(tokType, &scanTok); @@ -307,9 +310,9 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident.substr(0, dot).c_str() << " token:" - << parser_->nameOfToken(tokType) << " with " + << parser_->tokenName(tokType) << " with " << ident.substr(dot).c_str() << " token:" - << parser_->nameOfToken(methType) << nl; + << parser_->tokenName(methType) << nl; // The field (before the ".") ident.erase(dot); @@ -395,7 +398,7 @@ bool Foam::expressions::fieldExpr::scanner::process // Initialize FSM variables -#line 399 "fieldExprScanner.cc" +#line 402 "fieldExprScanner.cc" { cs = fieldExpr_start; ts = 0; @@ -403,18 +406,18 @@ bool Foam::expressions::fieldExpr::scanner::process act = 0; } -#line 525 "fieldExprScanner.rl" +#line 528 "fieldExprScanner.rl" /* ^^^ FSM initialization here ^^^ */; -#line 411 "fieldExprScanner.cc" +#line 414 "fieldExprScanner.cc" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr2: -#line 186 "fieldExprScanner.rl" +#line 189 "fieldExprScanner.rl" {te = p+1;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -422,7 +425,7 @@ tr2: }} goto st11; tr4: -#line 186 "fieldExprScanner.rl" +#line 189 "fieldExprScanner.rl" {te = p+1;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -430,7 +433,7 @@ tr4: }} goto st11; tr5: -#line 164 "fieldExprScanner.rl" +#line 167 "fieldExprScanner.rl" {{p = ((te))-1;}{ driver_.parsePosition() = (ts-buf); @@ -454,91 +457,91 @@ tr5: }} goto st11; tr8: -#line 229 "fieldExprScanner.rl" +#line 232 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(EQUAL); }} goto st11; tr9: -#line 281 "fieldExprScanner.rl" +#line 284 "fieldExprScanner.rl" {{p = ((te))-1;}{ EMIT_TOKEN(TENSOR); }} goto st11; tr11: -#line 289 "fieldExprScanner.rl" +#line 292 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(UNIT_TENSOR); }} goto st11; tr12: -#line 232 "fieldExprScanner.rl" +#line 235 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LOR); }} goto st11; tr16: -#line 214 "fieldExprScanner.rl" +#line 217 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(PERCENT); }} goto st11; tr19: -#line 215 "fieldExprScanner.rl" +#line 218 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LPAREN); }} goto st11; tr20: -#line 216 "fieldExprScanner.rl" +#line 219 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(RPAREN); }} goto st11; tr21: -#line 217 "fieldExprScanner.rl" +#line 220 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(TIMES); }} goto st11; tr22: -#line 218 "fieldExprScanner.rl" +#line 221 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(PLUS); }} goto st11; tr23: -#line 220 "fieldExprScanner.rl" +#line 223 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(COMMA); }} goto st11; tr24: -#line 219 "fieldExprScanner.rl" +#line 222 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(MINUS); }} goto st11; tr26: -#line 222 "fieldExprScanner.rl" +#line 225 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(DIVIDE); }} goto st11; tr28: -#line 224 "fieldExprScanner.rl" +#line 227 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(COLON); }} goto st11; tr32: -#line 223 "fieldExprScanner.rl" +#line 226 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(QUESTION); }} goto st11; tr35: -#line 235 "fieldExprScanner.rl" +#line 238 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(BIT_XOR); }} goto st11; tr51: -#line 208 "fieldExprScanner.rl" +#line 211 "fieldExprScanner.rl" {te = p;p--;} goto st11; tr52: -#line 213 "fieldExprScanner.rl" +#line 216 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(NOT); }} goto st11; tr53: -#line 230 "fieldExprScanner.rl" +#line 233 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(NOT_EQUAL); }} goto st11; tr54: -#line 233 "fieldExprScanner.rl" +#line 236 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(BIT_AND); }} goto st11; tr55: -#line 231 "fieldExprScanner.rl" +#line 234 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LAND); }} goto st11; tr56: -#line 221 "fieldExprScanner.rl" +#line 224 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(DOT); }} goto st11; tr59: -#line 164 "fieldExprScanner.rl" +#line 167 "fieldExprScanner.rl" {te = p;p--;{ driver_.parsePosition() = (ts-buf); @@ -562,7 +565,7 @@ tr59: }} goto st11; tr61: -#line 192 "fieldExprScanner.rl" +#line 195 "fieldExprScanner.rl" {te = p;p--;{ // Tokenized ".method" - dispatch '.' and "method" separately driver_.parsePosition() = (ts-buf); @@ -571,23 +574,23 @@ tr61: }} goto st11; tr62: -#line 225 "fieldExprScanner.rl" +#line 228 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(LESS); }} goto st11; tr63: -#line 226 "fieldExprScanner.rl" +#line 229 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LESS_EQ); }} goto st11; tr64: -#line 227 "fieldExprScanner.rl" +#line 230 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(GREATER); }} goto st11; tr65: -#line 228 "fieldExprScanner.rl" +#line 231 "fieldExprScanner.rl" {te = p+1;{ EMIT_TOKEN(GREATER_EQ); }} goto st11; tr66: -#line 186 "fieldExprScanner.rl" +#line 189 "fieldExprScanner.rl" {te = p;p--;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -698,43 +701,43 @@ tr68: } goto st11; tr82: -#line 257 "fieldExprScanner.rl" +#line 260 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(ATAN); }} goto st11; tr97: -#line 253 "fieldExprScanner.rl" +#line 256 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(COS); }} goto st11; tr114: -#line 246 "fieldExprScanner.rl" +#line 249 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(LOG); }} goto st11; tr121: -#line 262 "fieldExprScanner.rl" +#line 265 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(MAG); }} goto st11; tr128: -#line 266 "fieldExprScanner.rl" +#line 269 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(NEG); }} goto st11; tr134: -#line 265 "fieldExprScanner.rl" +#line 268 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(POS); }} goto st11; tr153: -#line 252 "fieldExprScanner.rl" +#line 255 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(SIN); }} goto st11; tr169: -#line 249 "fieldExprScanner.rl" +#line 252 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(SQR); }} goto st11; tr184: -#line 254 "fieldExprScanner.rl" +#line 257 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(TAN); }} goto st11; tr190: -#line 281 "fieldExprScanner.rl" +#line 284 "fieldExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(TENSOR); }} goto st11; st11: @@ -745,7 +748,7 @@ st11: case 11: #line 1 "NONE" {ts = p;} -#line 749 "fieldExprScanner.cc" +#line 752 "fieldExprScanner.cc" switch( (*p) ) { case 32: goto st12; case 33: goto st13; @@ -872,7 +875,7 @@ st16: if ( ++p == pe ) goto _test_eof16; case 16: -#line 876 "fieldExprScanner.cc" +#line 879 "fieldExprScanner.cc" switch( (*p) ) { case 69: goto st5; case 101: goto st5; @@ -923,7 +926,7 @@ st19: if ( ++p == pe ) goto _test_eof19; case 19: -#line 927 "fieldExprScanner.cc" +#line 930 "fieldExprScanner.cc" switch( (*p) ) { case 46: goto tr57; case 69: goto st5; @@ -973,194 +976,194 @@ case 22: tr67: #line 1 "NONE" {te = p+1;} -#line 186 "fieldExprScanner.rl" +#line 189 "fieldExprScanner.rl" {act = 67;} goto st23; tr71: #line 1 "NONE" {te = p+1;} -#line 286 "fieldExprScanner.rl" +#line 289 "fieldExprScanner.rl" {act = 63;} goto st23; tr77: #line 1 "NONE" {te = p+1;} -#line 256 "fieldExprScanner.rl" +#line 259 "fieldExprScanner.rl" {act = 40;} goto st23; tr79: #line 1 "NONE" {te = p+1;} -#line 255 "fieldExprScanner.rl" +#line 258 "fieldExprScanner.rl" {act = 39;} goto st23; tr83: #line 1 "NONE" {te = p+1;} -#line 258 "fieldExprScanner.rl" +#line 261 "fieldExprScanner.rl" {act = 42;} goto st23; tr88: #line 1 "NONE" {te = p+1;} -#line 274 "fieldExprScanner.rl" +#line 277 "fieldExprScanner.rl" {act = 55;} goto st23; tr91: #line 1 "NONE" {te = p+1;} -#line 279 "fieldExprScanner.rl" +#line 282 "fieldExprScanner.rl" {act = 58;} goto st23; tr95: #line 1 "NONE" {te = p+1;} -#line 251 "fieldExprScanner.rl" +#line 254 "fieldExprScanner.rl" {act = 35;} goto st23; tr98: #line 1 "NONE" {te = p+1;} -#line 260 "fieldExprScanner.rl" +#line 263 "fieldExprScanner.rl" {act = 44;} goto st23; tr105: #line 1 "NONE" {te = p+1;} -#line 243 "fieldExprScanner.rl" +#line 246 "fieldExprScanner.rl" {act = 27;} goto st23; tr107: #line 1 "NONE" {te = p+1;} -#line 245 "fieldExprScanner.rl" +#line 248 "fieldExprScanner.rl" {act = 29;} goto st23; tr111: #line 1 "NONE" {te = p+1;} -#line 288 "fieldExprScanner.rl" +#line 291 "fieldExprScanner.rl" {act = 65;} goto st23; tr116: #line 1 "NONE" {te = p+1;} -#line 247 "fieldExprScanner.rl" +#line 250 "fieldExprScanner.rl" {act = 31;} goto st23; tr120: #line 1 "NONE" {te = p+1;} -#line 273 "fieldExprScanner.rl" +#line 276 "fieldExprScanner.rl" {act = 54;} goto st23; tr124: #line 1 "NONE" {te = p+1;} -#line 263 "fieldExprScanner.rl" +#line 266 "fieldExprScanner.rl" {act = 47;} goto st23; tr125: #line 1 "NONE" {te = p+1;} -#line 272 "fieldExprScanner.rl" +#line 275 "fieldExprScanner.rl" {act = 53;} goto st23; tr129: #line 1 "NONE" {te = p+1;} -#line 268 "fieldExprScanner.rl" +#line 271 "fieldExprScanner.rl" {act = 51;} goto st23; tr130: #line 1 "NONE" {te = p+1;} -#line 242 "fieldExprScanner.rl" +#line 245 "fieldExprScanner.rl" {act = 26;} goto st23; tr133: #line 1 "NONE" {te = p+1;} -#line 248 "fieldExprScanner.rl" +#line 251 "fieldExprScanner.rl" {act = 32;} goto st23; tr135: #line 1 "NONE" {te = p+1;} -#line 267 "fieldExprScanner.rl" +#line 270 "fieldExprScanner.rl" {act = 50;} goto st23; tr143: #line 1 "NONE" {te = p+1;} -#line 244 "fieldExprScanner.rl" +#line 247 "fieldExprScanner.rl" {act = 28;} goto st23; tr144: #line 1 "NONE" {te = p+1;} -#line 276 "fieldExprScanner.rl" +#line 279 "fieldExprScanner.rl" {act = 57;} goto st23; tr152: #line 1 "NONE" {te = p+1;} -#line 269 "fieldExprScanner.rl" +#line 272 "fieldExprScanner.rl" {act = 52;} goto st23; tr154: #line 1 "NONE" {te = p+1;} -#line 259 "fieldExprScanner.rl" +#line 262 "fieldExprScanner.rl" {act = 43;} goto st23; tr167: #line 1 "NONE" {te = p+1;} -#line 283 "fieldExprScanner.rl" +#line 286 "fieldExprScanner.rl" {act = 62;} goto st23; tr170: #line 1 "NONE" {te = p+1;} -#line 250 "fieldExprScanner.rl" +#line 253 "fieldExprScanner.rl" {act = 34;} goto st23; tr171: #line 1 "NONE" {te = p+1;} -#line 275 "fieldExprScanner.rl" +#line 278 "fieldExprScanner.rl" {act = 56;} goto st23; tr179: #line 1 "NONE" {te = p+1;} -#line 282 "fieldExprScanner.rl" +#line 285 "fieldExprScanner.rl" {act = 61;} goto st23; tr185: #line 1 "NONE" {te = p+1;} -#line 261 "fieldExprScanner.rl" +#line 264 "fieldExprScanner.rl" {act = 45;} goto st23; tr193: #line 1 "NONE" {te = p+1;} -#line 287 "fieldExprScanner.rl" +#line 290 "fieldExprScanner.rl" {act = 64;} goto st23; tr198: #line 1 "NONE" {te = p+1;} -#line 280 "fieldExprScanner.rl" +#line 283 "fieldExprScanner.rl" {act = 59;} goto st23; st23: if ( ++p == pe ) goto _test_eof23; case 23: -#line 1164 "fieldExprScanner.cc" +#line 1167 "fieldExprScanner.cc" switch( (*p) ) { case 46: goto tr67; case 95: goto tr67; @@ -2926,7 +2929,7 @@ st120: if ( ++p == pe ) goto _test_eof120; case 120: -#line 2930 "fieldExprScanner.cc" +#line 2933 "fieldExprScanner.cc" switch( (*p) ) { case 46: goto tr67; case 58: goto st8; @@ -3347,7 +3350,7 @@ case 10: _out: {} } -#line 527 "fieldExprScanner.rl" +#line 530 "fieldExprScanner.rl" /* ^^^ FSM execution here ^^^ */; if (0 == cs) diff --git a/src/OpenFOAM/expressions/fields/fieldExprScanner.rl b/src/OpenFOAM/expressions/fields/fieldExprScanner.rl index 2bf42cbd1f..bedfe81ff7 100644 --- a/src/OpenFOAM/expressions/fields/fieldExprScanner.rl +++ b/src/OpenFOAM/expressions/fields/fieldExprScanner.rl @@ -54,6 +54,9 @@ namespace Foam //- An {int, c_str} enum pairing #define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } +//- An {int, c_str} enum pairing for field types +#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() } + #undef HAS_LOOKBEHIND_TOKENS // Special handling of predefined method types. Eg, .x(), .y(), ... @@ -87,7 +90,7 @@ static const Enum funcTokenEnums TOKEN_PAIR("ceil", CEIL), TOKEN_PAIR("round", ROUND), #endif -#ifdef TOK_HYPOT /* Can use hypot? */ +#ifdef TOK_HYPOT TOKEN_PAIR("hypot", HYPOT), #endif }); @@ -374,7 +377,7 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " function:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; parser_->parse(tokType, nullptr); return true; @@ -388,7 +391,7 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " as look-behind:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; driver_.resetStashedTokenId(tokType); parser_->parse(tokType, nullptr); @@ -407,7 +410,7 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " token:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; scanTok.name = new Foam::word(std::move(ident)); parser_->parse(tokType, &scanTok); @@ -435,9 +438,9 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident.substr(0, dot).c_str() << " token:" - << parser_->nameOfToken(tokType) << " with " + << parser_->tokenName(tokType) << " with " << ident.substr(dot).c_str() << " token:" - << parser_->nameOfToken(methType) << nl; + << parser_->tokenName(methType) << nl; // The field (before the ".") ident.erase(dot); diff --git a/src/OpenFOAM/include/m4/bison/named-characters.m4 b/src/OpenFOAM/include/m4/bison/named-characters.m4 index 7925e094fa..62f6ebdefd 100644 --- a/src/OpenFOAM/include/m4/bison/named-characters.m4 +++ b/src/OpenFOAM/include/m4/bison/named-characters.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Named versions (as m4 macros) of single quoted characters to avoid diff --git a/src/OpenFOAM/include/m4/lemon/base-setup.m4 b/src/OpenFOAM/include/m4/lemon/base-setup.m4 index a7aff0bd1d..159d5e3418 100644 --- a/src/OpenFOAM/include/m4/lemon/base-setup.m4 +++ b/src/OpenFOAM/include/m4/lemon/base-setup.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # A collection of 'base' setup of m4 macros for lemon, and setup diff --git a/src/OpenFOAM/include/m4/lemon/operator-precedence.m4 b/src/OpenFOAM/include/m4/lemon/operator-precedence.m4 index 67715e2f95..a8e1baa698 100644 --- a/src/OpenFOAM/include/m4/lemon/operator-precedence.m4 +++ b/src/OpenFOAM/include/m4/lemon/operator-precedence.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Defines standard operator precedence macro for lemon grammar. diff --git a/src/OpenFOAM/include/m4/lemon/parser-methods.m4 b/src/OpenFOAM/include/m4/lemon/parser-methods.m4 new file mode 100644 index 0000000000..3fda03d395 --- /dev/null +++ b/src/OpenFOAM/include/m4/lemon/parser-methods.m4 @@ -0,0 +1,83 @@ +divert(-1)dnl +#-----------------------------------*- m4 -*----------------------------------- +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | www.openfoam.com +# \\/ M anipulation | +#------------------------------------------------------------------------------ +# Copyright (C) 2019 OpenCFD Ltd. +#------------------------------------------------------------------------------ +# License +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later +# +# Description +# Various "boilerplate" parser methods (C++) +# +# Requires +# IOmanip.H +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# parser_code_static_methods(clsName) +# +# Description +# Emit common parser static methods +# `tokenName` +# `printTokenNames` +# `printRules` +# +# Note +# Array access uses `*(array + i)` to avoid [] square brackets, +# which may be used for m4 quoting, unless we switched back to `' !! +# +# Example +# parser_code_static_methods(Foam::expressions::fieldExpr::parser) +# +#------------------------------------------------------------------------------ + +define([parser_code_static_methods], +[dnl +Foam::word $1::tokenName(int i) +{ + #ifndef NDEBUG + if (i > 0 && unsigned(i) < (sizeof(yyTokenName) / sizeof(char*))) + { + return *(yyTokenName + i); + } + return ""; + #else + return ""; + #endif +} + +void $1::printTokenNames(Ostream& os) +{ + #ifndef NDEBUG + const unsigned nElem(sizeof(yyTokenName) / sizeof(char*)); + for (unsigned i = 1; i < nElem; ++i) // start = 1 (skip termination token) + { + os << *(yyTokenName + i) << nl; + } + #endif +} + +void $1::printRules(Ostream& os) +{ + #ifndef NDEBUG + const unsigned nElem(sizeof(yyRuleName) / sizeof(char*)); + + // Easy way to count number of digits + const unsigned width(std::to_string(nElem).length()); + + for (unsigned i = 0; i < nElem; ++i) + { + os << setw(width) << i << ": " << *(yyRuleName + i) << nl; + } + #endif +}] +) + +#------------------------------------------------------------------------------ +divert(0)dnl diff --git a/src/OpenFOAM/include/m4/lemon/rules-components.m4 b/src/OpenFOAM/include/m4/lemon/rules-components.m4 index a1218e4911..ef7f0af979 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-components.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-components.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Collection of VectorSpace `component' functions diff --git a/src/OpenFOAM/include/m4/lemon/rules-fields-components.m4 b/src/OpenFOAM/include/m4/lemon/rules-fields-components.m4 index ec20e3adcf..3aa67c0e3a 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-fields-components.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-fields-components.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Rules for vector/tensor `zip' functions, which are used to combine @@ -117,7 +117,10 @@ define([rule_tensor_transpose], # rule_vector_zip(target, sources, tok) # # Description -# Combine scalars to produce a vector +# Combine three scalars to produce a vector +# - vector(x, y, z) +# +# A rule such as [x y z] does not reduce well - needs more investigation. # # Example # rule_vector_zip(vfield, sfield, VECTOR) @@ -143,7 +146,8 @@ define([rule_vector_zip], # rule_sphTensor_zip(target, sources, tok) # # Description -# Combine scalars to produce a sphericalTensor +# Combine one scalar to produce a sphericalTensor +# - sphericalTensor(ii) #------------------------------------------------------------------------------ define([rule_sphTensor_zip], @@ -164,7 +168,8 @@ define([rule_sphTensor_zip], # rule_symTensor_zip(target, sources, tok) # # Description -# Combine scalars to produce a symmTensor +# Combine six scalars to produce a symmTensor +# - symmTensor(xx, xy, xy, yy, yz, zz) #------------------------------------------------------------------------------ define([rule_symTensor_zip], diff --git a/src/OpenFOAM/include/m4/lemon/rules-fields.m4 b/src/OpenFOAM/include/m4/lemon/rules-fields.m4 index 495242c89e..178e91e6c6 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-fields.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-fields.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Field handling m4/lemon macros. diff --git a/src/OpenFOAM/include/m4/lemon/rules-functions.m4 b/src/OpenFOAM/include/m4/lemon/rules-functions.m4 index 03e0a9c9e3..57d5c429bf 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-functions.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-functions.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Collection of `standard' functions and type-specific ones. diff --git a/src/OpenFOAM/include/m4/lemon/rules-operations.m4 b/src/OpenFOAM/include/m4/lemon/rules-operations.m4 index e144aac521..a1297a34ff 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-operations.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-operations.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Collection of `standard' operations and type-specific ones. diff --git a/src/OpenFOAM/include/m4/lemon/rules-scalar-logic.m4 b/src/OpenFOAM/include/m4/lemon/rules-scalar-logic.m4 index cc27952ea6..60861e2805 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-scalar-logic.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-scalar-logic.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Logic rules, using bool or Foam::scalar for its storage. diff --git a/src/OpenFOAM/include/m4/lemon/rules-standard.m4 b/src/OpenFOAM/include/m4/lemon/rules-standard.m4 index 3fed5cde93..f88ce9fc00 100644 --- a/src/OpenFOAM/include/m4/lemon/rules-standard.m4 +++ b/src/OpenFOAM/include/m4/lemon/rules-standard.m4 @@ -9,8 +9,8 @@ divert(-1)dnl # Copyright (C) 2019 OpenCFD Ltd. #------------------------------------------------------------------------------ # License -# This file is part of OpenFOAM, licensed under GNU General Public License -# . +# This file is part of OpenFOAM, distributed under GNU General Public +# License GPL-3.0 or later # # Description # Collection of common functions that should work on all (non-logical) diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 b/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 index 477cc7ea46..5e6ea91dd0 100644 --- a/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 +++ b/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 @@ -36,7 +36,7 @@ Description } // %include /* - * include[patchExprLemonParserMacros.m4] + * include patchExprLemonParserMacros.m4 *include(`patchExprLemonParserMacros.m4')dnl !done in a comment since many editors have issues matching m4 quotes! */ @@ -46,8 +46,9 @@ Description #include "patchExprParser.H" #include "patchExprScanner.H" #include "unitConversion.H" -#include "error.H" #include "volFields.H" +#include "error.H" +#include "IOmanip.H" #include "exprOps.H" #include "exprDriverOps.H" #include "GeometricFieldOps.H" @@ -491,13 +492,21 @@ rule_faceToPoint(phfield, hfield) // ************************************************************************* // -dnl/* Standard m4 quoting -changequote([`],['])dnl -dnl*/ +/* + * include m4/lemon/parser-methods.m4 +include([m4/lemon/parser-methods.m4])dnl +dnl Can revert to standard m4 quoting +dnl ... Or not changequote([`],['])dnl Revert to standard m4 quoting + */ %code { +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +parser_code_static_methods(Foam::expressions::patchExpr::parser) + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::expressions::patchExpr::parser::stop() @@ -537,27 +546,6 @@ void Foam::expressions::patchExpr::parser::parse } -Foam::word Foam::expressions::patchExpr::parser::nameOfToken -( - int tokenId -) const -{ - #ifndef NDEBUG - if - ( - tokenId > 0 - && unsigned(tokenId) < (sizeof(yyTokenName) / sizeof(char*)) - ) - { - return yyTokenName[tokenId]; - } - return ""; - #else - return word(); - #endif -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End of %code diff --git a/src/finiteVolume/expressions/patch/patchExprParser.H b/src/finiteVolume/expressions/patch/patchExprParser.H index a59fcdcca6..45d4adfbdf 100644 --- a/src/finiteVolume/expressions/patch/patchExprParser.H +++ b/src/finiteVolume/expressions/patch/patchExprParser.H @@ -77,6 +77,18 @@ public: } + // Static Member Functions + + //- Return the text name corresponding to the tokenId + static word tokenName(int tokenId); + + //- Print all token names + static void printTokenNames(Ostream& os); + + //- Print all rules + static void printRules(Ostream& os); + + // Member Functions //- Start parsing, with the given driver context @@ -87,9 +99,6 @@ public: //- Push token/value to parser void parse(int tokenId, scanToken* tokenVal); - - //- Return the text name corresponding to the tokenId - word nameOfToken(int tokenId) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.cc b/src/finiteVolume/expressions/patch/patchExprScanner.cc index 98fe2225e1..bc158851e8 100644 --- a/src/finiteVolume/expressions/patch/patchExprScanner.cc +++ b/src/finiteVolume/expressions/patch/patchExprScanner.cc @@ -56,6 +56,9 @@ namespace Foam //- An {int, c_str} enum pairing #define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } +//- An {int, c_str} enum pairing for field types +#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() } + #undef HAS_LOOKBEHIND_TOKENS // Special handling of predefined method types. Eg, .x(), .y(), ... @@ -78,37 +81,49 @@ static const Enum fieldMethodEnums TOKEN_PAIR("T", TRANSPOSE), /* tensors only */ }); + // Known field-token types -static const Enum fieldTokenEnums -({ -#ifdef TOK_SCALAR_ID - TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID), - TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID), - TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID), - TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID), - TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID), -#else -#error TOK_SCALAR_ID not defined -#endif -#ifdef TOK_SSCALAR_ID - TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID), - TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID), - TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID), - TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID), - TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID), -#else -#error TOK_SSCALAR_ID not defined -#endif -#ifdef TOK_PSCALAR_ID - TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID), - TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID), - TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID), - TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID), - TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID), -#else -#warning TOK_PSCALAR_ID not defined -#endif -}); +// - delay populating until run-time +static const Enum& fieldTokenEnums() +{ + static Enum enums_; + + if (enums_.empty()) + { + enums_.append + ({ + #ifdef TOK_SCALAR_ID + FIELD_PAIR(volScalarField, SCALAR_ID), + FIELD_PAIR(volVectorField, VECTOR_ID), + FIELD_PAIR(volTensorField, TENSOR_ID), + FIELD_PAIR(volSymmTensorField, SYM_TENSOR_ID), + FIELD_PAIR(volSphericalTensorField, SPH_TENSOR_ID), + #else + #error TOK_SCALAR_ID not defined + #endif + #ifdef TOK_SSCALAR_ID + FIELD_PAIR(surfaceScalarField, SSCALAR_ID), + FIELD_PAIR(surfaceVectorField, SVECTOR_ID), + FIELD_PAIR(surfaceTensorField, STENSOR_ID), + FIELD_PAIR(surfaceSymmTensorField, SSYM_TENSOR_ID), + FIELD_PAIR(surfaceSphericalTensorField, SSPH_TENSOR_ID), + #else + #error TOK_SSCALAR_ID not defined + #endif + #ifdef TOK_PSCALAR_ID + FIELD_PAIR(pointScalarField, PSCALAR_ID), + FIELD_PAIR(pointVectorField, PVECTOR_ID), + FIELD_PAIR(pointTensorField, PTENSOR_ID), + FIELD_PAIR(pointSymmTensorField, PSYM_TENSOR_ID), + FIELD_PAIR(pointSphericalTensorField, PSPH_TENSOR_ID), + #else + #warning TOK_PSCALAR_ID not defined + #endif + }); + } + + return enums_; +} // Simple compile-time function name declarations. @@ -121,7 +136,7 @@ static const Enum funcTokenEnums TOKEN_PAIR("ceil", CEIL), TOKEN_PAIR("round", ROUND), #endif -#ifdef TOK_HYPOT /* Can use hypot? */ +#ifdef TOK_HYPOT TOKEN_PAIR("hypot", HYPOT), #endif @@ -243,7 +258,7 @@ static int driverTokenType { const word fieldType(driver_.getFieldClassName(ident)); - int tokType = fieldTokenEnums.get(fieldType, -1); + int tokType = fieldTokenEnums().get(fieldType, -1); if (tokType > 0) { @@ -272,7 +287,7 @@ static int driverTokenType -#line 276 "patchExprScanner.cc" +#line 291 "patchExprScanner.cc" static const int patchExpr_start = 11; static const int patchExpr_first_final = 11; static const int patchExpr_error = 0; @@ -280,7 +295,7 @@ static const int patchExpr_error = 0; static const int patchExpr_en_main = 11; -#line 414 "patchExprScanner.rl" +#line 429 "patchExprScanner.rl" @@ -358,7 +373,7 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " function:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; parser_->parse(tokType, nullptr); return true; @@ -372,7 +387,7 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " as look-behind:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; driver_.resetStashedTokenId(tokType); parser_->parse(tokType, nullptr); @@ -391,7 +406,7 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " token:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; scanTok.name = new Foam::word(std::move(ident)); parser_->parse(tokType, &scanTok); @@ -419,9 +434,9 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident.substr(0, dot).c_str() << " token:" - << parser_->nameOfToken(tokType) << " with " + << parser_->tokenName(tokType) << " with " << ident.substr(dot).c_str() << " token:" - << parser_->nameOfToken(methType) << nl; + << parser_->tokenName(methType) << nl; // The field (before the ".") ident.erase(dot); @@ -507,7 +522,7 @@ bool Foam::expressions::patchExpr::scanner::process // Initialize FSM variables -#line 511 "patchExprScanner.cc" +#line 526 "patchExprScanner.cc" { cs = patchExpr_start; ts = 0; @@ -515,18 +530,18 @@ bool Foam::expressions::patchExpr::scanner::process act = 0; } -#line 639 "patchExprScanner.rl" +#line 654 "patchExprScanner.rl" /* ^^^ FSM initialization here ^^^ */; -#line 523 "patchExprScanner.cc" +#line 538 "patchExprScanner.cc" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr2: -#line 298 "patchExprScanner.rl" +#line 313 "patchExprScanner.rl" {te = p+1;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -534,7 +549,7 @@ tr2: }} goto st11; tr4: -#line 298 "patchExprScanner.rl" +#line 313 "patchExprScanner.rl" {te = p+1;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -542,7 +557,7 @@ tr4: }} goto st11; tr5: -#line 276 "patchExprScanner.rl" +#line 291 "patchExprScanner.rl" {{p = ((te))-1;}{ driver_.parsePosition() = (ts-buf); @@ -566,91 +581,91 @@ tr5: }} goto st11; tr8: -#line 341 "patchExprScanner.rl" +#line 356 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(EQUAL); }} goto st11; tr9: -#line 395 "patchExprScanner.rl" +#line 410 "patchExprScanner.rl" {{p = ((te))-1;}{ EMIT_TOKEN(TENSOR); }} goto st11; tr11: -#line 403 "patchExprScanner.rl" +#line 418 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(UNIT_TENSOR); }} goto st11; tr12: -#line 344 "patchExprScanner.rl" +#line 359 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LOR); }} goto st11; tr16: -#line 326 "patchExprScanner.rl" +#line 341 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(PERCENT); }} goto st11; tr19: -#line 327 "patchExprScanner.rl" +#line 342 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LPAREN); }} goto st11; tr20: -#line 328 "patchExprScanner.rl" +#line 343 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(RPAREN); }} goto st11; tr21: -#line 329 "patchExprScanner.rl" +#line 344 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(TIMES); }} goto st11; tr22: -#line 330 "patchExprScanner.rl" +#line 345 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(PLUS); }} goto st11; tr23: -#line 332 "patchExprScanner.rl" +#line 347 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(COMMA); }} goto st11; tr24: -#line 331 "patchExprScanner.rl" +#line 346 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(MINUS); }} goto st11; tr26: -#line 334 "patchExprScanner.rl" +#line 349 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(DIVIDE); }} goto st11; tr28: -#line 336 "patchExprScanner.rl" +#line 351 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(COLON); }} goto st11; tr32: -#line 335 "patchExprScanner.rl" +#line 350 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(QUESTION); }} goto st11; tr35: -#line 347 "patchExprScanner.rl" +#line 362 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(BIT_XOR); }} goto st11; tr52: -#line 320 "patchExprScanner.rl" +#line 335 "patchExprScanner.rl" {te = p;p--;} goto st11; tr53: -#line 325 "patchExprScanner.rl" +#line 340 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(NOT); }} goto st11; tr54: -#line 342 "patchExprScanner.rl" +#line 357 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(NOT_EQUAL); }} goto st11; tr55: -#line 345 "patchExprScanner.rl" +#line 360 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(BIT_AND); }} goto st11; tr56: -#line 343 "patchExprScanner.rl" +#line 358 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LAND); }} goto st11; tr57: -#line 333 "patchExprScanner.rl" +#line 348 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(DOT); }} goto st11; tr60: -#line 276 "patchExprScanner.rl" +#line 291 "patchExprScanner.rl" {te = p;p--;{ driver_.parsePosition() = (ts-buf); @@ -674,7 +689,7 @@ tr60: }} goto st11; tr62: -#line 304 "patchExprScanner.rl" +#line 319 "patchExprScanner.rl" {te = p;p--;{ // Tokenized ".method" - dispatch '.' and "method" separately driver_.parsePosition() = (ts-buf); @@ -683,23 +698,23 @@ tr62: }} goto st11; tr63: -#line 337 "patchExprScanner.rl" +#line 352 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(LESS); }} goto st11; tr64: -#line 338 "patchExprScanner.rl" +#line 353 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LESS_EQ); }} goto st11; tr65: -#line 339 "patchExprScanner.rl" +#line 354 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(GREATER); }} goto st11; tr66: -#line 340 "patchExprScanner.rl" +#line 355 "patchExprScanner.rl" {te = p+1;{ EMIT_TOKEN(GREATER_EQ); }} goto st11; tr67: -#line 298 "patchExprScanner.rl" +#line 313 "patchExprScanner.rl" {te = p;p--;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -819,43 +834,43 @@ tr69: } goto st11; tr83: -#line 369 "patchExprScanner.rl" +#line 384 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(ATAN); }} goto st11; tr98: -#line 365 "patchExprScanner.rl" +#line 380 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(COS); }} goto st11; tr115: -#line 358 "patchExprScanner.rl" +#line 373 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(LOG); }} goto st11; tr122: -#line 374 "patchExprScanner.rl" +#line 389 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(MAG); }} goto st11; tr129: -#line 378 "patchExprScanner.rl" +#line 393 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(NEG); }} goto st11; tr135: -#line 377 "patchExprScanner.rl" +#line 392 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(POS); }} goto st11; tr154: -#line 364 "patchExprScanner.rl" +#line 379 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(SIN); }} goto st11; tr170: -#line 361 "patchExprScanner.rl" +#line 376 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(SQR); }} goto st11; tr186: -#line 366 "patchExprScanner.rl" +#line 381 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(TAN); }} goto st11; tr192: -#line 395 "patchExprScanner.rl" +#line 410 "patchExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(TENSOR); }} goto st11; st11: @@ -866,7 +881,7 @@ st11: case 11: #line 1 "NONE" {ts = p;} -#line 870 "patchExprScanner.cc" +#line 885 "patchExprScanner.cc" switch( (*p) ) { case 32: goto st12; case 33: goto st13; @@ -994,7 +1009,7 @@ st16: if ( ++p == pe ) goto _test_eof16; case 16: -#line 998 "patchExprScanner.cc" +#line 1013 "patchExprScanner.cc" switch( (*p) ) { case 69: goto st5; case 101: goto st5; @@ -1045,7 +1060,7 @@ st19: if ( ++p == pe ) goto _test_eof19; case 19: -#line 1049 "patchExprScanner.cc" +#line 1064 "patchExprScanner.cc" switch( (*p) ) { case 46: goto tr58; case 69: goto st5; @@ -1095,212 +1110,212 @@ case 22: tr68: #line 1 "NONE" {te = p+1;} -#line 298 "patchExprScanner.rl" +#line 313 "patchExprScanner.rl" {act = 70;} goto st23; tr72: #line 1 "NONE" {te = p+1;} -#line 400 "patchExprScanner.rl" +#line 415 "patchExprScanner.rl" {act = 65;} goto st23; tr78: #line 1 "NONE" {te = p+1;} -#line 368 "patchExprScanner.rl" +#line 383 "patchExprScanner.rl" {act = 40;} goto st23; tr80: #line 1 "NONE" {te = p+1;} -#line 367 "patchExprScanner.rl" +#line 382 "patchExprScanner.rl" {act = 39;} goto st23; tr84: #line 1 "NONE" {te = p+1;} -#line 370 "patchExprScanner.rl" +#line 385 "patchExprScanner.rl" {act = 42;} goto st23; tr89: #line 1 "NONE" {te = p+1;} -#line 386 "patchExprScanner.rl" +#line 401 "patchExprScanner.rl" {act = 55;} goto st23; tr92: #line 1 "NONE" {te = p+1;} -#line 393 "patchExprScanner.rl" +#line 408 "patchExprScanner.rl" {act = 60;} goto st23; tr96: #line 1 "NONE" {te = p+1;} -#line 363 "patchExprScanner.rl" +#line 378 "patchExprScanner.rl" {act = 35;} goto st23; tr99: #line 1 "NONE" {te = p+1;} -#line 372 "patchExprScanner.rl" +#line 387 "patchExprScanner.rl" {act = 44;} goto st23; tr106: #line 1 "NONE" {te = p+1;} -#line 355 "patchExprScanner.rl" +#line 370 "patchExprScanner.rl" {act = 27;} goto st23; tr108: #line 1 "NONE" {te = p+1;} -#line 357 "patchExprScanner.rl" +#line 372 "patchExprScanner.rl" {act = 29;} goto st23; tr112: #line 1 "NONE" {te = p+1;} -#line 402 "patchExprScanner.rl" +#line 417 "patchExprScanner.rl" {act = 67;} goto st23; tr117: #line 1 "NONE" {te = p+1;} -#line 359 "patchExprScanner.rl" +#line 374 "patchExprScanner.rl" {act = 31;} goto st23; tr121: #line 1 "NONE" {te = p+1;} -#line 385 "patchExprScanner.rl" +#line 400 "patchExprScanner.rl" {act = 54;} goto st23; tr125: #line 1 "NONE" {te = p+1;} -#line 375 "patchExprScanner.rl" +#line 390 "patchExprScanner.rl" {act = 47;} goto st23; tr126: #line 1 "NONE" {te = p+1;} -#line 384 "patchExprScanner.rl" +#line 399 "patchExprScanner.rl" {act = 53;} goto st23; tr130: #line 1 "NONE" {te = p+1;} -#line 380 "patchExprScanner.rl" +#line 395 "patchExprScanner.rl" {act = 51;} goto st23; tr131: #line 1 "NONE" {te = p+1;} -#line 354 "patchExprScanner.rl" +#line 369 "patchExprScanner.rl" {act = 26;} goto st23; tr134: #line 1 "NONE" {te = p+1;} -#line 360 "patchExprScanner.rl" +#line 375 "patchExprScanner.rl" {act = 32;} goto st23; tr136: #line 1 "NONE" {te = p+1;} -#line 379 "patchExprScanner.rl" +#line 394 "patchExprScanner.rl" {act = 50;} goto st23; tr144: #line 1 "NONE" {te = p+1;} -#line 356 "patchExprScanner.rl" +#line 371 "patchExprScanner.rl" {act = 28;} goto st23; tr145: #line 1 "NONE" {te = p+1;} -#line 390 "patchExprScanner.rl" +#line 405 "patchExprScanner.rl" {act = 59;} goto st23; tr153: #line 1 "NONE" {te = p+1;} -#line 381 "patchExprScanner.rl" +#line 396 "patchExprScanner.rl" {act = 52;} goto st23; tr155: #line 1 "NONE" {te = p+1;} -#line 371 "patchExprScanner.rl" +#line 386 "patchExprScanner.rl" {act = 43;} goto st23; tr168: #line 1 "NONE" {te = p+1;} -#line 397 "patchExprScanner.rl" +#line 412 "patchExprScanner.rl" {act = 64;} goto st23; tr171: #line 1 "NONE" {te = p+1;} -#line 362 "patchExprScanner.rl" +#line 377 "patchExprScanner.rl" {act = 34;} goto st23; tr172: #line 1 "NONE" {te = p+1;} -#line 387 "patchExprScanner.rl" +#line 402 "patchExprScanner.rl" {act = 56;} goto st23; tr180: #line 1 "NONE" {te = p+1;} -#line 396 "patchExprScanner.rl" +#line 411 "patchExprScanner.rl" {act = 63;} goto st23; tr187: #line 1 "NONE" {te = p+1;} -#line 373 "patchExprScanner.rl" +#line 388 "patchExprScanner.rl" {act = 45;} goto st23; tr195: #line 1 "NONE" {te = p+1;} -#line 404 "patchExprScanner.rl" +#line 419 "patchExprScanner.rl" {act = 69;} goto st23; tr197: #line 1 "NONE" {te = p+1;} -#line 401 "patchExprScanner.rl" +#line 416 "patchExprScanner.rl" {act = 66;} goto st23; tr202: #line 1 "NONE" {te = p+1;} -#line 394 "patchExprScanner.rl" +#line 409 "patchExprScanner.rl" {act = 61;} goto st23; tr215: #line 1 "NONE" {te = p+1;} -#line 388 "patchExprScanner.rl" +#line 403 "patchExprScanner.rl" {act = 57;} goto st23; tr217: #line 1 "NONE" {te = p+1;} -#line 389 "patchExprScanner.rl" +#line 404 "patchExprScanner.rl" {act = 58;} goto st23; st23: if ( ++p == pe ) goto _test_eof23; case 23: -#line 1304 "patchExprScanner.cc" +#line 1319 "patchExprScanner.cc" switch( (*p) ) { case 46: goto tr68; case 95: goto tr68; @@ -3067,7 +3082,7 @@ st120: if ( ++p == pe ) goto _test_eof120; case 120: -#line 3071 "patchExprScanner.cc" +#line 3086 "patchExprScanner.cc" switch( (*p) ) { case 46: goto tr68; case 58: goto st8; @@ -3809,7 +3824,7 @@ case 10: _out: {} } -#line 641 "patchExprScanner.rl" +#line 656 "patchExprScanner.rl" /* ^^^ FSM execution here ^^^ */; if (0 == cs) diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.rl b/src/finiteVolume/expressions/patch/patchExprScanner.rl index e26c621c3f..d560c6b351 100644 --- a/src/finiteVolume/expressions/patch/patchExprScanner.rl +++ b/src/finiteVolume/expressions/patch/patchExprScanner.rl @@ -54,6 +54,9 @@ namespace Foam //- An {int, c_str} enum pairing #define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } +//- An {int, c_str} enum pairing for field types +#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() } + #undef HAS_LOOKBEHIND_TOKENS // Special handling of predefined method types. Eg, .x(), .y(), ... @@ -76,37 +79,49 @@ static const Enum fieldMethodEnums TOKEN_PAIR("T", TRANSPOSE), /* tensors only */ }); + // Known field-token types -static const Enum fieldTokenEnums -({ -#ifdef TOK_SCALAR_ID - TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID), - TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID), - TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID), - TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID), - TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID), -#else -#error TOK_SCALAR_ID not defined -#endif -#ifdef TOK_SSCALAR_ID - TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID), - TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID), - TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID), - TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID), - TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID), -#else -#error TOK_SSCALAR_ID not defined -#endif -#ifdef TOK_PSCALAR_ID - TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID), - TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID), - TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID), - TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID), - TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID), -#else -#warning TOK_PSCALAR_ID not defined -#endif -}); +// - delay populating until run-time +static const Enum& fieldTokenEnums() +{ + static Enum enums_; + + if (enums_.empty()) + { + enums_.append + ({ + #ifdef TOK_SCALAR_ID + FIELD_PAIR(volScalarField, SCALAR_ID), + FIELD_PAIR(volVectorField, VECTOR_ID), + FIELD_PAIR(volTensorField, TENSOR_ID), + FIELD_PAIR(volSymmTensorField, SYM_TENSOR_ID), + FIELD_PAIR(volSphericalTensorField, SPH_TENSOR_ID), + #else + #error TOK_SCALAR_ID not defined + #endif + #ifdef TOK_SSCALAR_ID + FIELD_PAIR(surfaceScalarField, SSCALAR_ID), + FIELD_PAIR(surfaceVectorField, SVECTOR_ID), + FIELD_PAIR(surfaceTensorField, STENSOR_ID), + FIELD_PAIR(surfaceSymmTensorField, SSYM_TENSOR_ID), + FIELD_PAIR(surfaceSphericalTensorField, SSPH_TENSOR_ID), + #else + #error TOK_SSCALAR_ID not defined + #endif + #ifdef TOK_PSCALAR_ID + FIELD_PAIR(pointScalarField, PSCALAR_ID), + FIELD_PAIR(pointVectorField, PVECTOR_ID), + FIELD_PAIR(pointTensorField, PTENSOR_ID), + FIELD_PAIR(pointSymmTensorField, PSYM_TENSOR_ID), + FIELD_PAIR(pointSphericalTensorField, PSPH_TENSOR_ID), + #else + #warning TOK_PSCALAR_ID not defined + #endif + }); + } + + return enums_; +} // Simple compile-time function name declarations. @@ -119,7 +134,7 @@ static const Enum funcTokenEnums TOKEN_PAIR("ceil", CEIL), TOKEN_PAIR("round", ROUND), #endif -#ifdef TOK_HYPOT /* Can use hypot? */ +#ifdef TOK_HYPOT TOKEN_PAIR("hypot", HYPOT), #endif @@ -241,7 +256,7 @@ static int driverTokenType { const word fieldType(driver_.getFieldClassName(ident)); - int tokType = fieldTokenEnums.get(fieldType, -1); + int tokType = fieldTokenEnums().get(fieldType, -1); if (tokType > 0) { @@ -488,7 +503,7 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " function:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; parser_->parse(tokType, nullptr); return true; @@ -502,7 +517,7 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " as look-behind:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; driver_.resetStashedTokenId(tokType); parser_->parse(tokType, nullptr); @@ -521,7 +536,7 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " token:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; scanTok.name = new Foam::word(std::move(ident)); parser_->parse(tokType, &scanTok); @@ -549,9 +564,9 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident.substr(0, dot).c_str() << " token:" - << parser_->nameOfToken(tokType) << " with " + << parser_->tokenName(tokType) << " with " << ident.substr(dot).c_str() << " token:" - << parser_->nameOfToken(methType) << nl; + << parser_->tokenName(methType) << nl; // The field (before the ".") ident.erase(dot); diff --git a/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4 b/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4 index cc7ae238b5..77c1efe91d 100644 --- a/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4 +++ b/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4 @@ -36,7 +36,7 @@ Description } // %include /* - * include[volumeExprLemonParserMacros.m4] + * include volumeExprLemonParserMacros.m4 *include(`volumeExprLemonParserMacros.m4')dnl !done in a comment since many editors have issues matching m4 quotes! */ @@ -45,11 +45,13 @@ Description #include "volumeExprDriver.H" #include "volumeExprParser.H" #include "volumeExprScanner.H" -#include "unitConversion.H" -#include "error.H" #include "volFields.H" #include "surfaceFields.H" #include "pointFields.H" +#include "unitConversion.H" +#include "error.H" +#include "IOmanip.H" +#include "exprOps.H" #include "exprDriverOps.H" #include "GeometricFieldOps.H" #include "fvcReconstruct.H" @@ -752,13 +754,22 @@ dnl*/ // ************************************************************************* // -dnl/* Standard m4 quoting -changequote([`],['])dnl -dnl*/ +/* + * include m4/lemon/parser-methods.m4 +include([m4/lemon/parser-methods.m4])dnl +dnl Can revert to standard m4 quoting +dnl ... Or not changequote([`],['])dnl Revert to standard m4 quoting + */ + %code { +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +parser_code_static_methods(Foam::expressions::volumeExpr::parser) + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::expressions::volumeExpr::parser::stop() @@ -798,27 +809,6 @@ void Foam::expressions::volumeExpr::parser::parse } -Foam::word Foam::expressions::volumeExpr::parser::nameOfToken -( - int tokenId -) const -{ - #ifndef NDEBUG - if - ( - tokenId > 0 - && unsigned(tokenId) < (sizeof(yyTokenName) / sizeof(char*)) - ) - { - return yyTokenName[tokenId]; - } - return ""; - #else - return word(); - #endif -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End of %code diff --git a/src/finiteVolume/expressions/volume/volumeExprParser.H b/src/finiteVolume/expressions/volume/volumeExprParser.H index 7664d10b4e..110ba86ef5 100644 --- a/src/finiteVolume/expressions/volume/volumeExprParser.H +++ b/src/finiteVolume/expressions/volume/volumeExprParser.H @@ -77,6 +77,18 @@ public: } + // Static Member Functions + + //- Return the text name corresponding to the tokenId + static word tokenName(int tokenId); + + //- Print all token names + static void printTokenNames(Ostream& os); + + //- Print all rules + static void printRules(Ostream& os); + + // Member Functions //- Start parsing, with the given driver context @@ -87,9 +99,6 @@ public: //- Push token/value to parser void parse(int tokenId, scanToken* tokenVal); - - //- Return the text name corresponding to the tokenId - word nameOfToken(int tokenId) const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/finiteVolume/expressions/volume/volumeExprScanner.cc b/src/finiteVolume/expressions/volume/volumeExprScanner.cc index c83ed2be63..549cffd0a5 100644 --- a/src/finiteVolume/expressions/volume/volumeExprScanner.cc +++ b/src/finiteVolume/expressions/volume/volumeExprScanner.cc @@ -56,6 +56,10 @@ namespace Foam //- An {int, c_str} enum pairing #define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } +//- An {int, c_str} enum pairing for field types +#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() } + + // Special handling for these known (stashed) look-back types static const Enum lookBehindTokenEnums ({ @@ -92,36 +96,46 @@ static const Enum fieldMethodEnums // Known field-token types -static const Enum fieldTokenEnums -({ -#ifdef TOK_SCALAR_ID - TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID), - TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID), - TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID), - TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID), - TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID), -#else -#error TOK_SCALAR_ID not defined -#endif -#ifdef TOK_SSCALAR_ID - TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID), - TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID), - TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID), - TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID), - TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID), -#else -#warning TOK_SSCALAR_ID not defined -#endif -#ifdef TOK_PSCALAR_ID - TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID), - TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID), - TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID), - TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID), - TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID), -#else -#warning TOK_PSCALAR_ID not defined -#endif -}); +static const Enum& fieldTokenEnums() +{ + static Enum enums_; + + if (enums_.empty()) + { + enums_.append + ({ + #ifdef TOK_SCALAR_ID + FIELD_PAIR(volScalarField, SCALAR_ID), + FIELD_PAIR(volVectorField, VECTOR_ID), + FIELD_PAIR(volTensorField, TENSOR_ID), + FIELD_PAIR(volSymmTensorField, SYM_TENSOR_ID), + FIELD_PAIR(volSphericalTensorField, SPH_TENSOR_ID), + #else + #error TOK_SCALAR_ID not defined + #endif + #ifdef TOK_SSCALAR_ID + FIELD_PAIR(surfaceScalarField, SSCALAR_ID), + FIELD_PAIR(surfaceVectorField, SVECTOR_ID), + FIELD_PAIR(surfaceTensorField, STENSOR_ID), + FIELD_PAIR(surfaceSymmTensorField, SSYM_TENSOR_ID), + FIELD_PAIR(surfaceSphericalTensorField, SSPH_TENSOR_ID), + #else + #warning TOK_SSCALAR_ID not defined + #endif + #ifdef TOK_PSCALAR_ID + FIELD_PAIR(pointScalarField, PSCALAR_ID), + FIELD_PAIR(pointVectorField, PVECTOR_ID), + FIELD_PAIR(pointTensorField, PTENSOR_ID), + FIELD_PAIR(pointSymmTensorField, PSYM_TENSOR_ID), + FIELD_PAIR(pointSphericalTensorField, PSPH_TENSOR_ID), + #else + #warning TOK_PSCALAR_ID not defined + #endif + }); + } + + return enums_; +} // Simple compile-time function name declarations. @@ -134,7 +148,7 @@ static const Enum funcTokenEnums TOKEN_PAIR("ceil", CEIL), TOKEN_PAIR("round", ROUND), #endif -#ifdef TOK_HYPOT /* Can use hypot? */ +#ifdef TOK_HYPOT TOKEN_PAIR("hypot", HYPOT), #endif @@ -273,7 +287,7 @@ static int driverTokenType { const word fieldType(driver_.getFieldClassName(ident)); - int tokType = fieldTokenEnums.get(fieldType, -1); + int tokType = fieldTokenEnums().get(fieldType, -1); if (tokType > 0) { @@ -302,7 +316,7 @@ static int driverTokenType -#line 306 "volumeExprScanner.cc" +#line 320 "volumeExprScanner.cc" static const int volumeExpr_start = 11; static const int volumeExpr_first_final = 11; static const int volumeExpr_error = 0; @@ -310,7 +324,7 @@ static const int volumeExpr_error = 0; static const int volumeExpr_en_main = 11; -#line 444 "volumeExprScanner.rl" +#line 458 "volumeExprScanner.rl" @@ -388,7 +402,7 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " function:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; parser_->parse(tokType, nullptr); return true; @@ -402,7 +416,7 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " as look-behind:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; driver_.resetStashedTokenId(tokType); parser_->parse(tokType, nullptr); @@ -421,7 +435,7 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " token:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; scanTok.name = new Foam::word(std::move(ident)); parser_->parse(tokType, &scanTok); @@ -449,9 +463,9 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident.substr(0, dot).c_str() << " token:" - << parser_->nameOfToken(tokType) << " with " + << parser_->tokenName(tokType) << " with " << ident.substr(dot).c_str() << " token:" - << parser_->nameOfToken(methType) << nl; + << parser_->tokenName(methType) << nl; // The field (before the ".") ident.erase(dot); @@ -537,7 +551,7 @@ bool Foam::expressions::volumeExpr::scanner::process // Initialize FSM variables -#line 541 "volumeExprScanner.cc" +#line 555 "volumeExprScanner.cc" { cs = volumeExpr_start; ts = 0; @@ -545,18 +559,18 @@ bool Foam::expressions::volumeExpr::scanner::process act = 0; } -#line 669 "volumeExprScanner.rl" +#line 683 "volumeExprScanner.rl" /* ^^^ FSM initialization here ^^^ */; -#line 553 "volumeExprScanner.cc" +#line 567 "volumeExprScanner.cc" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr2: -#line 328 "volumeExprScanner.rl" +#line 342 "volumeExprScanner.rl" {te = p+1;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -564,7 +578,7 @@ tr2: }} goto st11; tr4: -#line 328 "volumeExprScanner.rl" +#line 342 "volumeExprScanner.rl" {te = p+1;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -572,7 +586,7 @@ tr4: }} goto st11; tr5: -#line 306 "volumeExprScanner.rl" +#line 320 "volumeExprScanner.rl" {{p = ((te))-1;}{ driver_.parsePosition() = (ts-buf); @@ -596,91 +610,91 @@ tr5: }} goto st11; tr8: -#line 371 "volumeExprScanner.rl" +#line 385 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(EQUAL); }} goto st11; tr9: -#line 425 "volumeExprScanner.rl" +#line 439 "volumeExprScanner.rl" {{p = ((te))-1;}{ EMIT_TOKEN(TENSOR); }} goto st11; tr11: -#line 433 "volumeExprScanner.rl" +#line 447 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(UNIT_TENSOR); }} goto st11; tr12: -#line 374 "volumeExprScanner.rl" +#line 388 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LOR); }} goto st11; tr16: -#line 356 "volumeExprScanner.rl" +#line 370 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(PERCENT); }} goto st11; tr19: -#line 357 "volumeExprScanner.rl" +#line 371 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LPAREN); }} goto st11; tr20: -#line 358 "volumeExprScanner.rl" +#line 372 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(RPAREN); }} goto st11; tr21: -#line 359 "volumeExprScanner.rl" +#line 373 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(TIMES); }} goto st11; tr22: -#line 360 "volumeExprScanner.rl" +#line 374 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(PLUS); }} goto st11; tr23: -#line 362 "volumeExprScanner.rl" +#line 376 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(COMMA); }} goto st11; tr24: -#line 361 "volumeExprScanner.rl" +#line 375 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(MINUS); }} goto st11; tr26: -#line 364 "volumeExprScanner.rl" +#line 378 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(DIVIDE); }} goto st11; tr28: -#line 366 "volumeExprScanner.rl" +#line 380 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(COLON); }} goto st11; tr32: -#line 365 "volumeExprScanner.rl" +#line 379 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(QUESTION); }} goto st11; tr35: -#line 377 "volumeExprScanner.rl" +#line 391 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(BIT_XOR); }} goto st11; tr52: -#line 350 "volumeExprScanner.rl" +#line 364 "volumeExprScanner.rl" {te = p;p--;} goto st11; tr53: -#line 355 "volumeExprScanner.rl" +#line 369 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(NOT); }} goto st11; tr54: -#line 372 "volumeExprScanner.rl" +#line 386 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(NOT_EQUAL); }} goto st11; tr55: -#line 375 "volumeExprScanner.rl" +#line 389 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(BIT_AND); }} goto st11; tr56: -#line 373 "volumeExprScanner.rl" +#line 387 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LAND); }} goto st11; tr57: -#line 363 "volumeExprScanner.rl" +#line 377 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(DOT); }} goto st11; tr60: -#line 306 "volumeExprScanner.rl" +#line 320 "volumeExprScanner.rl" {te = p;p--;{ driver_.parsePosition() = (ts-buf); @@ -704,7 +718,7 @@ tr60: }} goto st11; tr62: -#line 334 "volumeExprScanner.rl" +#line 348 "volumeExprScanner.rl" {te = p;p--;{ // Tokenized ".method" - dispatch '.' and "method" separately driver_.parsePosition() = (ts-buf); @@ -713,23 +727,23 @@ tr62: }} goto st11; tr63: -#line 367 "volumeExprScanner.rl" +#line 381 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(LESS); }} goto st11; tr64: -#line 368 "volumeExprScanner.rl" +#line 382 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(LESS_EQ); }} goto st11; tr65: -#line 369 "volumeExprScanner.rl" +#line 383 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(GREATER); }} goto st11; tr66: -#line 370 "volumeExprScanner.rl" +#line 384 "volumeExprScanner.rl" {te = p+1;{ EMIT_TOKEN(GREATER_EQ); }} goto st11; tr67: -#line 328 "volumeExprScanner.rl" +#line 342 "volumeExprScanner.rl" {te = p;p--;{ driver_.parsePosition() = (ts-buf); dispatch_ident(driver_, scanTok, word(ts, te-ts, false)); @@ -849,43 +863,43 @@ tr69: } goto st11; tr83: -#line 399 "volumeExprScanner.rl" +#line 413 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(ATAN); }} goto st11; tr98: -#line 395 "volumeExprScanner.rl" +#line 409 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(COS); }} goto st11; tr115: -#line 388 "volumeExprScanner.rl" +#line 402 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(LOG); }} goto st11; tr122: -#line 404 "volumeExprScanner.rl" +#line 418 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(MAG); }} goto st11; tr129: -#line 408 "volumeExprScanner.rl" +#line 422 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(NEG); }} goto st11; tr135: -#line 407 "volumeExprScanner.rl" +#line 421 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(POS); }} goto st11; tr154: -#line 394 "volumeExprScanner.rl" +#line 408 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(SIN); }} goto st11; tr170: -#line 391 "volumeExprScanner.rl" +#line 405 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(SQR); }} goto st11; tr186: -#line 396 "volumeExprScanner.rl" +#line 410 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(TAN); }} goto st11; tr192: -#line 425 "volumeExprScanner.rl" +#line 439 "volumeExprScanner.rl" {te = p;p--;{ EMIT_TOKEN(TENSOR); }} goto st11; st11: @@ -896,7 +910,7 @@ st11: case 11: #line 1 "NONE" {ts = p;} -#line 900 "volumeExprScanner.cc" +#line 914 "volumeExprScanner.cc" switch( (*p) ) { case 32: goto st12; case 33: goto st13; @@ -1024,7 +1038,7 @@ st16: if ( ++p == pe ) goto _test_eof16; case 16: -#line 1028 "volumeExprScanner.cc" +#line 1042 "volumeExprScanner.cc" switch( (*p) ) { case 69: goto st5; case 101: goto st5; @@ -1075,7 +1089,7 @@ st19: if ( ++p == pe ) goto _test_eof19; case 19: -#line 1079 "volumeExprScanner.cc" +#line 1093 "volumeExprScanner.cc" switch( (*p) ) { case 46: goto tr58; case 69: goto st5; @@ -1125,212 +1139,212 @@ case 22: tr68: #line 1 "NONE" {te = p+1;} -#line 328 "volumeExprScanner.rl" +#line 342 "volumeExprScanner.rl" {act = 70;} goto st23; tr72: #line 1 "NONE" {te = p+1;} -#line 430 "volumeExprScanner.rl" +#line 444 "volumeExprScanner.rl" {act = 65;} goto st23; tr78: #line 1 "NONE" {te = p+1;} -#line 398 "volumeExprScanner.rl" +#line 412 "volumeExprScanner.rl" {act = 40;} goto st23; tr80: #line 1 "NONE" {te = p+1;} -#line 397 "volumeExprScanner.rl" +#line 411 "volumeExprScanner.rl" {act = 39;} goto st23; tr84: #line 1 "NONE" {te = p+1;} -#line 400 "volumeExprScanner.rl" +#line 414 "volumeExprScanner.rl" {act = 42;} goto st23; tr89: #line 1 "NONE" {te = p+1;} -#line 416 "volumeExprScanner.rl" +#line 430 "volumeExprScanner.rl" {act = 55;} goto st23; tr92: #line 1 "NONE" {te = p+1;} -#line 423 "volumeExprScanner.rl" +#line 437 "volumeExprScanner.rl" {act = 60;} goto st23; tr96: #line 1 "NONE" {te = p+1;} -#line 393 "volumeExprScanner.rl" +#line 407 "volumeExprScanner.rl" {act = 35;} goto st23; tr99: #line 1 "NONE" {te = p+1;} -#line 402 "volumeExprScanner.rl" +#line 416 "volumeExprScanner.rl" {act = 44;} goto st23; tr106: #line 1 "NONE" {te = p+1;} -#line 385 "volumeExprScanner.rl" +#line 399 "volumeExprScanner.rl" {act = 27;} goto st23; tr108: #line 1 "NONE" {te = p+1;} -#line 387 "volumeExprScanner.rl" +#line 401 "volumeExprScanner.rl" {act = 29;} goto st23; tr112: #line 1 "NONE" {te = p+1;} -#line 432 "volumeExprScanner.rl" +#line 446 "volumeExprScanner.rl" {act = 67;} goto st23; tr117: #line 1 "NONE" {te = p+1;} -#line 389 "volumeExprScanner.rl" +#line 403 "volumeExprScanner.rl" {act = 31;} goto st23; tr121: #line 1 "NONE" {te = p+1;} -#line 415 "volumeExprScanner.rl" +#line 429 "volumeExprScanner.rl" {act = 54;} goto st23; tr125: #line 1 "NONE" {te = p+1;} -#line 405 "volumeExprScanner.rl" +#line 419 "volumeExprScanner.rl" {act = 47;} goto st23; tr126: #line 1 "NONE" {te = p+1;} -#line 414 "volumeExprScanner.rl" +#line 428 "volumeExprScanner.rl" {act = 53;} goto st23; tr130: #line 1 "NONE" {te = p+1;} -#line 410 "volumeExprScanner.rl" +#line 424 "volumeExprScanner.rl" {act = 51;} goto st23; tr131: #line 1 "NONE" {te = p+1;} -#line 384 "volumeExprScanner.rl" +#line 398 "volumeExprScanner.rl" {act = 26;} goto st23; tr134: #line 1 "NONE" {te = p+1;} -#line 390 "volumeExprScanner.rl" +#line 404 "volumeExprScanner.rl" {act = 32;} goto st23; tr136: #line 1 "NONE" {te = p+1;} -#line 409 "volumeExprScanner.rl" +#line 423 "volumeExprScanner.rl" {act = 50;} goto st23; tr144: #line 1 "NONE" {te = p+1;} -#line 386 "volumeExprScanner.rl" +#line 400 "volumeExprScanner.rl" {act = 28;} goto st23; tr145: #line 1 "NONE" {te = p+1;} -#line 420 "volumeExprScanner.rl" +#line 434 "volumeExprScanner.rl" {act = 59;} goto st23; tr153: #line 1 "NONE" {te = p+1;} -#line 411 "volumeExprScanner.rl" +#line 425 "volumeExprScanner.rl" {act = 52;} goto st23; tr155: #line 1 "NONE" {te = p+1;} -#line 401 "volumeExprScanner.rl" +#line 415 "volumeExprScanner.rl" {act = 43;} goto st23; tr168: #line 1 "NONE" {te = p+1;} -#line 427 "volumeExprScanner.rl" +#line 441 "volumeExprScanner.rl" {act = 64;} goto st23; tr171: #line 1 "NONE" {te = p+1;} -#line 392 "volumeExprScanner.rl" +#line 406 "volumeExprScanner.rl" {act = 34;} goto st23; tr172: #line 1 "NONE" {te = p+1;} -#line 417 "volumeExprScanner.rl" +#line 431 "volumeExprScanner.rl" {act = 56;} goto st23; tr180: #line 1 "NONE" {te = p+1;} -#line 426 "volumeExprScanner.rl" +#line 440 "volumeExprScanner.rl" {act = 63;} goto st23; tr187: #line 1 "NONE" {te = p+1;} -#line 403 "volumeExprScanner.rl" +#line 417 "volumeExprScanner.rl" {act = 45;} goto st23; tr195: #line 1 "NONE" {te = p+1;} -#line 434 "volumeExprScanner.rl" +#line 448 "volumeExprScanner.rl" {act = 69;} goto st23; tr197: #line 1 "NONE" {te = p+1;} -#line 431 "volumeExprScanner.rl" +#line 445 "volumeExprScanner.rl" {act = 66;} goto st23; tr202: #line 1 "NONE" {te = p+1;} -#line 424 "volumeExprScanner.rl" +#line 438 "volumeExprScanner.rl" {act = 61;} goto st23; tr215: #line 1 "NONE" {te = p+1;} -#line 418 "volumeExprScanner.rl" +#line 432 "volumeExprScanner.rl" {act = 57;} goto st23; tr217: #line 1 "NONE" {te = p+1;} -#line 419 "volumeExprScanner.rl" +#line 433 "volumeExprScanner.rl" {act = 58;} goto st23; st23: if ( ++p == pe ) goto _test_eof23; case 23: -#line 1334 "volumeExprScanner.cc" +#line 1348 "volumeExprScanner.cc" switch( (*p) ) { case 46: goto tr68; case 95: goto tr68; @@ -3097,7 +3111,7 @@ st120: if ( ++p == pe ) goto _test_eof120; case 120: -#line 3101 "volumeExprScanner.cc" +#line 3115 "volumeExprScanner.cc" switch( (*p) ) { case 46: goto tr68; case 58: goto st8; @@ -3839,7 +3853,7 @@ case 10: _out: {} } -#line 671 "volumeExprScanner.rl" +#line 685 "volumeExprScanner.rl" /* ^^^ FSM execution here ^^^ */; if (0 == cs) diff --git a/src/finiteVolume/expressions/volume/volumeExprScanner.rl b/src/finiteVolume/expressions/volume/volumeExprScanner.rl index 0b198b10af..8b7551353a 100644 --- a/src/finiteVolume/expressions/volume/volumeExprScanner.rl +++ b/src/finiteVolume/expressions/volume/volumeExprScanner.rl @@ -54,6 +54,10 @@ namespace Foam //- An {int, c_str} enum pairing #define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name } +//- An {int, c_str} enum pairing for field types +#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() } + + // Special handling for these known (stashed) look-back types static const Enum lookBehindTokenEnums ({ @@ -90,36 +94,46 @@ static const Enum fieldMethodEnums // Known field-token types -static const Enum fieldTokenEnums -({ -#ifdef TOK_SCALAR_ID - TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID), - TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID), - TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID), - TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID), - TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID), -#else -#error TOK_SCALAR_ID not defined -#endif -#ifdef TOK_SSCALAR_ID - TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID), - TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID), - TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID), - TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID), - TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID), -#else -#warning TOK_SSCALAR_ID not defined -#endif -#ifdef TOK_PSCALAR_ID - TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID), - TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID), - TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID), - TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID), - TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID), -#else -#warning TOK_PSCALAR_ID not defined -#endif -}); +static const Enum& fieldTokenEnums() +{ + static Enum enums_; + + if (enums_.empty()) + { + enums_.append + ({ + #ifdef TOK_SCALAR_ID + FIELD_PAIR(volScalarField, SCALAR_ID), + FIELD_PAIR(volVectorField, VECTOR_ID), + FIELD_PAIR(volTensorField, TENSOR_ID), + FIELD_PAIR(volSymmTensorField, SYM_TENSOR_ID), + FIELD_PAIR(volSphericalTensorField, SPH_TENSOR_ID), + #else + #error TOK_SCALAR_ID not defined + #endif + #ifdef TOK_SSCALAR_ID + FIELD_PAIR(surfaceScalarField, SSCALAR_ID), + FIELD_PAIR(surfaceVectorField, SVECTOR_ID), + FIELD_PAIR(surfaceTensorField, STENSOR_ID), + FIELD_PAIR(surfaceSymmTensorField, SSYM_TENSOR_ID), + FIELD_PAIR(surfaceSphericalTensorField, SSPH_TENSOR_ID), + #else + #warning TOK_SSCALAR_ID not defined + #endif + #ifdef TOK_PSCALAR_ID + FIELD_PAIR(pointScalarField, PSCALAR_ID), + FIELD_PAIR(pointVectorField, PVECTOR_ID), + FIELD_PAIR(pointTensorField, PTENSOR_ID), + FIELD_PAIR(pointSymmTensorField, PSYM_TENSOR_ID), + FIELD_PAIR(pointSphericalTensorField, PSPH_TENSOR_ID), + #else + #warning TOK_PSCALAR_ID not defined + #endif + }); + } + + return enums_; +} // Simple compile-time function name declarations. @@ -132,7 +146,7 @@ static const Enum funcTokenEnums TOKEN_PAIR("ceil", CEIL), TOKEN_PAIR("round", ROUND), #endif -#ifdef TOK_HYPOT /* Can use hypot? */ +#ifdef TOK_HYPOT TOKEN_PAIR("hypot", HYPOT), #endif @@ -271,7 +285,7 @@ static int driverTokenType { const word fieldType(driver_.getFieldClassName(ident)); - int tokType = fieldTokenEnums.get(fieldType, -1); + int tokType = fieldTokenEnums().get(fieldType, -1); if (tokType > 0) { @@ -518,7 +532,7 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " function:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; parser_->parse(tokType, nullptr); return true; @@ -532,7 +546,7 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " as look-behind:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; driver_.resetStashedTokenId(tokType); parser_->parse(tokType, nullptr); @@ -551,7 +565,7 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident << " token:" - << parser_->nameOfToken(tokType) << nl; + << parser_->tokenName(tokType) << nl; scanTok.name = new Foam::word(std::move(ident)); parser_->parse(tokType, &scanTok); @@ -579,9 +593,9 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident { DebugInfo << "Emit:" << ident.substr(0, dot).c_str() << " token:" - << parser_->nameOfToken(tokType) << " with " + << parser_->tokenName(tokType) << " with " << ident.substr(dot).c_str() << " token:" - << parser_->nameOfToken(methType) << nl; + << parser_->tokenName(methType) << nl; // The field (before the ".") ident.erase(dot);