82 |
|
for ( ; true; ichToken += cchToken) { |
83 |
|
if (lookingAtLeadingWhitespace()) |
84 |
|
continue; |
85 |
< |
if (lookingAtComment()) |
86 |
< |
continue; |
85 |
> |
//if (lookingAtComment()) |
86 |
> |
// continue; |
87 |
|
bool endOfLine = lookingAtEndOfLine(); |
88 |
|
if (endOfLine || lookingAtEndOfStatement()) { |
89 |
|
if (tokCommand != Token::nada) { |
118 |
|
// continue; |
119 |
|
//} |
120 |
|
if (lookingAtDecimal((tokCommand & Token::negnums) != 0)) { |
121 |
< |
float value = lexi_cast<float>(script.substr(ichToken, ichToken + cchToken)); |
122 |
< |
ltoken.push_back(Token(Token::decimal, value));/**@todo*/ |
121 |
> |
float value = lexi_cast<float>(script.substr(ichToken, cchToken)); |
122 |
> |
ltoken.push_back(Token(Token::decimal, boost::any(value))); |
123 |
|
continue; |
124 |
|
} |
125 |
|
if (lookingAtInteger((tokCommand & Token::negnums) != 0)) { |
126 |
< |
std::string intString = script.substr(ichToken, ichToken + cchToken); |
127 |
< |
int val = lexi_cast<int>(intString); |
128 |
< |
ltoken.push_back(Token(Token::integer, val, intString));/**@todo*/ |
126 |
> |
|
127 |
> |
int val = lexi_cast<int>(script.substr(ichToken, cchToken)); |
128 |
> |
ltoken.push_back(Token(Token::integer, boost::any(val))); |
129 |
|
continue; |
130 |
|
} |
131 |
|
} |
132 |
|
|
133 |
|
if (lookingAtLookupToken()) { |
134 |
< |
std::string ident = script.substr(ichToken, ichToken + cchToken); |
135 |
< |
|
134 |
> |
std::string ident = script.substr(ichToken, cchToken); |
135 |
|
Token token; |
136 |
|
Token* pToken = TokenMap::getInstance()->getToken(ident); |
137 |
|
if (pToken != NULL) { |
242 |
|
previousCharBackslash = ch == '\\' ? !previousCharBackslash : false; |
243 |
|
} |
244 |
|
cchToken = ichT - ichToken; |
245 |
+ |
|
246 |
|
return true; |
247 |
|
} |
248 |
|
|
340 |
|
return false; |
341 |
|
} |
342 |
|
|
343 |
< |
// to support 1.ca, let's check the character after the dot |
344 |
< |
// to determine if it is an alpha |
345 |
< |
if (ch == '.' && (ichT + 1 < cchScript) && std::isalpha(script[ichT + 1])) { |
343 |
> |
// to support DMPC.1, let's check the character before the dot |
344 |
> |
if (ch == '.' && (ichT > 0) && std::isalpha(script[ichT - 1])) { |
345 |
|
return false; |
346 |
|
} |
347 |
|
|
384 |
|
case '(': |
385 |
|
case ')': |
386 |
|
case ',': |
388 |
– |
case '*': |
389 |
– |
case '-': |
387 |
|
case '[': |
388 |
|
case ']': |
392 |
– |
case '+': |
393 |
– |
case ':': |
394 |
– |
case '@': |
395 |
– |
case '.': |
396 |
– |
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::isalpha(ch = script[ichT]) ||std::isdigit(ch) || |
416 |
< |
ch == '_' || ch == '?') ||(ch == '^' && ichT > ichToken && std::isdigit(script[ichT - 1]))) { |
417 |
< |
// hack for insertion codes embedded in an atom expression :-( |
425 |
< |
// select c3^a |
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 |
|
} |
420 |
|
break; |
421 |
|
} |
422 |
+ |
|
423 |
|
cchToken = ichT - ichToken; |
424 |
+ |
|
425 |
|
return true; |
426 |
|
} |
427 |
|
|
558 |
|
case Token::asterisk: |
559 |
|
case Token::identifier: |
560 |
|
return clauseChemObjName(); |
561 |
< |
|
561 |
> |
|
562 |
> |
case Token::integer : |
563 |
> |
return clauseIndex(); |
564 |
|
default: |
565 |
|
if ((tok & Token::atomproperty) == Token::atomproperty) { |
566 |
|
return clauseComparator(); |
593 |
|
} |
594 |
|
|
595 |
|
Token tokenValue = tokenNext(); |
596 |
< |
if (tokenValue.tok != Token::integer) { |
597 |
< |
return integerExpected(); |
596 |
> |
if (tokenValue.tok != Token::integer && tokenValue.tok != Token::decimal) { |
597 |
> |
return numberExpected(); |
598 |
|
} |
599 |
< |
int val = tokenValue.intValue; |
600 |
< |
// note that a comparator instruction is a complicated instruction |
601 |
< |
// int intValue is the tok of the property you are comparing |
602 |
< |
// the value against which you are comparing is stored as an Integer |
603 |
< |
// in the object value |
599 |
> |
|
600 |
> |
float val; |
601 |
> |
if (tokenValue.value.type() == typeid(int)) { |
602 |
> |
val = boost::any_cast<int>(tokenValue.value); |
603 |
> |
} else if (tokenValue.value.type() == typeid(float)) { |
604 |
> |
val = boost::any_cast<float>(tokenValue.value); |
605 |
> |
} else { |
606 |
> |
return false; |
607 |
> |
} |
608 |
> |
|
609 |
> |
boost::any floatVal; |
610 |
> |
floatVal = val; |
611 |
|
return addTokenToPostfix(Token(tokenComparator.tok, |
612 |
< |
tokenAtomProperty.tok, boost::any(val))); |
612 |
> |
tokenAtomProperty.tok, floatVal)); |
613 |
|
} |
614 |
|
|
615 |
|
bool SelectionCompiler::clauseWithin() { |
622 |
|
Token tokenDistance = tokenNext(); // distance |
623 |
|
switch(tokenDistance.tok) { |
624 |
|
case Token::integer: |
622 |
– |
distance = float(tokenDistance.intValue); |
623 |
– |
break; |
625 |
|
case Token::decimal: |
626 |
|
distance = tokenDistance.value; |
627 |
|
break; |
645 |
|
} |
646 |
|
|
647 |
|
bool SelectionCompiler::clauseChemObjName() { |
648 |
< |
std::string chemObjName; |
649 |
< |
int tok = tokPeek(); |
649 |
< |
if (!clauseName(chemObjName)){ |
650 |
< |
return false; |
651 |
< |
} |
648 |
> |
Token token = tokenNext(); |
649 |
> |
if (token.tok == Token::identifier && token.value.type() == typeid(std::string)) { |
650 |
|
|
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 |
+ |
} |
658 |
|
|
659 |
< |
tok = tokPeek(); |
660 |
< |
//allow two dot at most |
661 |
< |
if (tok == Token::dot) { |
662 |
< |
if (!clauseName(chemObjName)) { |
663 |
< |
return false; |
659 |
> |
return false; |
660 |
> |
|
661 |
> |
} |
662 |
> |
|
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 |
> |
case '[' : |
670 |
> |
++nbracket; |
671 |
> |
break; |
672 |
> |
case ']' : |
673 |
> |
--nbracket; |
674 |
> |
break; |
675 |
> |
case '.' : |
676 |
> |
++ndot; |
677 |
> |
break; |
678 |
|
} |
660 |
– |
tok = tokPeek(); |
661 |
– |
if (tok == Token::dot) { |
662 |
– |
if (!clauseName(chemObjName)) { |
663 |
– |
return false; |
664 |
– |
} |
665 |
– |
} |
679 |
|
} |
680 |
|
|
681 |
< |
return addTokenToPostfix(Token(Token::name, chemObjName)); |
681 |
> |
//only allow 3 dots at most |
682 |
> |
return (ndot <=3 && nbracket == 0) ? true : false; |
683 |
|
} |
684 |
|
|
685 |
< |
bool SelectionCompiler:: clauseName(std::string& name) { |
686 |
< |
|
687 |
< |
int tok = tokPeek(); |
688 |
< |
|
689 |
< |
if (tok == Token::asterisk || tok == Token::identifier) { |
690 |
< |
name += boost::any_cast<std::string>(tokenNext().value); |
691 |
< |
|
692 |
< |
while(true){ |
685 |
> |
bool SelectionCompiler::clauseIndex(){ |
686 |
> |
Token token = tokenNext(); |
687 |
> |
if (token.tok == Token::integer) { |
688 |
> |
int index = boost::any_cast<int>(token.value); |
689 |
> |
int tok = tokPeek(); |
690 |
> |
std::cout << "Token::to is " << Token::to << ", tok = " << tok << std::endl; |
691 |
> |
if (tok == Token::to) { |
692 |
> |
tokenNext(); |
693 |
|
tok = tokPeek(); |
694 |
< |
switch (tok) { |
695 |
< |
case Token::asterisk : |
682 |
< |
name += "*"; |
683 |
< |
tokenNext(); |
684 |
< |
break; |
685 |
< |
case Token::identifier : |
686 |
< |
name += boost::any_cast<std::string>(tokenNext().value); |
687 |
< |
break; |
688 |
< |
case Token::integer : |
689 |
< |
name += toString(boost::any_cast<int>(tokenNext().value)); |
690 |
< |
break; |
691 |
< |
case Token::dot : |
692 |
< |
return true; |
693 |
< |
default : |
694 |
< |
return true; |
694 |
> |
if (tok != Token::integer) { |
695 |
> |
return numberExpected(); |
696 |
|
} |
697 |
+ |
|
698 |
+ |
boost::any intVal = tokenNext().value; |
699 |
+ |
int first = index; |
700 |
+ |
if (intVal.type() != typeid(int)){ |
701 |
+ |
return false; |
702 |
+ |
} |
703 |
+ |
int second = boost::any_cast<int>(intVal); |
704 |
+ |
|
705 |
+ |
return addTokenToPostfix(Token(Token::index, boost::any(std::make_pair(first, second)))); |
706 |
+ |
|
707 |
+ |
}else { |
708 |
+ |
return addTokenToPostfix(Token(Token::index, boost::any(index))); |
709 |
|
} |
710 |
< |
|
711 |
< |
}else { |
699 |
< |
return false; |
710 |
> |
} else { |
711 |
> |
return numberExpected(); |
712 |
|
} |
701 |
– |
|
713 |
|
} |
714 |
|
|
704 |
– |
|
715 |
|
} |