--- trunk/src/selection/SelectionCompiler.cpp 2005/02/04 22:39:26 288 +++ trunk/src/selection/SelectionCompiler.cpp 2005/04/05 23:09:48 452 @@ -118,14 +118,14 @@ bool SelectionCompiler::internalCompile(){ // continue; //} if (lookingAtDecimal((tokCommand & Token::negnums) != 0)) { - float value = lexi_cast(script.substr(ichToken, ichToken + cchToken)); - ltoken.push_back(Token(Token::decimal, value));/**@todo*/ + float value = lexi_cast(script.substr(ichToken, cchToken)); + ltoken.push_back(Token(Token::decimal, boost::any(value))); continue; } if (lookingAtInteger((tokCommand & Token::negnums) != 0)) { - std::string intString = script.substr(ichToken, ichToken + cchToken); - int val = lexi_cast(intString); - ltoken.push_back(Token(Token::integer, val, intString));/**@todo*/ + + int val = lexi_cast(script.substr(ichToken, cchToken)); + ltoken.push_back(Token(Token::integer, boost::any(val))); continue; } } @@ -242,6 +242,7 @@ bool SelectionCompiler::internalCompile(){ previousCharBackslash = ch == '\\' ? !previousCharBackslash : false; } cchToken = ichT - ichToken; + return true; } @@ -339,9 +340,8 @@ bool SelectionCompiler::lookingAtDecimal(bool allowNeg 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; } @@ -384,15 +384,8 @@ bool SelectionCompiler::lookingAtLookupToken() { case '(': case ')': case ',': - case '*': - case '-': case '[': case ']': - case '+': - case ':': - case '@': - case '.': - case '%': break; case '&': case '|': @@ -417,15 +410,18 @@ bool SelectionCompiler::lookingAtLookupToken() { if ((ch < 'a' || ch > 'z') && (ch < 'A' && ch > 'Z') && ch != '_') { return false; } + case '*': case '?': // include question marks in identifier for atom expressions - while (ichT < cchScript && !std::isspace(ch = script[ichT]) && (std::isalpha(ch) ||std::isdigit(ch) || - ch == '_' || ch == '?') ) { + while (ichT < cchScript && !std::isspace(ch = script[ichT]) && + (std::isalpha(ch) ||std::isdigit(ch) || ch == '_' || ch == '.' || ch == '*' || ch == '?' || ch == '+' || ch == '-' || ch == '[' || ch == ']') ){ ++ichT; } break; } + cchToken = ichT - ichToken; + return true; } @@ -562,7 +558,9 @@ bool SelectionCompiler::clausePrimitive() { case Token::asterisk: case Token::identifier: return clauseChemObjName(); - + + case Token::integer : + return clauseIndex(); default: if ((tok & Token::atomproperty) == Token::atomproperty) { return clauseComparator(); @@ -608,8 +606,10 @@ bool SelectionCompiler::clauseComparator() { return false; } + boost::any floatVal; + floatVal = val; return addTokenToPostfix(Token(tokenComparator.tok, - tokenAtomProperty.tok, boost::any(val))); + tokenAtomProperty.tok, floatVal)); } bool SelectionCompiler::clauseWithin() { @@ -622,8 +622,6 @@ bool SelectionCompiler::clauseWithin() { Token tokenDistance = tokenNext(); // distance switch(tokenDistance.tok) { case Token::integer: - distance = float(tokenDistance.intValue); - break; case Token::decimal: distance = tokenDistance.value; break; @@ -647,67 +645,71 @@ bool SelectionCompiler::clauseChemObjName() { } bool SelectionCompiler::clauseChemObjName() { - std::string chemObjName; - int tok = tokPeek(); - if (!clauseName(chemObjName)){ - return false; - } + Token token = tokenNext(); + if (token.tok == Token::identifier && token.value.type() == typeid(std::string)) { - - tok = tokPeek(); - //allow two dot at most - if (tok == Token::dot) { - tokenNext(); - chemObjName += "."; - if (!clauseName(chemObjName)) { - return false; + std::string name = boost::any_cast(token.value); + if (isNameValid(name)) { + return addTokenToPostfix(Token(Token::name, name)); + } else { + return compileError("invalid name: " + name); } - tok = tokPeek(); - if (tok == Token::dot) { - tokenNext(); - chemObjName += "."; + } - if (!clauseName(chemObjName)) { - return false; - } - } + return false; + +} + +bool SelectionCompiler::isNameValid(const std::string& name) { + int nbracket = 0; + int ndot = 0; + for (int i =0 ; i < name.size(); ++i) { + switch(name[i]) { + + case '[' : + ++nbracket; + break; + case ']' : + --nbracket; + break; + case '.' : + ++ndot; + break; + } } - return addTokenToPostfix(Token(Token::name, chemObjName)); + //only allow 3 dots at most + return (ndot <=3 && nbracket == 0) ? true : false; } -bool SelectionCompiler:: clauseName(std::string& name) { - - int tok = tokPeek(); - - if (tok == Token::asterisk || tok == Token::identifier) { - name += boost::any_cast(tokenNext().value); - - while(true){ +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(); - 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; + 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 false; + } else { + return numberExpected(); } - } - }