ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/selection/SelectionCompiler.cpp
(Generate patch)

Comparing:
trunk/src/selection/SelectionCompiler.cpp (file contents), Revision 279 by tim, Wed Feb 2 12:51:25 2005 UTC vs.
branches/development/src/selection/SelectionCompiler.cpp (file contents), Revision 1465 by chuckv, Fri Jul 9 23:08:25 2010 UTC

# Line 6 | Line 6
6   * redistribute this software in source and binary code form, provided
7   * that the following conditions are met:
8   *
9 < * 1. Acknowledgement of the program authors must be made in any
10 < *    publication of scientific results based in part on use of the
11 < *    program.  An acceptable form of acknowledgement is citation of
12 < *    the article in which the program was described (Matthew
13 < *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 < *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 < *    Parallel Simulation Engine for Molecular Dynamics,"
16 < *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 < *
18 < * 2. Redistributions of source code must retain the above copyright
9 > * 1. Redistributions of source code must retain the above copyright
10   *    notice, this list of conditions and the following disclaimer.
11   *
12 < * 3. Redistributions in binary form must reproduce the above copyright
12 > * 2. Redistributions in binary form must reproduce the above copyright
13   *    notice, this list of conditions and the following disclaimer in the
14   *    documentation and/or other materials provided with the
15   *    distribution.
# Line 37 | Line 28
28   * arising out of the use of or inability to use software, even if the
29   * University of Notre Dame has been advised of the possibility of
30   * such damages.
31 + *
32 + * SUPPORT OPEN SCIENCE!  If you use OpenMD or its source code in your
33 + * research, please cite the appropriate papers when you publish your
34 + * work.  Good starting points are:
35 + *                                                                      
36 + * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
37 + * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
38 + * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).          
39 + * [4]  Vardeman & Gezelter, in progress (2009).                        
40   */
41  
42   #include "selection/SelectionCompiler.hpp"
43 < namespace oopse {
43 > #include "utils/StringUtils.hpp"
44 > namespace OpenMD {
45  
46 < bool SelectionCompiler::compile(const std::string& filename, const std::string& script) {
46 >  bool SelectionCompiler::compile(const std::string& filename,
47 >                                  const std::string& script) {
48  
49      this->filename = filename;
50      this->script = script;
# Line 50 | Line 52 | bool SelectionCompiler::compile(const std::string& fil
52      lineIndices.clear();
53      aatokenCompiled.clear();
54          
55 <    if (internalcompile()) {
56 <        return true;
55 >    if (internalCompile()) {
56 >      return true;
57      }
58      
59      int icharEnd;
60 <    if ((icharEnd = script.find('\r', ichCurrentCommand)) == std::string:npos &&
61 <        (icharEnd = script.find('\n', ichCurrentCommand)) == std::string:npos) {
62 <        icharEnd = script.size();
60 >    if ((icharEnd = script.find('\r', ichCurrentCommand)) == std::string::npos &&
61 >        (icharEnd = script.find('\n', ichCurrentCommand)) == std::string::npos) {
62 >      icharEnd = script.size();
63      }
64      errorLine = script.substr(ichCurrentCommand, icharEnd);
65      return false;
66 < }
66 >  }
67  
68 < bool SelectionCompiler::internalCompile(){
68 >  bool SelectionCompiler::internalCompile(){
69  
70      cchScript = script.size();
71      ichToken = 0;
# Line 71 | Line 73 | bool SelectionCompiler::internalCompile(){
73  
74      error = false;
75  
76 <    std::vector<Token> lltoken;
76 >    //std::vector<Token> lltoken;
77 >    aatokenCompiled.clear();
78      std::vector<Token> ltoken;
79  
80 <    //Token tokenCommand = null;
81 <    int tokCommand = Token.nada;
80 >    Token tokenCommand;
81 >    int tokCommand = Token::nada;
82  
83      for ( ; true; ichToken += cchToken) {
84 <        if (lookingAtLeadingWhitespace())
85 <            continue;
86 <        if (lookingAtComment())
87 <            continue;
88 <        boolean endOfLine = lookingAtEndOfLine();
89 <        if (endOfLine || lookingAtEndOfStatement()) {
90 <            if (tokCommand != Token.nada) {
91 <                if (! compileCommand(ltoken)) {
92 <                    return false;
93 <                }
94 <            lltoken.push_back(atokenCommand);
95 <            /** @todo*/
96 <            int iCommand = lltoken.size();
97 <            lineNumbers[iCommand] = lineCurrent;
98 <            lineIndices[iCommand] = (short) ichCurrentCommand;
99 <            ltoken.clear();
97 <            tokCommand = Token.nada;
98 <            }
84 >      if (lookingAtLeadingWhitespace())
85 >        continue;
86 >      //if (lookingAtComment())
87 >      //    continue;
88 >      bool endOfLine = lookingAtEndOfLine();
89 >      if (endOfLine || lookingAtEndOfStatement()) {
90 >        if (tokCommand != Token::nada) {
91 >          if (! compileCommand(ltoken)) {
92 >            return false;
93 >          }
94 >          aatokenCompiled.push_back(atokenCommand);
95 >          lineNumbers.push_back(lineCurrent);
96 >          lineIndices.push_back(ichCurrentCommand);
97 >          ltoken.clear();
98 >          tokCommand = Token::nada;
99 >        }
100              
101 <            if (ichToken < cchScript) {
102 <                if (endOfLine)
103 <                    ++lineCurrent;
104 <              continue;
105 <            }
106 <            break;
107 <        }
101 >        if (ichToken < cchScript) {
102 >          if (endOfLine)
103 >            ++lineCurrent;
104 >          continue;
105 >        }
106 >        break;
107 >      }
108  
109 <        if (tokCommand != Token.nada) {
110 <            if (lookingAtString()) {
111 <                std::string str = getUnescapedStringLiteral();
112 <                ltoken.push_back(Token(Token.string, str));
113 <                continue;
114 <            }
115 <            if ((tokCommand & Token.specialstring) != 0 &&
116 <                lookingAtSpecialString()) {
117 <                std::string str = script.substr(ichToken, ichToken + cchToken);
118 <                ltoken.push_back(Token(Token.string, str));
119 <                continue;
120 <            }
121 <            if (lookingAtDecimal((tokCommand & Token.negnums) != 0)) {
122 <                float value = lexi_cast<float>((script.substr(ichToken, ichToken + cchToken));          
123 <                ltoken.push_back(Token(Token.decimal, new Float(value)));/**@todo*/
124 <                continue;
125 <            }
126 <            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(new Token(Token.integer, val, intString));/**@todo*/
129 <                continue;
130 <            }
131 <        }
132 <      
133 <        if (lookingAtLookupToken()) {
134 <            std::string ident = script.subst(ichToken, ichToken + cchToken);
135 <
136 <            /**@todo */
137 <            Token token = (Token) Token.map.get(ident);
138 <            if (token == NULL) {
139 <
140 <            }
141 <            Token token(Token.identifier, ident);
109 >      if (tokCommand != Token::nada) {
110 >        if (lookingAtString()) {
111 >          std::string str = getUnescapedStringLiteral();
112 >          ltoken.push_back(Token(Token::string, str));
113 >          continue;
114 >        }
115 >        //if ((tokCommand & Token::specialstring) != 0 &&
116 >        //    lookingAtSpecialString()) {
117 >        //    std::string str = script.substr(ichToken, ichToken + cchToken);
118 >        //    ltoken.push_back(Token(Token::string, str));
119 >        //    continue;
120 >        //}
121 >        if (lookingAtDecimal((tokCommand & Token::negnums) != 0)) {
122 >          float value = lexi_cast<float>(script.substr(ichToken, cchToken));        
123 >          ltoken.push_back(Token(Token::decimal, boost::any(value)));
124 >          continue;
125 >        }
126 >        if (lookingAtInteger((tokCommand & Token::negnums) != 0)) {
127  
128 +          int val = lexi_cast<int>(script.substr(ichToken, cchToken));
129 +          ltoken.push_back(Token(Token::integer,   boost::any(val)));
130 +          continue;
131 +        }
132 +      }
133 +      
134 +      if (lookingAtLookupToken()) {
135 +        std::string ident = script.substr(ichToken, cchToken);
136 +        Token token;            
137 +        Token* pToken = TokenMap::getInstance()->getToken(ident);
138 +        if (pToken != NULL) {
139 +          token = *pToken;
140 +        } else {
141 +          token = Token(Token::identifier, ident);
142 +        }
143              
144 <            int tok = token.tok;
144 >        int tok = token.tok;
145              
146 <            switch (tokCommand) {
147 <                case Token.nada:
148 <                    ichCurrentCommand = ichToken;
149 <                    //tokenCommand = token;
150 <                    tokCommand = tok;
151 <                    if ((tokCommand & Token.command) == 0)
152 <                    return commandExpected();
153 <                    break;
146 >        switch (tokCommand) {
147 >        case Token::nada:
148 >          ichCurrentCommand = ichToken;
149 >          //tokenCommand = token;
150 >          tokCommand = tok;
151 >          if ((tokCommand & Token::command) == 0)
152 >            return commandExpected();
153 >          break;
154  
155 <                case Token.define:
156 <                    if (ltoken.size() == 1) {
157 <                        // we are looking at the variable name
158 <                        if (tok != Token.identifier &&
159 <                        (tok & Token.predefinedset) != Token.predefinedset)
160 <                        return invalidExpressionToken(ident);
161 <                    } else {
162 <                    // we are looking at the expression
163 <                    if (tok != Token.identifier && tok != Token.set &&
164 <                        (tok & (Token.expression | Token.predefinedset)) == 0)
165 <                        return invalidExpressionToken(ident);
166 <                    }
155 >        case Token::define:
156 >          if (ltoken.size() == 1) {
157 >            // we are looking at the variable name
158 >            if (tok != Token::identifier &&
159 >                (tok & Token::predefinedset) != Token::predefinedset)
160 >              return invalidExpressionToken(ident);
161 >          } else {
162 >            // we are looking at the expression
163 >            if (tok != Token::identifier &&
164 >                (tok & (Token::expression | Token::predefinedset)) == 0)
165 >              return invalidExpressionToken(ident);
166 >          }
167                      
168 <                    break;
168 >          break;
169  
170 <                case Token.select:
171 <                    if (tok != Token.identifier && (tok & Token.expression) == 0)
172 <                        return invalidExpressionToken(ident);
173 <                break;
174 <            }
175 <            ltoken.push_back(token);
176 <            continue;
177 <        }
170 >        case Token::select:
171 >          if (tok != Token::identifier && (tok & Token::expression) == 0)
172 >            return invalidExpressionToken(ident);
173 >          break;
174 >        }
175 >        ltoken.push_back(token);
176 >        continue;
177 >      }
178  
179 <        if (ltoken.size() == 0) {
180 <            return commandExpected();
181 <        }
179 >      if (ltoken.size() == 0) {
180 >        return commandExpected();
181 >      }
182          
183 <        return unrecognizedToken();
183 >      return unrecognizedToken();
184      }
185  
186    aatokenCompiled.push_back(lltoken);
186      return true;
187    }
188  
# Line 206 | Line 205 | bool SelectionCompiler::internalCompile(){
205      if (ch == '\r') {
206        ++ichT;
207        if (ichT < cchScript && script[ichT] == '\n')
208 <          ++ichT;
208 >        ++ichT;
209      } else if (ch == '\n') {
210        ++ichT;
211      } else {
# Line 236 | Line 235 | bool SelectionCompiler::internalCompile(){
235      int ichT = ichToken + 1;
236      //    while (ichT < cchScript && script.charAt(ichT++) != chFirst)
237      char ch;
238 <    boolean previousCharBackslash = false;
238 >    bool previousCharBackslash = false;
239      while (ichT < cchScript) {
240 <      ch = script.[ichT++];
240 >      ch = script[ichT++];
241        if (ch == '"' && !previousCharBackslash)
242          break;
243        previousCharBackslash = ch == '\\' ? !previousCharBackslash : false;
244      }
245      cchToken = ichT - ichToken;
246 +
247      return true;
248    }
249  
250    
251 < std::string SelectionCompiler::getUnescapedStringLiteral() {
252 <    StringBuffer sb = new StringBuffer(cchToken - 2);
251 >  std::string SelectionCompiler::getUnescapedStringLiteral() {
252 >    /** @todo */
253 >    std::string sb(cchToken - 2, ' ');
254 >    
255      int ichMax = ichToken + cchToken - 1;
256      int ich = ichToken + 1;
257  
258      while (ich < ichMax) {
259 <        char ch = script[ich++];
260 <        if (ch == '\\' && ich < ichMax) {
261 <            ch = script[ich++];
262 <            switch (ch) {
263 <                case 'b':
264 <                    ch = '\b';
265 <                    break;
266 <                case 'n':
267 <                    ch = '\n';
268 <                    break;
269 <                case 't':
270 <                    ch = '\t';
271 <                    break;
272 <                case 'r':
273 <                    ch = '\r';
274 <                    // fall into
275 <                case '"':
276 <                case '\\':
277 <                case '\'':
278 <                break;
279 <                case 'x':
280 <                case 'u':
281 <                    int digitCount = ch == 'x' ? 2 : 4;
282 <                    if (ich < ichMax) {
283 <                        int unicode = 0;
284 <                        for (int k = digitCount; --k >= 0 && ich < ichMax; ) {
285 <                            char chT = script[ich];
286 <                            int hexit = getHexitValue(chT);
287 <                            if (hexit < 0)
288 <                                break;
289 <                            unicode <<= 4;
290 <                            unicode += hexit;
291 <                            ++ich;
292 <                        }
293 <                        ch = (char)unicode;
294 <                    }
295 <            }
296 <        }
297 <        sb.append(ch);
259 >      char ch = script[ich++];
260 >      if (ch == '\\' && ich < ichMax) {
261 >        ch = script[ich++];
262 >        switch (ch) {
263 >        case 'b':
264 >          ch = '\b';
265 >          break;
266 >        case 'n':
267 >          ch = '\n';
268 >          break;
269 >        case 't':
270 >          ch = '\t';
271 >          break;
272 >        case 'r':
273 >          ch = '\r';
274 >          // fall into
275 >        case '"':
276 >        case '\\':
277 >        case '\'':
278 >          break;
279 >        case 'x':
280 >        case 'u':
281 >          int digitCount = ch == 'x' ? 2 : 4;
282 >          if (ich < ichMax) {
283 >            int unicode = 0;
284 >            for (int k = digitCount; --k >= 0 && ich < ichMax; ) {
285 >              char chT = script[ich];
286 >              int hexit = getHexitValue(chT);
287 >              if (hexit < 0)
288 >                break;
289 >              unicode <<= 4;
290 >              unicode += hexit;
291 >              ++ich;
292 >            }
293 >            ch = (char)unicode;
294 >          }
295 >        }
296 >      }
297 >      sb.append(1, ch);
298      }
299  
300 <    return "" + sb;
301 < }
300 >    return sb;
301 >  }
302  
303 < static int SelectionCompiler::getHexitValue(char ch) {
303 >  int SelectionCompiler::getHexitValue(char ch) {
304      if (ch >= '0' && ch <= '9')
305 <        return ch - '0';
305 >      return ch - '0';
306      else if (ch >= 'a' && ch <= 'f')
307 <        return 10 + ch - 'a';
307 >      return 10 + ch - 'a';
308      else if (ch >= 'A' && ch <= 'F')
309 <        return 10 + ch - 'A';
309 >      return 10 + ch - 'A';
310      else
311 <        return -1;
312 < }
311 >      return -1;
312 >  }
313  
314 < bool SelectionCompiler::lookingAtSpecialString() {
314 >  bool SelectionCompiler::lookingAtSpecialString() {
315      int ichT = ichToken;
316      char ch = script[ichT];
317      while (ichT < cchScript && ch != ';' && ch != '\r' && ch != '\n') {
318 <        ++ichT;
318 >      ++ichT;
319      }
320      cchToken = ichT - ichToken;
321      return cchToken > 0;
322 < }
322 >  }
323  
324 < bool SelectionCompiler::lookingAtDecimal(boolean allowNegative) {
324 >  bool SelectionCompiler::lookingAtDecimal(bool allowNegative) {
325      if (ichToken == cchScript) {
326 <        return false;
326 >      return false;
327      }
328      
329      int ichT = ichToken;
330      if (script[ichT] == '-') {
331 <        ++ichT;
331 >      ++ichT;
332      }
333 <    boolean digitSeen = false;
333 >    bool digitSeen = false;
334      char ch = 'X';
335      while (ichT < cchScript && std::isdigit(ch = script[ichT])) {
336 <        ++ichT;
337 <        digitSeen = true;
336 >      ++ichT;
337 >      digitSeen = true;
338      }
339  
340      if (ichT == cchScript || ch != '.') {
341 <        return false;
341 >      return false;
342      }
343  
344 <    // to support 1.ca, let's check the character after the dot
345 <    // to determine if it is an alpha
346 <    if (ch == '.' && (ichT + 1 < cchScript) && std::isalpha(script[ichT + 1])) {
345 <        return false;
344 >    // to support DMPC.1, let's check the character before the dot
345 >    if (ch == '.' && (ichT > 0) && std::isalpha(script[ichT - 1])) {
346 >      return false;
347      }
348  
349      ++ichT;
350      while (ichT < cchScript && std::isdigit(script[ichT])) {
351 <        ++ichT;
352 <        digitSeen = true;
351 >      ++ichT;
352 >      digitSeen = true;
353      }
354      cchToken = ichT - ichToken;
355      return digitSeen;
356 < }
356 >  }
357  
358 < bool SelectionCompiler::lookingAtInteger(boolean allowNegative) {
358 >  bool SelectionCompiler::lookingAtInteger(bool allowNegative) {
359      if (ichToken == cchScript) {
360 <        return false;
360 >      return false;
361      }
362      int ichT = ichToken;
363      if (allowNegative && script[ichToken] == '-') {
364 <        ++ichT;
364 >      ++ichT;
365      }
366      int ichBeginDigits = ichT;
367      while (ichT < cchScript && std::isdigit(script[ichT])) {
368 <        ++ichT;
368 >      ++ichT;
369      }
370      if (ichBeginDigits == ichT) {
371 <        return false;
371 >      return false;
372      }
373      cchToken = ichT - ichToken;
374      return true;
375 < }
375 >  }
376  
377 < bool SelectionCompiler::lookingAtLookupToken() {
377 >  bool SelectionCompiler::lookingAtLookupToken() {
378      if (ichToken == cchScript) {
379 <        return false;
379 >      return false;
380      }
381  
382      int ichT = ichToken;
383      char ch;
384      switch (ch = script[ichT++]) {
385 <        case '(':
386 <        case ')':
387 <        case ',':
388 <        case '*':
389 <        case '-':
390 <        case '[':
391 <        case ']':
392 <        case '+':
393 <        case ':':
394 <        case '@':
395 <        case '.':
396 <        case '%':
397 <        break;
398 <        case '&':
399 <        case '|':
400 <            if (ichT < cchScript && script[ichT] == ch) {
401 <                ++ichT;
402 <            }
403 <        break;
404 <        case '<':
405 <        case '=':
406 <        case '>':
407 <            if (ichT < cchScript && ((ch = script[ichT]) == '<' || ch == '=' || ch == '>')) {
408 <                ++ichT;
409 <            }
410 <            break;
411 <        case '/':
412 <        case '!':
413 <            if (ichT < cchScript && script[ichT] == '=') {
414 <                ++ichT;
415 <            }
416 <            break;
417 <        default:
418 <            if ((ch < 'a' || ch > 'z') && (ch < 'A' && ch > 'Z') && ch != '_') {
419 <                return false;
420 <            }
421 <        case '?': // include question marks in identifier for atom expressions
421 <            while (ichT < cchScript && (std::isalpha(ch = script[ichT]) ||std::isdigit(ch) ||
422 <                ch == '_' || ch == '?') ||(ch == '^' && ichT > ichToken && std::isdigit(script[ichT - 1]))) {
423 <                // hack for insertion codes embedded in an atom expression :-(
424 <                // select c3^a
425 <                ++ichT;
426 <            }
427 <        break;
385 >    case '(':
386 >    case ')':
387 >    case ',':
388 >    case '[':
389 >    case ']':
390 >      break;
391 >    case '&':
392 >    case '|':
393 >      if (ichT < cchScript && script[ichT] == ch) {
394 >        ++ichT;
395 >      }
396 >      break;
397 >    case '<':
398 >    case '=':
399 >    case '>':
400 >      if (ichT < cchScript && ((ch = script[ichT]) == '<' || ch == '=' || ch == '>')) {
401 >        ++ichT;
402 >      }
403 >      break;
404 >    case '/':
405 >    case '!':
406 >      if (ichT < cchScript && script[ichT] == '=') {
407 >        ++ichT;
408 >      }
409 >      break;
410 >    default:
411 >      if ((ch < 'a' || ch > 'z') && (ch < 'A' && ch > 'Z') && ch != '_') {
412 >        return false;
413 >      }
414 >    case '*':
415 >    case '?': // include question marks in identifier for atom expressions
416 >      while (ichT < cchScript && !std::isspace(ch = script[ichT]) &&
417 >             (std::isalpha(ch) ||std::isdigit(ch) || ch == '_' || ch == '.' || ch == '*' || ch == '?' || ch == '+' || ch == '-' || ch == '[' || ch == ']') ){
418 >
419 >        ++ichT;
420 >      }
421 >      break;
422      }
423 +
424      cchToken = ichT - ichToken;
425 +
426      return true;
427 < }
427 >  }
428  
429 < bool SelectionCompiler::compileCommand(Vector ltoken) {
430 <    /** todo */
435 <    Token tokenCommand = (Token)ltoken.firstElement();
429 >  bool SelectionCompiler::compileCommand(const std::vector<Token>& ltoken) {
430 >    const Token& tokenCommand = ltoken[0];
431      int tokCommand = tokenCommand.tok;
432 <        
433 <    atokenCommand = new Token[ltoken.size()];
434 <    ltoken.copyInto(atokenCommand);
435 <    if ((tokCommand & Token.expressionCommand) != 0 && !compileExpression()) {
441 <        return false;
432 >
433 >    atokenCommand = ltoken;
434 >    if ((tokCommand & Token::expressionCommand) != 0 && !compileExpression()) {
435 >      return false;
436      }
437 +    
438      return true;
439 < }
439 >  }
440  
441 < bool SelectionCompiler::compileExpression() {
441 >  bool SelectionCompiler::compileExpression() {
442      /** todo */
443      int i = 1;
444      int tokCommand = atokenCommand[0].tok;
445 <    if (tokCommand == Token.define)
445 >    if (tokCommand == Token::define) {
446        i = 2;
447 <    else if ((tokCommand & Token.embeddedExpression) != 0) {
447 >    } else if ((tokCommand & Token::embeddedExpression) != 0) {
448        // look for the open parenthesis
449 <      while (i < atokenCommand.length &&
450 <             atokenCommand[i].tok != Token.leftparen)
449 >      while (i < atokenCommand.size() &&
450 >             atokenCommand[i].tok != Token::leftparen)
451          ++i;
452      }
453 <    if (i >= atokenCommand.length)
453 >
454 >    if (i >= atokenCommand.size()) {
455        return true;
456 +    }
457      return compileExpression(i);
458    }
459  
460                    
461 < bool SelectionCompiler::addTokenToPostfix(Token token) {
461 >  bool SelectionCompiler::addTokenToPostfix(const Token& token) {
462      ltokenPostfix.push_back(token);
463      return true;
464 < }
464 >  }
465  
466 < bool SelectionCompiler::compileExpression(int itoken) {
467 <    ltokenPostfix = new Vector();
468 <    for (int i = 0; i < itoken; ++i)
469 <        addTokenToPostfix(atokenCommand[i]);
470 <
466 >  bool SelectionCompiler::compileExpression(int itoken) {
467 >    ltokenPostfix.clear();
468 >    for (int i = 0; i < itoken; ++i) {
469 >      addTokenToPostfix(atokenCommand[i]);
470 >    }
471 >    
472      atokenInfix = atokenCommand;
473      itokenInfix = itoken;
474  
475 <    addTokenToPostfix(Token.tokenExpressionBegin);
475 >    addTokenToPostfix(Token::tokenExpressionBegin);
476      if (!clauseOr()) {
477 <        return false;
477 >      return false;
478      }
479      
480 <    addTokenToPostfix(Token.tokenExpressionEnd);
481 <    if (itokenInfix != atokenInfix.length) {
482 <        return endOfExpressionExpected();
480 >    addTokenToPostfix(Token::tokenExpressionEnd);
481 >    if (itokenInfix != atokenInfix.size()) {
482 >      return endOfExpressionExpected();
483      }
484  
485      atokenCommand = ltokenPostfix;
486      return true;
487 < }
487 >  }
488  
489 < Token SelectionCompiler::tokenNext() {
490 < if (itokenInfix == atokenInfix.length)
491 < return null;
492 < return atokenInfix[itokenInfix++];
493 < }
489 >  Token SelectionCompiler::tokenNext() {
490 >    if (itokenInfix == atokenInfix.size()) {
491 >      return Token();
492 >    }
493 >    return atokenInfix[itokenInfix++];
494 >  }
495  
496 < Object SelectionCompiler::valuePeek() {
497 <    if (itokenInfix == atokenInfix.length) {
498 <        return null;
496 >  boost::any SelectionCompiler::valuePeek() {
497 >    if (itokenInfix == atokenInfix.size()) {
498 >      return boost::any();
499      } else {
500 <        return atokenInfix[itokenInfix].value;
500 >      return atokenInfix[itokenInfix].value;
501      }
502 < }
502 >  }
503  
504 < int SelectionCompiler::tokPeek() {
505 <    if (itokenInfix == atokenInfix.length) {
506 <        return 0;
504 >  int SelectionCompiler::tokPeek() {
505 >    if (itokenInfix == atokenInfix.size()) {
506 >      return 0;
507      }else {
508 <        return atokenInfix[itokenInfix].tok;
508 >      return atokenInfix[itokenInfix].tok;
509      }
510 < }
510 >  }
511  
512 < bool SelectionCompiler::clauseOr() {
512 >  bool SelectionCompiler::clauseOr() {
513      if (!clauseAnd()) {
514 <        return false;
514 >      return false;
515      }
516      
517 <    while (tokPeek() == Token.opOr) {
518 <        Token tokenOr = tokenNext();
519 <        if (!clauseAnd()) {
520 <            return false;
521 <        }
522 <        addTokenToPostfix(tokenOr);
517 >    while (tokPeek() == Token::opOr) {
518 >      Token tokenOr = tokenNext();
519 >      if (!clauseAnd()) {
520 >        return false;
521 >      }
522 >      addTokenToPostfix(tokenOr);
523      }
524      return true;
525 < }
525 >  }
526  
527 < bool SelectionCompiler::clauseAnd() {
527 >  bool SelectionCompiler::clauseAnd() {
528      if (!clauseNot()) {
529 <        return false;
529 >      return false;
530      }
531  
532 <    while (tokPeek() == Token.opAnd) {
533 <        Token tokenAnd = tokenNext();
534 <        if (!clauseNot()) {
535 <            return false;
536 <        }
537 <        addTokenToPostfix(tokenAnd);
532 >    while (tokPeek() == Token::opAnd) {
533 >      Token tokenAnd = tokenNext();
534 >      if (!clauseNot()) {
535 >        return false;
536 >      }
537 >      addTokenToPostfix(tokenAnd);
538      }
539      return true;
540 < }
540 >  }
541  
542 < bool SelectionCompiler::clauseNot() {
543 <    if (tokPeek() == Token.opNot) {
544 <        Token tokenNot = tokenNext();
545 <        if (!clauseNot()) {
546 <            return false;
547 <        }
548 <        return addTokenToPostfix(tokenNot);
542 >  bool SelectionCompiler::clauseNot() {
543 >    if (tokPeek() == Token::opNot) {
544 >      Token tokenNot = tokenNext();
545 >      if (!clauseNot()) {
546 >        return false;
547 >      }
548 >      return addTokenToPostfix(tokenNot);
549      }
550      return clausePrimitive();
551 < }
551 >  }
552  
553 < bool SelectionCompiler::clausePrimitive() {
553 >  bool SelectionCompiler::clausePrimitive() {
554      int tok = tokPeek();
555      switch (tok) {
556 <        case Token.within:
557 <            return clauseWithin();
559 <        case Token.hyphen: // selecting a negative residue spec
560 <        case Token.integer:
561 <        case Token.seqcode:
562 <        case Token.asterisk:
563 <        case Token.leftsquare:
564 <        case Token.identifier:
565 <        case Token.x:
566 <        case Token.y:
567 <        case Token.z:
568 <        case Token.colon:
569 <            return clauseResidueSpec();
570 <        default:
571 <            if ((tok & Token.atomproperty) == Token.atomproperty) {
572 <                return clauseComparator();
573 <            }
574 <            if ((tok & Token.predefinedset) != Token.predefinedset) {
575 <                break;
576 <            }
577 <            // fall into the code and below and just add the token
578 <        case Token.all:
579 <        case Token.none:
580 <            return addTokenToPostfix(tokenNext());
581 <        case Token.leftparen:
582 <            tokenNext();
583 <            if (!clauseOr()) {
584 <                return false;
585 <            }
586 <            if (tokenNext().tok != Token.rightparen) {
587 <                return rightParenthesisExpected();
588 <            }
589 <            return true;
590 <    }
591 <    return unrecognizedExpressionToken();
592 < }
556 >    case Token::within:
557 >      return clauseWithin();
558  
559 < bool SelectionCompiler::clauseComparator() {
559 >    case Token::asterisk:
560 >    case Token::identifier:
561 >      return clauseChemObjName();
562 >
563 >    case Token::integer :
564 >      return clauseIndex();
565 >    default:
566 >      if ((tok & Token::atomproperty) == Token::atomproperty) {
567 >        return clauseComparator();
568 >      }
569 >      if ((tok & Token::predefinedset) != Token::predefinedset) {
570 >        break;
571 >      }
572 >      // fall into the code and below and just add the token
573 >    case Token::all:
574 >    case Token::none:
575 >      return addTokenToPostfix(tokenNext());
576 >    case Token::leftparen:
577 >      tokenNext();
578 >      if (!clauseOr()) {
579 >        return false;
580 >      }
581 >      if (tokenNext().tok != Token::rightparen) {
582 >        return rightParenthesisExpected();
583 >      }
584 >      return true;
585 >    }
586 >    return unrecognizedExpressionToken();
587 >  }
588 >
589 >  bool SelectionCompiler::clauseComparator() {
590      Token tokenAtomProperty = tokenNext();
591      Token tokenComparator = tokenNext();
592 <    if ((tokenComparator.tok & Token.comparator) == 0) {
593 <        return comparisonOperatorExpected();
592 >    if ((tokenComparator.tok & Token::comparator) == 0) {
593 >      return comparisonOperatorExpected();
594      }
595  
596      Token tokenValue = tokenNext();
597 <    if (tokenValue.tok != Token.integer) {
598 <        return integerExpected();
597 >    if (tokenValue.tok != Token::integer && tokenValue.tok != Token::decimal) {
598 >      return numberExpected();
599      }
600 <    int val = tokenValue.intValue;
601 <    // note that a comparator instruction is a complicated instruction
602 <    // int intValue is the tok of the property you are comparing
603 <    // the value against which you are comparing is stored as an Integer
604 <    // in the object value
605 <    return addTokenToPostfix(new Token(tokenComparator.tok,
606 <                       tokenAtomProperty.tok,
607 <                       new Integer(val)));
608 < }
600 >    
601 >    float val;
602 >    if (tokenValue.value.type() == typeid(int)) {
603 >      val = boost::any_cast<int>(tokenValue.value);
604 >    } else if (tokenValue.value.type() == typeid(float)) {
605 >      val = boost::any_cast<float>(tokenValue.value);
606 >    } else {
607 >      return false;
608 >    }
609  
610 < bool SelectionCompiler::clauseWithin() {
610 >    boost::any floatVal;
611 >    floatVal = val;
612 >    return addTokenToPostfix(Token(tokenComparator.tok,
613 >                                   tokenAtomProperty.tok, floatVal));
614 >  }
615 >
616 >  bool SelectionCompiler::clauseWithin() {
617      tokenNext();                             // WITHIN
618 <    if (tokenNext().tok != Token.leftparen) {  // (
619 <        return leftParenthesisExpected();
618 >    if (tokenNext().tok != Token::leftparen) {  // (
619 >      return leftParenthesisExpected();
620      }
621      
622 <    Object distance;
622 >    boost::any distance;
623      Token tokenDistance = tokenNext();       // distance
624      switch(tokenDistance.tok) {
625 <        case Token.integer:
626 <            distance = new Float((tokenDistance.intValue * 4) / 1000f);
627 <            break;
628 <        case Token.decimal:
629 <            distance = tokenDistance.value;
630 <            break;
630 <        default:
631 <            return numberOrKeywordExpected();
625 >    case Token::integer:
626 >    case Token::decimal:
627 >      distance = tokenDistance.value;
628 >      break;
629 >    default:
630 >      return numberOrKeywordExpected();
631      }
632  
633 <    if (tokenNext().tok != Token.opOr) {       // ,
634 <        return commaExpected();
633 >    if (tokenNext().tok != Token::opOr) {       // ,
634 >      return commaExpected();
635      }
636      
637      if (! clauseOr()) {                        // *expression*
638 <        return false;
638 >      return false;
639      }
640      
641 <    if (tokenNext().tok != Token.rightparen) { // )T
642 <        return rightParenthesisExpected();
641 >    if (tokenNext().tok != Token::rightparen) { // )T
642 >      return rightParenthesisExpected();
643      }
644      
645 <    return addTokenToPostfix(new Token(Token.within, distance));
646 < }
645 >    return addTokenToPostfix(Token(Token::within, distance));
646 >  }
647  
648 < bool SelectionCompiler:: clauseChemObject() {
649 < }
648 >  bool SelectionCompiler::clauseChemObjName() {
649 >    Token token = tokenNext();
650 >    if (token.tok == Token::identifier && token.value.type() == typeid(std::string)) {
651  
652 < bool SelectionCompiler:: clauseMolecule() {
653 < }
652 >      std::string name = boost::any_cast<std::string>(token.value);
653 >      if (isNameValid(name)) {
654 >        return addTokenToPostfix(Token(Token::name, name));
655 >      } else {
656 >        return compileError("invalid name: " + name);
657 >      }
658 >    }
659  
660 < bool SelectionCompiler:: clauseMolName() {
661 < }
660 >    return false;
661 >        
662 >  }
663  
664 < bool SelectionCompiler:: clauseMolIndex() {
665 < }
664 >  bool SelectionCompiler::isNameValid(const std::string& name) {
665 >    int nbracket = 0;
666 >    int ndot = 0;
667 >    for (int i =0 ; i < name.size(); ++i) {
668 >      switch(name[i]) {
669  
670 < bool SelectionCompiler:: clauseName() {
671 < }
670 >      case '[' :
671 >        ++nbracket;
672 >        break;
673 >      case ']' :
674 >        --nbracket;
675 >        break;
676 >      case '.' :
677 >        ++ndot;
678 >        break;      
679 >      }
680 >    }
681  
682 < bool SelectionCompiler:: clauseIndex() {
683 < }
682 >    //only allow 3 dots at most
683 >    return (ndot <=3 && nbracket == 0) ? true : false;
684 >  }
685  
686 < bool SelectionCompiler:: clauseStuntDoubleName() {
687 < }
686 >  bool SelectionCompiler::clauseIndex(){
687 >    Token token = tokenNext();
688 >    if (token.tok == Token::integer) {
689 >      int index = boost::any_cast<int>(token.value);
690 >      int tok = tokPeek();
691 >      std::cout << "Token::to is " << Token::to << ", tok = " << tok << std::endl;
692 >      if (tok == Token::to) {
693 >        tokenNext();
694 >        tok = tokPeek();
695 >        if (tok != Token::integer) {
696 >          return numberExpected();
697 >        }
698 >            
699 >        boost::any intVal = tokenNext().value;
700 >        int first = index;
701 >        if (intVal.type() != typeid(int)){
702 >          return false;
703 >        }
704 >        int second = boost::any_cast<int>(intVal);
705  
706 < bool SelectionCompiler:: clauseStuntDoubleIndex() {
707 < }
706 >        return addTokenToPostfix(Token(Token::index, boost::any(std::make_pair(first, second))));
707 >            
708 >      }else {
709 >        return addTokenToPostfix(Token(Token::index, boost::any(index)));
710 >      }
711 >    } else {
712 >      return numberExpected();
713 >    }
714 >  }
715  
716   }

Comparing:
trunk/src/selection/SelectionCompiler.cpp (property svn:keywords), Revision 279 by tim, Wed Feb 2 12:51:25 2005 UTC vs.
branches/development/src/selection/SelectionCompiler.cpp (property svn:keywords), Revision 1465 by chuckv, Fri Jul 9 23:08:25 2010 UTC

# Line 0 | Line 1
1 + Author Id Revision Date

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines