Update dictionary calcEntry testing for updated CoCo/R

This commit is contained in:
Mark Olesen
2009-12-21 15:02:33 +01:00
parent ccdbf4735f
commit 8bf3807c3e
8 changed files with 149 additions and 170 deletions

View File

@ -0,0 +1,15 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# this will have to do until we have a makefile rule
if type Coco > /dev/null 2>&1
then
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
calcEntry/calcEntry.atg
else
echo "Coco not installed"
fi
wmake

View File

@ -1,9 +0,0 @@
#/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# this will have to do until we make a makefile rule
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
SimpleCalc.atg

View File

@ -26,8 +26,6 @@ License
#include "calcEntry.H"
#include "dictionary.H"
#include "IStringStream.H"
#include "OStringStream.H"
#include "addToMemberFunctionSelectionTable.H"
#include "ISstream.H"
@ -60,121 +58,33 @@ bool Foam::functionEntries::calcEntry::execute
(
const dictionary& parentDict,
primitiveEntry& entry,
Istream& istr
Istream& is
)
{
static const int maxLen = 1024;
static const int errLen = 80; // truncate error message for readability
static char buf[maxLen];
ISstream& is = dynamicCast<ISstream>(istr);
// get the { ... } argument without the enclosing brace brackets
//
// THIS NEEDS REWORKING (LATER) ...
char c = 0;
if (!is.read(c).good() || c != token::BEGIN_BLOCK)
{
is.setBad();
FatalIOErrorIn("functionEntries::calcEntry::execute()", is)
<< "Expected a '" << token::BEGIN_BLOCK
<< "', found '" << c << "'" << exit(FatalIOError);
return false;
}
register int nChar = 0;
buf[nChar++] = token::BEGIN_BLOCK;
int listDepth = 1; // already saw the first '{'
while (is.get(c).good())
{
buf[nChar++] = c;
if (nChar == maxLen)
{
buf[errLen] = '\0';
FatalIOErrorIn("functionEntries::calcEntry::execute()", is)
<< "argument \"" << buf << "...\"\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return false;
}
// handle nested blocks, even if we don't know what they'd
// be useful for
if (c == token::BEGIN_BLOCK)
{
++listDepth;
}
else if (c == token::END_BLOCK)
{
if (--listDepth == 0)
{
// done reading - overwrite the final '}'
// --nChar;
break;
}
}
}
buf[nChar] = '\0';
// emit some info
Info<< "grabbed " << nChar << " characters:" << nl
<< "----------\n"
<< buf << nl
<< "----------\n"
<< nl;
std::istream& iss = dynamicCast<ISstream>(is).stdStream();
// define parser error handler
CocoParserErrors<calcEntryInternal::Errors>
myErrorHandler("calcEntry::Parser--");
myErrorHandler("calcEntryInternal::Parser");
calcEntryInternal::Scanner scanner(buf, nChar);
calcEntryInternal::Scanner scanner(iss);
calcEntryInternal::Parser parser(&scanner, &myErrorHandler);
// Attach dictionary context
parser.dict(parentDict);
// Attach scalar functions
// parser.functions(parentDict);
parser.Parse();
// Info<<"got: " << parser.Result() << endl;
// make a small input list to contain the answer
tokenList tokens(2);
tokens[0] = parser.Result();
tokens[1] = token::END_STATEMENT;
// Info<<"tokens[0] = " << tokens[0].info() <<nl;
// Info<<"tokens[1] = " << tokens[1].info() <<nl;
//
// {
// const tokenList& toks = entry;
//
// forAll(toks, tokI)
// {
// Info<< tokI <<":= " << toks[tokI].info() << endl;
// }
// }
entry.read(parentDict, ITstream("ParserResult", tokens)());
ITstream its("ParserResult", tokens);
entry.read(parentDict, its);
// Info<< "size: " << entry.size() << endl;
// entry = newente;
// entry.print(Info);
/// const tokenList& toks = entry;
///
/// forAll(toks, tokI)
/// {
/// Info<< tokI <<":= " << toks[tokI].info() << endl;
/// }
///
return true;
}

View File

