119 |
|
//} |
120 |
|
if (lookingAtDecimal((tokCommand & Token::negnums) != 0)) { |
121 |
|
float value = lexi_cast<float>(script.substr(ichToken, cchToken)); |
122 |
– |
std::cout << "encount an decimal: " << value << std::endl; |
122 |
|
ltoken.push_back(Token(Token::decimal, boost::any(value))); |
123 |
|
continue; |
124 |
|
} |
125 |
|
if (lookingAtInteger((tokCommand & Token::negnums) != 0)) { |
126 |
|
|
127 |
|
int val = lexi_cast<int>(script.substr(ichToken, cchToken)); |
129 |
– |
std::cout << "encount an integer: " << val << std::endl; |
128 |
|
ltoken.push_back(Token(Token::integer, boost::any(val))); |
129 |
|
continue; |
130 |
|
} |
243 |
|
} |
244 |
|
cchToken = ichT - ichToken; |
245 |
|
|
248 |
– |
|
249 |
– |
std::cout << "lookingAtString: encount " << script.substr(ichToken, cchToken) << std::endl; |
246 |
|
return true; |
247 |
|
} |
248 |
|
|
384 |
|
case '(': |
385 |
|
case ')': |
386 |
|
case ',': |
391 |
– |
case '*': |
392 |
– |
case '-': |
387 |
|
case '[': |
388 |
|
case ']': |
395 |
– |
case '+': |
396 |
– |
case ':': |
397 |
– |
case '@': |
398 |
– |
case '.': |
399 |
– |
case '%': |
389 |
|
break; |
390 |
|
case '&': |
391 |
|
case '|': |
410 |
|
if ((ch < 'a' || ch > 'z') && (ch < 'A' && ch > 'Z') && ch != '_') { |
411 |
|
return false; |
412 |
|
} |
413 |
+ |
case '*': |
414 |
|
case '?': // include question marks in identifier for atom expressions |
415 |
< |
while (ichT < cchScript && !std::isspace(ch = script[ichT]) && (std::isalpha(ch) ||std::isdigit(ch) || |
416 |
< |
ch == '_' || ch == '?') ) { |
415 |
> |
while (ichT < cchScript && !std::isspace(ch = script[ichT]) && |
416 |
> |
(std::isalpha(ch) ||std::isdigit(ch) || ch == '_' || ch == '.' || ch == '*' || ch == '?' || ch == '+' || ch == '-' || ch == '[' || ch == ']') ){ |
417 |
|
|
418 |
|
++ichT; |
419 |
|
} |
422 |
|
|
423 |
|
cchToken = ichT - ichToken; |
424 |
|
|
435 |
– |
std::cout << "lookingAtLookupToken: encount " << script.substr(ichToken, cchToken) << std::endl; |
425 |
|
return true; |
426 |
|
} |
427 |
|
|
645 |
|
} |
646 |
|
|
647 |
|
bool SelectionCompiler::clauseChemObjName() { |
648 |
< |
std::string chemObjName; |
649 |
< |
int tok = tokPeek(); |
661 |
< |
if (!clauseName(chemObjName)){ |
662 |
< |
return false; |
663 |
< |
} |
648 |
> |
Token token = tokenNext(); |
649 |
> |
if (token.tok == Token::identifier && token.value.type() == typeid(std::string)) { |
650 |
|
|
651 |
< |
|
652 |
< |
tok = tokPeek(); |
653 |
< |
//allow two dot at most |
654 |
< |
if (tok == Token::dot) { |
655 |
< |
tokenNext(); |
670 |
< |
chemObjName += "."; |
671 |
< |
if (!clauseName(chemObjName)) { |
672 |
< |
return false; |
651 |
> |
std::string name = boost::any_cast<std::string>(token.value); |
652 |
> |
if (isNameValid(name)) { |
653 |
> |
return addTokenToPostfix(Token(Token::name, name)); |
654 |
> |
} else { |
655 |
> |
return compileError("invalid name: " + name); |
656 |
|
} |
657 |
< |
tok = tokPeek(); |
675 |
< |
if (tok == Token::dot) { |
676 |
< |
tokenNext(); |
677 |
< |
chemObjName += "."; |
657 |
> |
} |
658 |
|
|
659 |
< |
if (!clauseName(chemObjName)) { |
660 |
< |
return false; |
681 |
< |
} |
682 |
< |
} |
683 |
< |
} |
684 |
< |
|
685 |
< |
return addTokenToPostfix(Token(Token::name, chemObjName)); |
659 |
> |
return false; |
660 |
> |
|
661 |
|
} |
662 |
|
|
663 |
< |
bool SelectionCompiler:: clauseName(std::string& name) { |
663 |
> |
bool SelectionCompiler::isNameValid(const std::string& name) { |
664 |
> |
int nbracket = 0; |
665 |
> |
int ndot = 0; |
666 |
> |
for (int i =0 ; i < name.size(); ++i) { |
667 |
> |
switch(name[i]) { |
668 |
|
|
669 |
< |
int tok = tokPeek(); |
670 |
< |
|
671 |
< |
if (tok == Token::asterisk || tok == Token::identifier || tok == Token::integer) { |
672 |
< |
|
673 |
< |
Token token = tokenNext(); |
674 |
< |
if (token.value.type() == typeid(std::string)) { |
675 |
< |
name += boost::any_cast<std::string>(token.value); |
676 |
< |
} else if (token.value.type() == typeid(int)){ |
677 |
< |
int intVal = boost::any_cast<int>(token.value); |
699 |
< |
char buffer[255]; |
700 |
< |
sprintf(buffer,"%d", intVal); |
701 |
< |
name += buffer; /** @todo */ |
702 |
< |
//name += toString<int>(intVal); |
669 |
> |
case '[' : |
670 |
> |
++nbracket; |
671 |
> |
break; |
672 |
> |
case ']' : |
673 |
> |
--nbracket; |
674 |
> |
break; |
675 |
> |
case '.' : |
676 |
> |
++ndot; |
677 |
> |
break; |
678 |
|
} |
704 |
– |
while(true){ |
705 |
– |
tok = tokPeek(); |
706 |
– |
switch (tok) { |
707 |
– |
case Token::asterisk : |
708 |
– |
name += "*"; |
709 |
– |
tokenNext(); |
710 |
– |
break; |
711 |
– |
case Token::identifier : |
712 |
– |
name += boost::any_cast<std::string>(tokenNext().value); |
713 |
– |
break; |
714 |
– |
case Token::integer : |
715 |
– |
name += toString(boost::any_cast<int>(tokenNext().value)); |
716 |
– |
break; |
717 |
– |
case Token::dot : |
718 |
– |
return true; |
719 |
– |
default : |
720 |
– |
return true; |
721 |
– |
} |
722 |
– |
} |
723 |
– |
|
724 |
– |
}else { |
725 |
– |
return false; |
679 |
|
} |
680 |
|
|
681 |
+ |
//only allow 3 dots at most |
682 |
+ |
return (ndot <=3 && nbracket == 0) ? true : false; |
683 |
|
} |
684 |
|
|
685 |
|
bool SelectionCompiler::clauseIndex(){ |