--- trunk/src/selection/SelectionCompiler.cpp 2005/02/02 12:51:25 279 +++ trunk/src/selection/SelectionCompiler.cpp 2005/03/09 18:46:16 415 @@ -40,6 +40,7 @@ */ #include "selection/SelectionCompiler.hpp" +#include "utils/StringUtils.hpp" namespace oopse { bool SelectionCompiler::compile(const std::string& filename, const std::string& script) { @@ -50,13 +51,13 @@ bool SelectionCompiler::compile(const std::string& fil lineIndices.clear(); aatokenCompiled.clear(); - if (internalcompile()) { + if (internalCompile()) { return true; } int icharEnd; - if ((icharEnd = script.find('\r', ichCurrentCommand)) == std::string:npos && - (icharEnd = script.find('\n', ichCurrentCommand)) == std::string:npos) { + if ((icharEnd = script.find('\r', ichCurrentCommand)) == std::string::npos && + (icharEnd = script.find('\n', ichCurrentCommand)) == std::string::npos) { icharEnd = script.size(); } errorLine = script.substr(ichCurrentCommand, icharEnd); @@ -71,30 +72,29 @@ bool SelectionCompiler::internalCompile(){ error = false; - std::vector lltoken; + //std::vector lltoken; + aatokenCompiled.clear(); std::vector ltoken; - //Token tokenCommand = null; - int tokCommand = Token.nada; + Token tokenCommand; + int tokCommand = Token::nada; for ( ; true; ichToken += cchToken) { if (lookingAtLeadingWhitespace()) continue; - if (lookingAtComment()) - continue; - boolean endOfLine = lookingAtEndOfLine(); + //if (lookingAtComment()) + // continue; + bool endOfLine = lookingAtEndOfLine(); if (endOfLine || lookingAtEndOfStatement()) { - if (tokCommand != Token.nada) { + if (tokCommand != Token::nada) { if (! compileCommand(ltoken)) { return false; } - lltoken.push_back(atokenCommand); - /** @todo*/ - int iCommand = lltoken.size(); - lineNumbers[iCommand] = lineCurrent; - lineIndices[iCommand] = (short) ichCurrentCommand; - ltoken.clear(); - tokCommand = Token.nada; + aatokenCompiled.push_back(atokenCommand); + lineNumbers.push_back(lineCurrent); + lineIndices.push_back(ichCurrentCommand); + ltoken.clear(); + tokCommand = Token::nada; } if (ichToken < cchScript) { @@ -105,70 +105,69 @@ bool SelectionCompiler::internalCompile(){ break; } - if (tokCommand != Token.nada) { + if (tokCommand != Token::nada) { if (lookingAtString()) { std::string str = getUnescapedStringLiteral(); - ltoken.push_back(Token(Token.string, str)); + ltoken.push_back(Token(Token::string, str)); continue; } - if ((tokCommand & Token.specialstring) != 0 && - lookingAtSpecialString()) { - std::string str = script.substr(ichToken, ichToken + cchToken); - ltoken.push_back(Token(Token.string, str)); + //if ((tokCommand & Token::specialstring) != 0 && + // lookingAtSpecialString()) { + // std::string str = script.substr(ichToken, ichToken + cchToken); + // ltoken.push_back(Token(Token::string, str)); + // continue; + //} + if (lookingAtDecimal((tokCommand & Token::negnums) != 0)) { + float value = lexi_cast(script.substr(ichToken, cchToken)); + ltoken.push_back(Token(Token::decimal, boost::any(value))); continue; } - if (lookingAtDecimal((tokCommand & Token.negnums) != 0)) { - float value = lexi_cast((script.substr(ichToken, ichToken + cchToken)); - ltoken.push_back(Token(Token.decimal, new Float(value)));/**@todo*/ + if (lookingAtInteger((tokCommand & Token::negnums) != 0)) { + + int val = lexi_cast(script.substr(ichToken, cchToken)); + ltoken.push_back(Token(Token::integer, boost::any(val))); continue; } - if (lookingAtInteger((tokCommand & Token.negnums) != 0)) { - std::string intString = script.substr(ichToken, ichToken + cchToken); - int val = lexi_cast(intString); - ltoken.push_back(new Token(Token.integer, val, intString));/**@todo*/ - continue; - } } if (lookingAtLookupToken()) { - std::string ident = script.subst(ichToken, ichToken + cchToken); - - /**@todo */ - Token token = (Token) Token.map.get(ident); - if (token == NULL) { - + std::string ident = script.substr(ichToken, cchToken); + Token token; + Token* pToken = TokenMap::getInstance()->getToken(ident); + if (pToken != NULL) { + token = *pToken; + } else { + token = Token(Token::identifier, ident); } - Token token(Token.identifier, ident); - int tok = token.tok; switch (tokCommand) { - case Token.nada: + case Token::nada: ichCurrentCommand = ichToken; //tokenCommand = token; tokCommand = tok; - if ((tokCommand & Token.command) == 0) + if ((tokCommand & Token::command) == 0) return commandExpected(); break; - case Token.define: + case Token::define: if (ltoken.size() == 1) { // we are looking at the variable name - if (tok != Token.identifier && - (tok & Token.predefinedset) != Token.predefinedset) + if (tok != Token::identifier && + (tok & Token::predefinedset) != Token::predefinedset) return invalidExpressionToken(ident); } else { // we are looking at the expression - if (tok != Token.identifier && tok != Token.set && - (tok & (Token.expression | Token.predefinedset)) == 0) + if (tok != Token::identifier && + (tok & (Token::expression | Token::predefinedset)) == 0) return invalidExpressionToken(ident); } break; - case Token.select: - if (tok != Token.identifier && (tok & Token.expression) == 0) + case Token::select: + if (tok != Token::identifier && (tok & Token::expression) == 0) return invalidExpressionToken(ident); break; } @@ -183,7 +182,6 @@ bool SelectionCompiler::internalCompile(){ return unrecognizedToken(); } - aatokenCompiled.push_back(lltoken); return true; } @@ -236,20 +234,23 @@ bool SelectionCompiler::internalCompile(){ int ichT = ichToken + 1; // while (ichT < cchScript && script.charAt(ichT++) != chFirst) char ch; - boolean previousCharBackslash = false; + bool previousCharBackslash = false; while (ichT < cchScript) { - ch = script.[ichT++]; + ch = script[ichT++]; if (ch == '"' && !previousCharBackslash) break; previousCharBackslash = ch == '\\' ? !previousCharBackslash : false; } cchToken = ichT - ichToken; + return true; } std::string SelectionCompiler::getUnescapedStringLiteral() { - StringBuffer sb = new StringBuffer(cchToken - 2); + /** @todo */ + std::string sb(cchToken - 2, ' '); + int ichMax = ichToken + cchToken - 1; int ich = ichToken + 1; @@ -292,13 +293,13 @@ std::string SelectionCompiler::getUnescapedStringLiter } } } - sb.append(ch); + sb.append(1, ch); } - return "" + sb; + return sb; } -static int SelectionCompiler::getHexitValue(char ch) { +int SelectionCompiler::getHexitValue(char ch) { if (ch >= '0' && ch <= '9') return ch - '0'; else if (ch >= 'a' && ch <= 'f') @@ -319,7 +320,7 @@ bool SelectionCompiler::lookingAtSpecialString() { return cchToken > 0; } -bool SelectionCompiler::lookingAtDecimal(boolean allowNegative) { +bool SelectionCompiler::lookingAtDecimal(bool allowNegative) { if (ichToken == cchScript) { return false; } @@ -328,7 +329,7 @@ bool SelectionCompiler::lookingAtDecimal(boolean allow if (script[ichT] == '-') { ++ichT; } - boolean digitSeen = false; + bool digitSeen = false; char ch = 'X'; while (ichT < cchScript && std::isdigit(ch = script[ichT])) { ++ichT; @@ -339,9 +340,8 @@ bool SelectionCompiler::lookingAtDecimal(boolean allow return false; } - // to support 1.ca, let's check the character after the dot - // to determine if it is an alpha - if (ch == '.' && (ichT + 1 < cchScript) && std::isalpha(script[ichT + 1])) { + // to support DMPC.1, let's check the character before the dot + if (ch == '.' && (ichT > 0) && std::isalpha(script[ichT - 1])) { return false; } @@ -354,7 +354,7 @@ bool SelectionCompiler::lookingAtDecimal(boolean allow return digitSeen; } -bool SelectionCompiler::lookingAtInteger(boolean allowNegative) { +bool SelectionCompiler::lookingAtInteger(bool allowNegative) { if (ichToken == cchScript) { return false; } @@ -418,28 +418,28 @@ bool SelectionCompiler::lookingAtLookupToken() { return false; } case '?': // include question marks in identifier for atom expressions - while (ichT < cchScript && (std::isalpha(ch = script[ichT]) ||std::isdigit(ch) || - ch == '_' || ch == '?') ||(ch == '^' && ichT > ichToken && std::isdigit(script[ichT - 1]))) { - // hack for insertion codes embedded in an atom expression :-( - // select c3^a + while (ichT < cchScript && !std::isspace(ch = script[ichT]) && (std::isalpha(ch) ||std::isdigit(ch) || + ch == '_' || ch == '?') ) { + ++ichT; } break; } + cchToken = ichT - ichToken; + return true; } -bool SelectionCompiler::compileCommand(Vector ltoken) { - /** todo */ - Token tokenCommand = (Token)ltoken.firstElement(); +bool SelectionCompiler::compileCommand(const std::vector& ltoken) { + const Token& tokenCommand = ltoken[0]; int tokCommand = tokenCommand.tok; - - atokenCommand = new Token[ltoken.size()]; - ltoken.copyInto(atokenCommand); - if ((tokCommand & Token.expressionCommand) != 0 && !compileExpression()) { + + atokenCommand = ltoken; + if ((tokCommand & Token::expressionCommand) != 0 && !compileExpression()) { return false; } + return true; } @@ -447,40 +447,43 @@ bool SelectionCompiler::compileExpression() { /** todo */ int i = 1; int tokCommand = atokenCommand[0].tok; - if (tokCommand == Token.define) - i = 2; - else if ((tokCommand & Token.embeddedExpression) != 0) { - // look for the open parenthesis - while (i < atokenCommand.length && - atokenCommand[i].tok != Token.leftparen) + if (tokCommand == Token::define) { + i = 2; + } else if ((tokCommand & Token::embeddedExpression) != 0) { + // look for the open parenthesis + while (i < atokenCommand.size() && + atokenCommand[i].tok != Token::leftparen) ++i; } - if (i >= atokenCommand.length) - return true; + + if (i >= atokenCommand.size()) { + return true; + } return compileExpression(i); } -bool SelectionCompiler::addTokenToPostfix(Token token) { +bool SelectionCompiler::addTokenToPostfix(const Token& token) { ltokenPostfix.push_back(token); return true; } bool SelectionCompiler::compileExpression(int itoken) { - ltokenPostfix = new Vector(); - for (int i = 0; i < itoken; ++i) + ltokenPostfix.clear(); + for (int i = 0; i < itoken; ++i) { addTokenToPostfix(atokenCommand[i]); - + } + atokenInfix = atokenCommand; itokenInfix = itoken; - addTokenToPostfix(Token.tokenExpressionBegin); + addTokenToPostfix(Token::tokenExpressionBegin); if (!clauseOr()) { return false; } - addTokenToPostfix(Token.tokenExpressionEnd); - if (itokenInfix != atokenInfix.length) { + addTokenToPostfix(Token::tokenExpressionEnd); + if (itokenInfix != atokenInfix.size()) { return endOfExpressionExpected(); } @@ -489,21 +492,22 @@ Token SelectionCompiler::tokenNext() { } Token SelectionCompiler::tokenNext() { -if (itokenInfix == atokenInfix.length) -return null; -return atokenInfix[itokenInfix++]; + if (itokenInfix == atokenInfix.size()) { + return Token(); + } + return atokenInfix[itokenInfix++]; } -Object SelectionCompiler::valuePeek() { - if (itokenInfix == atokenInfix.length) { - return null; +boost::any SelectionCompiler::valuePeek() { + if (itokenInfix == atokenInfix.size()) { + return boost::any(); } else { return atokenInfix[itokenInfix].value; } } int SelectionCompiler::tokPeek() { - if (itokenInfix == atokenInfix.length) { + if (itokenInfix == atokenInfix.size()) { return 0; }else { return atokenInfix[itokenInfix].tok; @@ -515,7 +519,7 @@ bool SelectionCompiler::clauseOr() { return false; } - while (tokPeek() == Token.opOr) { + while (tokPeek() == Token::opOr) { Token tokenOr = tokenNext(); if (!clauseAnd()) { return false; @@ -530,7 +534,7 @@ bool SelectionCompiler::clauseAnd() { return false; } - while (tokPeek() == Token.opAnd) { + while (tokPeek() == Token::opAnd) { Token tokenAnd = tokenNext(); if (!clauseNot()) { return false; @@ -541,7 +545,7 @@ bool SelectionCompiler::clauseNot() { } bool SelectionCompiler::clauseNot() { - if (tokPeek() == Token.opNot) { + if (tokPeek() == Token::opNot) { Token tokenNot = tokenNext(); if (!clauseNot()) { return false; @@ -554,36 +558,32 @@ bool SelectionCompiler::clausePrimitive() { bool SelectionCompiler::clausePrimitive() { int tok = tokPeek(); switch (tok) { - case Token.within: + case Token::within: return clauseWithin(); - case Token.hyphen: // selecting a negative residue spec - case Token.integer: - case Token.seqcode: - case Token.asterisk: - case Token.leftsquare: - case Token.identifier: - case Token.x: - case Token.y: - case Token.z: - case Token.colon: - return clauseResidueSpec(); + + case Token::asterisk: + case Token::identifier: + return clauseChemObjName(); + + case Token::integer : + return clauseIndex(); default: - if ((tok & Token.atomproperty) == Token.atomproperty) { + if ((tok & Token::atomproperty) == Token::atomproperty) { return clauseComparator(); } - if ((tok & Token.predefinedset) != Token.predefinedset) { + if ((tok & Token::predefinedset) != Token::predefinedset) { break; } // fall into the code and below and just add the token - case Token.all: - case Token.none: + case Token::all: + case Token::none: return addTokenToPostfix(tokenNext()); - case Token.leftparen: + case Token::leftparen: tokenNext(); if (!clauseOr()) { return false; } - if (tokenNext().tok != Token.rightparen) { + if (tokenNext().tok != Token::rightparen) { return rightParenthesisExpected(); } return true; @@ -594,44 +594,48 @@ bool SelectionCompiler::clauseComparator() { bool SelectionCompiler::clauseComparator() { Token tokenAtomProperty = tokenNext(); Token tokenComparator = tokenNext(); - if ((tokenComparator.tok & Token.comparator) == 0) { + if ((tokenComparator.tok & Token::comparator) == 0) { return comparisonOperatorExpected(); } Token tokenValue = tokenNext(); - if (tokenValue.tok != Token.integer) { - return integerExpected(); + if (tokenValue.tok != Token::integer && tokenValue.tok != Token::decimal) { + return numberExpected(); } - int val = tokenValue.intValue; - // note that a comparator instruction is a complicated instruction - // int intValue is the tok of the property you are comparing - // the value against which you are comparing is stored as an Integer - // in the object value - return addTokenToPostfix(new Token(tokenComparator.tok, - tokenAtomProperty.tok, - new Integer(val))); + + float val; + if (tokenValue.value.type() == typeid(int)) { + val = boost::any_cast(tokenValue.value); + } else if (tokenValue.value.type() == typeid(float)) { + val = boost::any_cast(tokenValue.value); + } else { + return false; + } + + boost::any floatVal; + floatVal = val; + return addTokenToPostfix(Token(tokenComparator.tok, + tokenAtomProperty.tok, floatVal)); } bool SelectionCompiler::clauseWithin() { tokenNext(); // WITHIN - if (tokenNext().tok != Token.leftparen) { // ( + if (tokenNext().tok != Token::leftparen) { // ( return leftParenthesisExpected(); } - Object distance; + boost::any distance; Token tokenDistance = tokenNext(); // distance switch(tokenDistance.tok) { - case Token.integer: - distance = new Float((tokenDistance.intValue * 4) / 1000f); - break; - case Token.decimal: + case Token::integer: + case Token::decimal: distance = tokenDistance.value; break; default: return numberOrKeywordExpected(); } - if (tokenNext().tok != Token.opOr) { // , + if (tokenNext().tok != Token::opOr) { // , return commaExpected(); } @@ -639,35 +643,113 @@ bool SelectionCompiler::clauseWithin() { return false; } - if (tokenNext().tok != Token.rightparen) { // )T + if (tokenNext().tok != Token::rightparen) { // )T return rightParenthesisExpected(); } - return addTokenToPostfix(new Token(Token.within, distance)); + return addTokenToPostfix(Token(Token::within, distance)); } -bool SelectionCompiler:: clauseChemObject() { -} +bool SelectionCompiler::clauseChemObjName() { + std::string chemObjName; + int tok = tokPeek(); + if (!clauseName(chemObjName)){ + return false; + } -bool SelectionCompiler:: clauseMolecule() { -} -bool SelectionCompiler:: clauseMolName() { -} + tok = tokPeek(); + //allow two dot at most + if (tok == Token::dot) { + tokenNext(); + chemObjName += "."; + if (!clauseName(chemObjName)) { + return false; + } + tok = tokPeek(); + if (tok == Token::dot) { + tokenNext(); + chemObjName += "."; -bool SelectionCompiler:: clauseMolIndex() { -} + if (!clauseName(chemObjName)) { + return false; + } + } + } -bool SelectionCompiler:: clauseName() { + return addTokenToPostfix(Token(Token::name, chemObjName)); } -bool SelectionCompiler:: clauseIndex() { -} +bool SelectionCompiler:: clauseName(std::string& name) { -bool SelectionCompiler:: clauseStuntDoubleName() { + int tok = tokPeek(); + + if (tok == Token::asterisk || tok == Token::identifier || tok == Token::integer) { + + Token token = tokenNext(); + if (token.value.type() == typeid(std::string)) { + name += boost::any_cast(token.value); + } else if (token.value.type() == typeid(int)){ + int intVal = boost::any_cast(token.value); + char buffer[255]; + sprintf(buffer,"%d", intVal); + name += buffer; /** @todo */ + //name += toString(intVal); + } + while(true){ + tok = tokPeek(); + switch (tok) { + case Token::asterisk : + name += "*"; + tokenNext(); + break; + case Token::identifier : + name += boost::any_cast(tokenNext().value); + break; + case Token::integer : + name += toString(boost::any_cast(tokenNext().value)); + break; + case Token::dot : + return true; + default : + return true; + } + } + + }else { + return false; + } + } -bool SelectionCompiler:: clauseStuntDoubleIndex() { +bool SelectionCompiler::clauseIndex(){ + Token token = tokenNext(); + if (token.tok == Token::integer) { + int index = boost::any_cast(token.value); + int tok = tokPeek(); + std::cout << "Token::to is " << Token::to << ", tok = " << tok << std::endl; + if (tok == Token::to) { + tokenNext(); + tok = tokPeek(); + if (tok != Token::integer) { + return numberExpected(); + } + + boost::any intVal = tokenNext().value; + int first = index; + if (intVal.type() != typeid(int)){ + return false; + } + int second = boost::any_cast(intVal); + + return addTokenToPostfix(Token(Token::index, boost::any(std::make_pair(first, second)))); + + }else { + return addTokenToPostfix(Token(Token::index, boost::any(index))); + } + } else { + return numberExpected(); + } } }