@ -2,9 +2,7 @@
compile with:
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
-prefix calcEntry \
-namespace Foam::functionEntries::calcEntryInternal \
SimpleCalc.atg
calcEntry.atg
-------------------------------------------------------------------------*/
#include "dictionary.H"
@ -13,9 +11,10 @@
#include "wchar.H"
COMPILER SimpleCalc
COMPILER calcEntry
$prefix=calcEntry
$namespace=Foam::functionEntries::calcEntryInternal
$eof=true // grammar handles eof itself
// Simple four function calculator for OpenFOAM dictionaries
@ -25,9 +24,13 @@ $namespace=Foam::functionEntries::calcEntryInternal
//! The parent dictionary
mutable dictionary* dict_;
//! Track that parent dictionary was set
bool hasDict_;
//! The calculation result
scalar val;
//! token -> scalar
scalar getScalar() const
{
@ -43,11 +46,11 @@ $namespace=Foam::functionEntries::calcEntryInternal
return s;
}
//! attach a dictionary
void dict(const dictionary& dict) const
void dict(const dictionary& dict)
{
dict_ = const_cast<dictionary*>(&dict);
hasDict_ = true;
}
@ -56,11 +59,11 @@ $namespace=Foam::functionEntries::calcEntryInternal
{
scalar dictValue = 0;
if (!dict_)
if (!hasDict_)
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
"calcEntry::getDictEntry() const"
) << "No dictionary attached!"
<< exit(FatalError);
@ -84,13 +87,22 @@ $namespace=Foam::functionEntries::calcEntryInternal
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict())
{
if (entryPtr->stream().size() != 1)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " has "
<< entryPtr->stream().size() << " values in dictionary "
<< exit(FatalError);
}
entryPtr->stream() >> dictValue;
}
else
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError);
}
@ -105,7 +117,7 @@ $namespace=Foam::functionEntries::calcEntryInternal
}
// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * //
/*---------------------------------------------------------------------------*/
CHARACTERS
letter = 'A'..'Z' + 'a'..'z'.
@ -148,38 +160,49 @@ number =
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
// ignore unprintables
IGNORE ANY - printable
IGNORE cr + lf + tab
// * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * //
PRODUCTIONS
SimpleCalc (. val = 0;
if (debug){Info<<"start val"<< nl;}
calcEntry (. val = 0;
if (debug){Info<<"start val pos:"<< t->pos << nl;}
.)
=
( '{' Expr<val> '}' | Expr<val> )
EOF
'{' Expr<val> '}' (.
if (debug){
Info<<"end {} at pos:"<< t->pos
<<" val:"<< t->val
<<" len:"<< coco_string_length(t->val)
<<" la pos:"<< la->pos << nl;
}
// reposition to immediately after the closing '}'
scanner->buffer->SetPos
(
t->pos + coco_string_length(t->val)
);
.)
| ( Expr<val> EOF )
.
/*---------------------------------------------------------------------------*/
Expr<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< nl;}
if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
.)
=
Term<val>
{
"+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 <<nl;}
"+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
val += val2;
if (debug) {Info<<"="<< val << nl;}
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
| "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2 <<nl;}
| "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
val -= val2;
if (debug) {Info<<"="<< val << nl;}
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
}
.
@ -188,18 +211,18 @@ Expr<scalar& val> (. scalar val2 = 0;
/*---------------------------------------------------------------------------*/
Term<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< nl;}
if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
.)
=
Factor<val>
{
"*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2 << nl;}
"*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
val *= val2;
if (debug) {Info<<"="<< val << nl; }
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
| "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2 << nl;}
| "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
val /= val2;
if (debug) {Info<<"="<< val << nl; }
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.)
}
.
@ -209,20 +232,21 @@ Term<scalar& val> (. scalar val2 = 0;
Factor<scalar& val>
=
variable (. val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<<nl;}
if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
.)
| number (. val = getScalar();
if (debug) {Info<<"got num:"<<val<<nl;}
if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
.)
| '-' '(' Expr<val> ')' (. val = -val;
if (debug) {Info<<"inv:"<<val<<nl;}
if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
.)
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
.)
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<<nl;} .)
.
/*---------------------------------------------------------------------------*/
END SimpleCalc.
END calcEntry.
// ************************************************************************* //

View File

