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);