예제 #1
0
 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;
         }
     }
 }
예제 #2
0
    // 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];
    }
}
예제 #4
0
    // 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);
    }
예제 #5
0
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;
            }
        }
    }
}