@ -90,39 +90,51 @@ bool Parser::WeakSeparator(int n, int syFol, int repFol) {
}
void Parser::SimpleCalc() {
void Parser::calcEntry() {
val = 0;
if (debug){Info<<"start val"<< nl;}
if (debug){Info<<"start val pos:"<< t->pos << nl;}
if (la->kind == 5) {
Get();
Expr(val);
Expect(6);
if (debug){
Info<<"end {} at pos:"<< t->pos
<<" val:"<< t->val
<<" len:"<< coco_string_length(t->val)
<<" la pos:"<< la->pos << nl;
}
// reposition to immediately after the closing '}'
scanner->buffer->SetPos
(
t->pos + coco_string_length(t->val)
);
} else if (StartOf(1)) {
Expr(val);
Expect(0);
} else SynErr(14);
Expect(0);
}
void Parser::Expr(scalar& val) {
scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< nl;}
if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
Term(val);
while (la->kind == 7 || la->kind == 8) {
if (la->kind == 7) {
Get();
Term(val2);
if (debug) {Info<<"+Term:"<<val2 <<nl;}
if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
val += val2;
if (debug) {Info<<"="<< val << nl;}
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} else {
Get();
Term(val2);
if (debug) {Info<<"-Term:"<<val2 <<nl;}
if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
val -= val2;
if (debug) {Info<<"="<< val << nl;}
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
}
}
@ -130,23 +142,23 @@ void Parser::Expr(scalar& val) {
void Parser::Term(scalar& val) {
scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< nl;}
if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
Factor(val);
while (la->kind == 9 || la->kind == 10) {
if (la->kind == 9) {
Get();
Factor(val2);
if (debug) {Info<<"*Factor:"<<val2 << nl;}
if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
val *= val2;
if (debug) {Info<<"="<< val << nl; }
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} else {
Get();
Factor(val2);
if (debug) {Info<<"/Factor:"<<val2 << nl;}
if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
val /= val2;
if (debug) {Info<<"="<< val << nl; }
if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
}
}
@ -156,12 +168,12 @@ void Parser::Factor(scalar& val) {
if (la->kind == 3) {
Get();
val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<<nl;}
if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 4) {
Get();
val = getScalar();
if (debug) {Info<<"got num:"<<val<<nl;}
if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 8) {
Get();
@ -169,13 +181,14 @@ void Parser::Factor(scalar& val) {
Expr(val);
Expect(12);
val = -val;
if (debug) {Info<<"inv:"<<val<<nl;}
if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 11) {
Get();
Expr(val);
Expect(12);
if (debug){Info<<"got Expr:"<<val<<nl;}
if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
} else SynErr(15);
}
@ -189,9 +202,9 @@ void Parser::Parse() {
la = dummyToken = new Token();
la->val = coco_string_create(L"Dummy Token");
Get();
SimpleCalc();
calcEntry();
// let grammar deal with end-of-file expectations
Expect(0);
}
@ -272,7 +285,7 @@ wchar_t* Errors::strerror(int n)
case 11: s = coco_string_create(L"\"(\" expected"); break;
case 12: s = coco_string_create(L"\")\" expected"); break;
case 13: s = coco_string_create(L"??? expected"); break;
case 14: s = coco_string_create(L"invalid SimpleCalc"); break;
case 14: s = coco_string_create(L"invalid calcEntry"); break;
case 15: s = coco_string_create(L"invalid Factor"); break;
default:

View File

@ -82,9 +82,13 @@ static const int debug = 0;
//! The parent dictionary
mutable dictionary* dict_;
//! Track that parent dictionary was set
bool hasDict_;
//! The calculation result
scalar val;
//! token -> scalar
scalar getScalar() const
{
@ -100,11 +104,11 @@ static const int debug = 0;
return s;
}
//! attach a dictionary
void dict(const dictionary& dict) const
void dict(const dictionary& dict)
{
dict_ = const_cast<dictionary*>(&dict);
hasDict_ = true;
}
@ -113,11 +117,11 @@ static const int debug = 0;
{
scalar dictValue = 0;
if (!dict_)
if (!hasDict_)
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
"calcEntry::getDictEntry() const"
) << "No dictionary attached!"
<< exit(FatalError);
@ -141,13 +145,22 @@ static const int debug = 0;
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict())
{
if (entryPtr->stream().size() != 1)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " has "
<< entryPtr->stream().size() << " values in dictionary "
<< exit(FatalError);
}
entryPtr->stream() >> dictValue;
}
else
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError);
}
@ -162,7 +175,7 @@ static const int debug = 0;
}
// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * //
/*---------------------------------------------------------------------------*/
@ -175,7 +188,7 @@ static const int debug = 0;
~Parser(); //!< Destructor - cleanup errors and dummyToken
void SemErr(const wchar_t* msg); //!< Handle semantic error
void SimpleCalc();
void calcEntry();
void Expr(scalar& val);
void Term(scalar& val);
void Factor(scalar& val);

View File

@ -800,7 +800,7 @@ void Scanner::AppendVal(Token* tok) {
Token* Scanner::NextToken() {
while (ch == ' ' ||
ch <= 31 || (ch >= 127 && ch <= 65535)
(ch >= 9 && ch <= 10) || ch == 13
) NextCh();
if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken();
t = CreateToken();

View File

@ -14,8 +14,11 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
x 10 /* what ever */ 20;
flowRatePerHour 720;
x 10;
y 20;
z t s v;
// z #test{ // this
// 123 - 456
// // comments // are
@ -26,8 +29,18 @@ y 20;
// + 1 /*100 */ 10
// };
p #calc{ 1 + 2 + 10 * 15 + $x - $y };
p this calculation #calc{
1 + 2 + 10 * 15 +
$x - $y
// $x + $y
}
is done inplace;
foo 30;
flowRate #calc{ $flowRatePerHour / 3600};
xxx yyy;
foo 30;
bar 15;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //