Commit 74b12c6a authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: improved separation of scanner/parser debug selection

- now use debug 2 for scanner and debug 4 for parser.
  Provided better feedback about what is being parsed (debug mode)

- relocate debug application to applications/tools/foamExprParserInfo
parent 9ab75c5c
......@@ -19,4 +19,7 @@ wmakeCheckPwd "$WM_PROJECT_DIR/applications" 2>/dev/null || {
wmake -all $targetType solvers
wmake -all $targetType utilities
# Optional
## wmake -all $targetType tools
#------------------------------------------------------------------------------
Test-parserInfo.C
EXE = $(FOAM_USER_APPBIN)/Test-parserInfo
The applications/tools directory contains tools that may be useful for
developers or advanced users, but which will not normally be built.
The user should note that the types of tools, their behaviour and
syntax are subject to much more fluctuation than regular utilities.
foamExprParserInfo.C
EXE = $(FOAM_APPBIN)/foamExprParserInfo
......@@ -23,8 +23,51 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
foamExprParserInfo
Group
grpTools
Description
Output some (expressions) parser information
Display token names or rules for specified expression parsers.
In the Lemon grammar, terminals (uppercase) are listed first.
Non-terminals (lowercase) are listed second.
The current OpenFOAM grammar short naming conventions:
- svalue : scalar value
- sfield : scalar field
- lfield : logic field
- vfield : vector field
- tfield : tensor field
- hfield : sphericalTensor field
- yfield : symmTensor field
.
Prefixes: 's' (surface) or 'p' (point).
For example, psfield for a point scalar field
Usage
\b foamExprParserInfo [OPTION]
Options:
- \par -rules
Print parser rules
- \par -tokens
Print token names (default)
- \par -all
Display information for all parsers
- \par -field
Field expression parser information
- \par -patch
Patch expression parser information
- \par -volume
Volume expression parser information
\*---------------------------------------------------------------------------*/
......@@ -48,13 +91,13 @@ void printInformation
{
if (printNames)
{
os << nl << name << " tokenNames:" << nl;
os << nl << "# Tokens for " << name << nl;
Parser::printTokenNames(os);
}
if (printRules)
{
os << nl << name << " rules:" << nl;
os << nl << "# Rules for " << name << nl;
Parser::printRules(os);
}
}
......@@ -66,32 +109,47 @@ void printInformation
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::setAdvanced("case"); // Hide -case : has no meaning here
argList::addNote
(
"Display token names or rules for specified expression parser(s)."
" Without options, displays everything."
"Display token names or rules for specified expression parsers.\n"
"In the Lemon grammar, terminals (uppercase) are listed first.\n"
"Non-terminals (lowercase) are listed second.\n \n"
"The current OpenFOAM grammar short naming conventions:\n"
" * svalue : scalar value\n"
" * sfield : scalar field\n"
" * lfield : logic field\n"
" * vfield : vector field\n"
" * tfield : tensor field\n"
" * hfield : sphericalTensor field\n"
" * yfield : symmTensor field\n"
" \n"
"Prefixes: 's' (surface) or 'p' (point).\n"
"Eg, psfield for a point scalar field\n"
);
argList::addBoolOption("rules", "Print parser rules");
argList::addBoolOption("tokens", "Print token names");
argList::addBoolOption("tokens", "Print token names (default)");
argList::addBoolOption("field", "Field expression parser");
argList::addBoolOption("patch", "Patch expression parser");
argList::addBoolOption("volume", "Volume expression parser");
argList::addBoolOption("all", "Display information for all parsers");
argList::addBoolOption("field", "Field expression parser information");
argList::addBoolOption("patch", "Patch expression parser information");
argList::addBoolOption("volume", "Volume expression parser information");
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");
const bool all = args.found("all");
const bool printRules = args.found("rules");
const bool printNames = args.found("tokens") || !printRules;
label count = 0;
if (all || args.found("field"))
{
printInformation<Foam::expressions::fieldExpr::parser>
++count;
printInformation<expressions::fieldExpr::parser>
(
Info,
"field",
......@@ -102,7 +160,8 @@ int main(int argc, char *argv[])
if (all || args.found("patch"))
{
printInformation<Foam::expressions::patchExpr::parser>
++count;
printInformation<expressions::patchExpr::parser>
(
Info,
"patch",
......@@ -113,7 +172,8 @@ int main(int argc, char *argv[])
if (all || args.found("volume"))
{
printInformation<Foam::expressions::volumeExpr::parser>
++count;
printInformation<expressions::volumeExpr::parser>
(
Info,
"volume",
......@@ -122,7 +182,15 @@ int main(int argc, char *argv[])
);
}
Info<< "\nEnd\n" << endl;
if (!count)
{
InfoErr
<< "Error: no parser selected." << nl
<< "See '" << args.executable() << " -help' for usage" << nl
<< nl;
return 1;
}
return 0;
}
......
......@@ -542,6 +542,7 @@ DebugSwitches
faceZone 0;
fan 0;
featureEdgeMesh 0;
fieldExpr 0;
fieldToCell 0;
file 0;
fileName 2;
......@@ -759,6 +760,7 @@ DebugSwitches
partialSlip 0;
passiveParticle 0;
patch 0;
patchExpr 0;
patchToFace 0;
patchZones 0;
pdf 0;
......@@ -966,6 +968,7 @@ DebugSwitches
volTensorField::Internal 0;
volVectorField 0;
volVectorField::Internal 0;
volumeExpr 0;
vtk 0;
walkPatch 0;
wall 0;
......
......@@ -395,7 +395,8 @@ public:
// Evaluation
//- Execute the parser
//- Execute the parser.
// The return value currently has no meaning.
virtual unsigned parse
(
const std::string& expr,
......
......@@ -39,6 +39,9 @@ Description
rand | Random field | 0/1 |
\endtable
Note
Use namespace debug switch \c fieldExpr for scanner (2), parser (4)
SourceFiles
fieldExprDriver.C
fieldExprDriverFields.C
......@@ -133,6 +136,7 @@ public:
using genericRagelLemonDriver::content;
//- Execute the parser
// The return value currently has no meaning.
virtual unsigned parse
(
const std::string& expr,
......
......@@ -381,7 +381,7 @@ void Foam::expressions::fieldExpr::parser::start(parseDriver& driver_)
this->stop();
lemon_ = ParseAlloc(::operator new, &driver_);
if (debug || driver_.debugParser())
if ((debug & 0x4) || driver_.debugParser())
{
#ifndef NDEBUG
ParseTrace(stderr, const_cast<char*>(prompt_));
......
......@@ -42,7 +42,7 @@ Description
// Debugging to stderr
#undef DebugInfo
#define DebugInfo if (debug) InfoErr
#define DebugInfo if (debug & 0x2) InfoErr
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -157,7 +157,7 @@ static int driverTokenType
#define EMIT_TOKEN(T) \
driver_.parsePosition() = (ts-buf); \
DebugInfo<< STRINGIFY(T) << ": " << driver_.parsePosition() << nl; \
DebugInfo<< STRINGIFY(T) << " at " << driver_.parsePosition() << nl; \
parser_->parse(TOKEN_OF(T), nullptr); \
driver_.parsePosition() = (p-buf);
......@@ -349,9 +349,14 @@ bool Foam::expressions::fieldExpr::scanner::process
// Save debug value
const int oldDebug = debug;
if (driver_.debugScanner())
if (driver_.debugScanner()) { debug |= 0x2; }
if (driver_.debugParser()) { debug |= 0x4; }
if (debug & 0x6)
{
debug |= 4;
InfoErr
<< "Begin parse {"
<< str.substr(strBeg, strLen).c_str() << '}' << nl;
}
if (!parser_)
......@@ -383,12 +388,12 @@ bool Foam::expressions::fieldExpr::scanner::process
// Scan token type
scanToken scanTok;
// Ragel token start/end (required naming)
// Token start/end (Ragel naming)
const char* ts;
const char* te;
// Local buffer data.
// - p, pe, eof are required Ragel naming
// - p, pe, eof are Ragel naming
// - buf is our own naming
const char* buf = &(str[strBeg]);
......@@ -398,7 +403,7 @@ bool Foam::expressions::fieldExpr::scanner::process
// Initialize FSM variables
#line 402 "fieldExprScanner.cc"
#line 407 "fieldExprScanner.cc"
{
cs = fieldExpr_start;
ts = 0;
......@@ -406,11 +411,11 @@ bool Foam::expressions::fieldExpr::scanner::process
act = 0;
}
#line 528 "fieldExprScanner.rl"
#line 533 "fieldExprScanner.rl"
/* ^^^ FSM initialization here ^^^ */;
#line 414 "fieldExprScanner.cc"
#line 419 "fieldExprScanner.cc"
{
if ( p == pe )
goto _test_eof;
......@@ -748,7 +753,7 @@ st11:
case 11:
#line 1 "NONE"
{ts = p;}
#line 752 "fieldExprScanner.cc"
#line 757 "fieldExprScanner.cc"
switch( (*p) ) {
case 32: goto st12;
case 33: goto st13;
......@@ -875,7 +880,7 @@ st16:
if ( ++p == pe )
goto _test_eof16;
case 16:
#line 879 "fieldExprScanner.cc"
#line 884 "fieldExprScanner.cc"
switch( (*p) ) {
case 69: goto st5;
case 101: goto st5;
......@@ -926,7 +931,7 @@ st19:
if ( ++p == pe )
goto _test_eof19;
case 19:
#line 930 "fieldExprScanner.cc"
#line 935 "fieldExprScanner.cc"
switch( (*p) ) {
case 46: goto tr57;
case 69: goto st5;
......@@ -1163,7 +1168,7 @@ st23:
if ( ++p == pe )
goto _test_eof23;
case 23:
#line 1167 "fieldExprScanner.cc"
#line 1172 "fieldExprScanner.cc"
switch( (*p) ) {
case 46: goto tr67;
case 95: goto tr67;
......@@ -2929,7 +2934,7 @@ st120:
if ( ++p == pe )
goto _test_eof120;
case 120:
#line 2933 "fieldExprScanner.cc"
#line 2938 "fieldExprScanner.cc"
switch( (*p) ) {
case 46: goto tr67;
case 58: goto st8;
......@@ -3350,7 +3355,7 @@ case 10:
_out: {}
}
#line 530 "fieldExprScanner.rl"
#line 535 "fieldExprScanner.rl"
/* ^^^ FSM execution here ^^^ */;
if (0 == cs)
......@@ -3367,6 +3372,11 @@ case 10:
parser_->parse(0, nullptr);
parser_->stop();
if (debug & 0x6)
{
InfoErr<< "Done parse." << nl;
}
// Restore debug value
debug = oldDebug;
......
......@@ -40,7 +40,7 @@ Description
// Debugging to stderr
#undef DebugInfo
#define DebugInfo if (debug) InfoErr
#define DebugInfo if (debug & 0x2) InfoErr
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -155,7 +155,7 @@ static int driverTokenType
#define EMIT_TOKEN(T) \
driver_.parsePosition() = (ts-buf); \
DebugInfo<< STRINGIFY(T) << ": " << driver_.parsePosition() << nl; \
DebugInfo<< STRINGIFY(T) << " at " << driver_.parsePosition() << nl; \
parser_->parse(TOKEN_OF(T), nullptr); \
driver_.parsePosition() = (p-buf);
......@@ -477,9 +477,14 @@ bool Foam::expressions::fieldExpr::scanner::process
// Save debug value
const int oldDebug = debug;
if (driver_.debugScanner())
if (driver_.debugScanner()) { debug |= 0x2; }
if (driver_.debugParser()) { debug |= 0x4; }
if (debug & 0x6)
{
debug |= 4;
InfoErr
<< "Begin parse {"
<< str.substr(strBeg, strLen).c_str() << '}' << nl;
}
if (!parser_)
......@@ -511,12 +516,12 @@ bool Foam::expressions::fieldExpr::scanner::process
// Scan token type
scanToken scanTok;
// Ragel token start/end (required naming)
// Token start/end (Ragel naming)
const char* ts;
const char* te;
// Local buffer data.
// - p, pe, eof are required Ragel naming
// - p, pe, eof are Ragel naming
// - buf is our own naming
const char* buf = &(str[strBeg]);
......@@ -543,6 +548,11 @@ bool Foam::expressions::fieldExpr::scanner::process
parser_->parse(0, nullptr);
parser_->stop();
if (debug & 0x6)
{
InfoErr<< "Done parse." << nl;
}
// Restore debug value
debug = oldDebug;
......
......@@ -30,13 +30,12 @@ Description
Driver for patch expressions
In addition to the standard mathematical functions, operations and
logical and relational operations, the volume expression support the
logical and relational operations, the patch expressions support the
following driver-specific functions:
Functions
\table
Function | Description | Number of arguments |
vol | The cell volumes | 0 |
pos | The face centres | 0 |
pts | The face points | 0 |
area | The face area magnitudes | 0 |
......@@ -49,6 +48,10 @@ Description
rand | Random field | 0/1 |
\endtable
Note
Use namespace debug switch \c patchExpr for scanner (2), parser (4)
or dictionary controls as per Foam::expressions::exprDriver.
SourceFiles
patchExprDriver.C
patchExprDriverFields.C
......@@ -176,7 +179,8 @@ public:
//- Perform parsing on (sub) string
using genericRagelLemonDriver::content;
//- Execute the parser
//- Execute the parser.
// The return value currently has no meaning.
virtual unsigned parse
(
const std::string& expr,
......
......@@ -527,7 +527,7 @@ void Foam::expressions::patchExpr::parser::start(parseDriver& driver_)
this->stop();
lemon_ = ParseAlloc(::operator new, &driver_);
if (debug || driver_.debugParser())
if ((debug & 0x4) || driver_.debugParser())
{
#ifndef NDEBUG
ParseTrace(stderr, const_cast<char*>(prompt_));
......
......@@ -42,7 +42,7 @@ Description
// Debugging to stderr
#undef DebugInfo
#define DebugInfo if (debug) InfoErr
#define DebugInfo if (debug & 0x2) InfoErr
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -281,7 +281,7 @@ static int driverTokenType
#define EMIT_TOKEN(T) \
driver_.parsePosition() = (ts-buf); \
DebugInfo<< STRINGIFY(T) << ": " << driver_.parsePosition() << nl; \
DebugInfo<< STRINGIFY(T) << " at " << driver_.parsePosition() << nl; \
parser_->parse(TOKEN_OF(T), nullptr); \
driver_.parsePosition() = (p-buf);
......@@ -473,9 +473,14 @@ bool Foam::expressions::patchExpr::scanner::process
// Save debug value
const int oldDebug = debug;
if (driver_.debugScanner())
if (driver_.debugScanner()) { debug |= 0x2; }
if (driver_.debugParser()) { debug |= 0x4; }
if (debug & 0x6)
{
debug |= 4;
InfoErr
<< "Begin parse {"
<< str.substr(strBeg, strLen).c_str() << '}' << nl;
}
if (!parser_)
......@@ -507,12 +512,12 @@ bool Foam::expressions::patchExpr::scanner::process
// Scan token type
scanToken scanTok;
// Ragel token start/end (required naming)
// Token start/end (Ragel naming)
const char* ts;
const char* te;
// Local buffer data.
// - p, pe, eof are required Ragel naming
// - p, pe, eof are Ragel naming
// - buf is our own naming
const char* buf = &(str[strBeg]);
......@@ -522,7 +527,7 @@ bool Foam::expressions::patchExpr::scanner::process
// Initialize FSM variables
#line 526 "patchExprScanner.cc"
#line 531 "patchExprScanner.cc"
{
cs = patchExpr_start;
ts = 0;
......@@ -530,11 +535,11 @@ bool Foam::expressions::patchExpr::scanner::process
act = 0;
}
#line 654 "patchExprScanner.rl"
#line 659 "patchExprScanner.rl"
/* ^^^ FSM initialization here ^^^ */;
#line 538 "patchExprScanner.cc"
#line 543 "patchExprScanner.cc"
{
if ( p == pe )
goto _test_eof;
......@@ -881,7 +886,7 @@ st11:
case 11:
#line 1 "NONE"
{ts = p;}
#line 885 "patchExprScanner.cc"
#line 890 "patchExprScanner.cc"
switch( (*p) ) {
case 32: goto st12;
case 33: goto st13;
......@@ -1009,7 +1014,7 @@ st16:
if ( ++p == pe )
goto _test_eof16;
case 16:
#line 1013 "patchExprScanner.cc"
#line 1018 "patchExprScanner.cc"
switch( (*p) ) {
case 69: goto st5;
case 101: goto st5;
......@@ -1060,7 +1065,7 @@ st19:
if ( ++p == pe )
goto _test_eof19;
case 19:
#line 1064 "patchExprScanner.cc"
#line 1069 "patchExprScanner.cc"
switch( (*p) ) {
case 46: goto tr58;
case 69: goto st5;
......@@ -1315,7 +1320,7 @@ st23:
if ( ++p == pe )
goto _test_eof23;
case 23:
#line 1319 "patchExprScanner.cc"
#line 1324 "patchExprScanner.cc"
switch( (*p) ) {
case 46: goto tr68;
case 95: goto tr68;
......@@ -3082,7 +3087,7 @@ st120:
if ( ++p == pe )
goto _test_eof120;
case 120:
#line 3086 "patchExprScanner.cc"
#line 3091 "patchExprScanner.cc"
switch( (*p) ) {
case 46: goto tr68;
case 58: goto st8;
......@@ -3824,7 +3829,7 @@ case 10:
_out: {}
}
#line 656 "patchExprScanner.rl"
#line 661 "patchExprScanner.rl"
/* ^^^ FSM execution here ^^^ */;
if (0 == cs)
......@@ -3841,6 +3846,11 @@ case 10:
parser_->parse(0, nullptr);
parser_->stop();
if (debug & 0x6)
{
InfoErr<< "Done parse." << nl;