void getMap(symbolMap &out) { for (auto it = tokout->begin(); it != tokout->end(); it++) { string &sym = (*it); it++; it++; // skip { while (*it != "}") { string key = *it; it++; it++; // skip : string val = *it; it++; it++; // skip ; out[sym][key] = val; } } }
// get to the next non-whitespace that equals tok void match(char tok) { skipws(); if (tok != input[offset]) throw syntax_error(string("expected ") + tok, line, linepos); incoffs(); char s[2]; s[0] = tok; s[1] = 0; tokout->push_back(s); }
void Foam::primitiveEntry::insert ( const tokenList& varTokens, const label posI ) { tokenList& tokens = *this; if (varTokens.empty()) { label end = tokens.size() - 1; for (label j=posI; j<end; j++) { tokens[j] = tokens[j+1]; } tokens.setSize(tokens.size() - 1); } else if (varTokens.size() > 1) { tokens.setSize(tokens.size() + varTokens.size() - 1); label end = tokens.size() - 1; label offset = varTokens.size() - 1; for (label j=end; j>posI; j--) { tokens[j] = tokens[j-offset]; } } forAll(varTokens, j) { tokens[posI + j] = varTokens[j]; } }
// read a name void readid() { string tok; skipws(); if (offset >= input.length() || istok(input[offset])) throw syntax_error("expected identifier", line, linepos); while (offset < input.length() && !isspace(input[offset]) && !istok(input[offset])) { tok += input[offset]; incoffs(); } tokout->push_back(tok); }
void Tokenizer::getTokens( const char * prog,tokenList & tokens) throw (Exception *) { int cursor=0; int line=1; Token * obj; do { obj=readNextToken(prog,cursor,line,tokens); if (obj!=NULL) { Token * t=dynamic_cast<Token*>(obj); if (t) t->setLine(line); tokens.push_back(obj); Token::addReference(obj); } } while (!dynamic_cast<TEndScript *>(obj)); }
void Foam::equationReader::removePowExponents ( const label index, tokenList& tl, PtrList<equationOperation>& map, labelList& opLvl, labelList& pl ) const { // Remove pow(a,b) exponent part 'b' from an equation and create a sub- // equation. label tokenI(0); while (tokenI < map.size()) { if (map[tokenI].operation() == equationOperation::otpow) { // Found a 'pow('. Look for ','; fail on ')', or end of list // pl checks ensure the ',' or ')' relate to the 'pow(', and not // another function / parethesis const label powFoundAt(tokenI); const label pLvl(pl[tokenI]); while ((opLvl[tokenI] != 5) || (pl[tokenI] != pLvl)) { if ( ((opLvl[tokenI] == -4) && (pl[tokenI] == pLvl)) || (tokenI == (map.size() - 1)) ) { OStringStream description; description << "pow() function takes two arguments."; fatalParseError ( index, tl, powFoundAt, tokenI, "equationReader::removePowExponents", description ); } tokenI++; } // Found 'pow( ... ,' look for ')', fail on list end const label commaFoundAt(tokenI); while ((opLvl[tokenI] != -4) || (pl[tokenI] != pLvl)) { if (tokenI == (map.size() - 1)) { OStringStream description; description << "Can't find closing parenthesis for " << "pow() function."; fatalParseError ( index, tl, powFoundAt, tokenI, "equationReader::removePowExponents", description ); } tokenI++; } const label closeFoundAt(tokenI); // Ignore if the exponent is only 1 token if ((closeFoundAt - commaFoundAt) > 2) { // Now create sub-equation OStringStream subEqnStream; for ( label subTokenI(commaFoundAt + 1); subTokenI < closeFoundAt; subTokenI++ ) { if ( tl[subTokenI].isPunctuation() && (tl[subTokenI].pToken() == token::COLON)) { subEqnStream << "^"; } else { subEqnStream << tl[subTokenI]; } } string subEqnRawText(subEqnStream.str()); const equation& eqn(operator[](index)); equation subEqn ( eqn.name() + "_powExponent_" + name(powFoundAt), subEqnRawText, eqn.overrideDimensions(), eqn.changeDimensions() ); bool eqnCreated(false); for (label eqnI(0); eqnI < size(); eqnI++) { const equation& eqnTest(operator[](eqnI)); if (eqnTest.name() == subEqn.name()) { clearEquation(eqnI); eqnTest.setRawText(subEqn.rawText()); eqnTest.setOverrideDimensions ( subEqn.overrideDimensions() ); eqnTest.setChangeDimensions ( eqnTest.changeDimensions() ); eqnCreated = true; } } if (!eqnCreated) { createEquation(subEqn); } // Change commaFoundAt + 1 entry to reflect new subEquation // reference tl[commaFoundAt + 1] = token(subEqn.name()); map.set ( commaFoundAt + 1, new equationOperation(findSource(subEqn.name())) ); opLvl[commaFoundAt + 1] = 0; pl[commaFoundAt + 1] = pl[commaFoundAt]; // Remove the subEquation from tl, map, opLvl and pl label tokensRemoved(closeFoundAt - (commaFoundAt + 2)); label newSize(map.size() - tokensRemoved); for ( label subTokenI(commaFoundAt + 2); subTokenI < newSize; subTokenI++ ) { tl[subTokenI] = tl[subTokenI + tokensRemoved]; map[subTokenI] = map[subTokenI + tokensRemoved]; opLvl[subTokenI] = opLvl[subTokenI + tokensRemoved]; pl[subTokenI] = pl[subTokenI + tokensRemoved]; } tl.setSize(newSize); map.setSize(newSize); opLvl.setSize(newSize); pl.setSize(newSize); } } tokenI++; } }
void Foam::equationReader::createMap ( const label index, const tokenList& tl, PtrList<equationOperation>& map, labelList& opLvl, labelList& pl ) const { // equation * eqn(&this->operator[](index)); // current parenthesis level - note, a negative parenthesis value indicates // that this is the root level of a function, and therefore ',' is allowed label p(0); forAll(tl, i) { if (tl[i].isNumber()) { // Internal constant. Save to internalScalars and record source opLvl[i] = 0; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stinternalScalar, addInternalScalar(tl[i].number()) + 1, 0, 0, equationOperation::otnone ) ); } else if (tl[i].isWord()) { // could be a variable name, function or mathematical constant // - check for function first - function is [word][punctuation '('] if ( (i < (tl.size() - 1)) && (tl[i + 1].isPunctuation()) && (tl[i + 1].pToken() == token::BEGIN_LIST) ) { // Function detected; function brackets are negative opLvl[i] = 4; p = -mag(p) - 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::findOp(tl[i].wordToken()) ) ); if (map[i].operation() == equationOperation::otnone) { OStringStream description; description << tl[i].wordToken() << " is not a recognized " << "function."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } // Set next token as well (function opening parenthesis) i++; opLvl[i] = 4; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); } else if ( (tl[i].wordToken() == "e_") || (tl[i].wordToken() == "pi_") || (tl[i].wordToken() == "twoPi_") || (tl[i].wordToken() == "piByTwo_") || (tl[i].wordToken() == "GREAT_") || (tl[i].wordToken() == "VGREAT_") || (tl[i].wordToken() == "ROOTVGREAT_") || (tl[i].wordToken() == "SMALL_") || (tl[i].wordToken() == "VSMALL_") || (tl[i].wordToken() == "ROOTVSMALL_") ) { // Mathematical constant if ( findSource(tl[i].wordToken()).sourceType() != equationOperation::stnone ) { // Found a possible conflicting variable name - warn WarningIn("equationReader::createMap") << "Equation for " << operator[](index).name() << ", given by:" << token::NL << token::TAB << operator[](index).rawText() << token:: NL << "refers " << "to '" << tl[i].wordToken() << "'. Although " << "variable " << tl[i].wordToken() << "was found in " << "the data sources, " << tl[i].wordToken() << " is a" << " mathematical constant. The mathematical constant " << "will be used." << endl; } opLvl[i] = 0; pl[i] = p; label internalIndex(0); if (tl[i].wordToken() == "e_") { // MathConstantScope is a hack that allows equationReader // to work in multiple versions of OpenFOAM. See // include/versionSpecific.H internalIndex = addInternalScalar(MathConstantScope::e) + 1; } else if (tl[i].wordToken() == "pi_") { internalIndex = addInternalScalar(MathConstantScope::pi) + 1; } else if (tl[i].wordToken() == "twoPi_") { internalIndex = addInternalScalar(MathConstantScope::twoPi) + 1; } else if (tl[i].wordToken() == "piByTwo_") { internalIndex = addInternalScalar(MathConstantScope::piByTwo) + 1; } else if (tl[i].wordToken() == "GREAT_") { internalIndex = addInternalScalar(GREAT) + 1; } else if (tl[i].wordToken() == "VGREAT_") { internalIndex = addInternalScalar(VGREAT) + 1; } else if (tl[i].wordToken() == "ROOTVGREAT_") { internalIndex = addInternalScalar(ROOTVGREAT) + 1; } else if (tl[i].wordToken() == "SMALL_") { internalIndex = addInternalScalar(SMALL) + 1; } else if (tl[i].wordToken() == "VSMALL_") { internalIndex = addInternalScalar(VSMALL) + 1; } else // tl[i].wordToken() == "ROOTVSMALL_" { internalIndex = addInternalScalar(ROOTVSMALL) + 1; } map.set ( i, new equationOperation ( equationOperation::stinternalScalar, internalIndex, 0, 0, equationOperation::otnone ) ); } else { // Variable name opLvl[i] = 0; pl[i] = p; map.set ( i, new equationOperation(findSource(tl[i].wordToken())) ); if (map[i].sourceIndex() == 0) { OStringStream description; description << "Variable name " << tl[i].wordToken() << " not found in any available sources."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } if (map[i].componentIndex() < 0) { OStringStream description; description << "Variable name " << tl[i].wordToken() << " is interpretted as variablePart.componentPart, " << "and the componentPart is not valid, or is " << "required, but is missing."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } } } else if (tl[i].isPunctuation()) { switch (tl[i].pToken()) { case token::BEGIN_LIST: // ( opLvl[i] = 4; p = mag(p) + 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); break; case token::END_LIST: // ) { opLvl[i] = -4; pl[i] = p; p = mag(p) - 1; if (p < 0) { OStringStream description; description << "Too many ')'."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } // Look for preceding parenthesis change - was it negative? for (label j(i - 1); j >= 0; j--) { if (mag(pl[j]) == p) { if (pl[j] < 0) { p = -p; } break; } } map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); break; } case token::COMMA: // , // , is only accepted in a function level parenthesis if (p < 0) { opLvl[i] = 5; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); } else { OStringStream description; description << "The comma, ',' does not make sense " << "here. Only permitted in the root parenthesis " << "level of a function."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } break; case token::ADD: // + opLvl[i] = 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otplus ) ); break; case token::SUBTRACT: // - opLvl[i] = 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otminus ) ); break; case token::MULTIPLY: // * opLvl[i] = 2; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::ottimes ) ); break; case token::DIVIDE: // / opLvl[i] = 2; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otdivide ) ); break; case token::COLON: // :, means ^ { OStringStream description; description << "The '^' operator is not currently " << "supported. Use pow(a,b) instead."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); break; } /* opLvl[i] = 3; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otpow ) ); break; */ default: { OStringStream description; description << "Punctuation character '" << tl[i].pToken() << "' is prohibitted."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); break; } } // end punctuation switch } // end if punctuation else { OStringStream description; description << "Unrecognized token: [" << tl[i] << "]."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } } // mapping loop if (p) { OStringStream description; description << "Parentheses do not match. Expecting " << mag(p) << " additional ')'s."; fatalParseError ( index, tl, 0, tl.size() - 1, "equationReader::parse", description ); } // Assign negatives (distinguish these from subtraction) // The difference is characterized by the preceding character: // -preceeded by an operator = negative '+' '-' '*' '/' '^' // -preceeded by an open bracket = negative '(' // -preceeded by a comma = negative ',' // -preceeded by a variable = subtract 'word' or 'number' // -preceeded by a close bracket = subtract ')' // Negatives are identified by a negative dictLookupIndex if (map[0].operation() == equationOperation::otminus) { opLvl[0] = 2; map[0].dictLookupIndex() = -1; } for (label i(1); i < map.size(); i++) { if (map[i].operation() == equationOperation::otminus) { if (opLvl[i-1] > 0) { opLvl[i] = 2; map[i].dictLookupIndex() = -1; } } } }