Example #1
0
 public static function parse($tokenStream, $dataContext)
 {
     $scopes = array();
     $expression = new PrimitiveExp(new Token('final'));
     while ($token = array_shift($tokenStream)) {
         // split non-primitive expression into primitive ones
         switch ($token->type) {
             case ExpType::$PAREN:
                 switch ($token->value) {
                     case '[':
                         $expression->append(new Token(ExpType::$DOT, '.'));
                         // drop through
                     // drop through
                     case '(':
                         ExpParser::scopePush($expression, $scopes, $token);
                         break;
                     case ']':
                         if ($expression->reason->value != '[') {
                             throw new ExpParserException("Unbalanced [], should be detected in Lexer");
                         }
                         ExpParser::scopePop($expression, $scopes, $dataContext);
                         break;
                     case ')':
                         if ($expression->reason->value != '(') {
                             throw new ExpParserException("Unbalanced (), should be detected in Lexer");
                         }
                         ExpParser::scopePop($expression, $scopes, $dataContext);
                         // close if it's a function
                         if ($expression->reason->type == ExpType::$FUNCTION) {
                             ExpParser::scopePop($expression, $scopes, $dataContext);
                         }
                         break;
                     default:
                         throw new ExpParserException("Token error: " . print_r($token, true));
                 }
                 break;
             case ExpType::$FUNCTION:
                 ExpParser::scopePush($expression, $scopes, $token);
                 break;
             case ExpType::$TERNARY:
                 if ($token->value != '?') {
                     throw new ExpParserException("Ternary token error");
                 }
                 $nextTernary = ExpParser::findNextTernary($tokenStream, 1);
                 $indicator = ExpType::coerceToBool($expression->evaluate($dataContext));
                 if ($indicator->value) {
                     // parsed?todo:skip
                     $nextCloseSymbol = ExpParser::findNextCloseSymbol($tokenStream, $nextTernary + 1);
                     array_splice($tokenStream, $nextTernary, $nextCloseSymbol - $nextTernary);
                 } else {
                     // parsed?skip:todo
                     $tokenStream = array_slice($tokenStream, $nextTernary + 1);
                 }
                 $expression = new PrimitiveExp($expression->reason);
                 break;
             case ExpType::$COMMA:
                 if ($expression->reason->value != '(') {
                     throw new ExpParserException("Unbalanced (), should be detected in Lexer");
                 }
                 ExpParser::scopePop($expression, $scopes, $dataContext);
                 ExpParser::scopePush($expression, $scopes, new Token(ExpType::$PAREN, '('));
                 break;
             default:
                 $expression->append($token);
         }
     }
     if ($expression->reason->type != 'final') {
         throw new ExpParserException("Gramma error on the non-primitive expression");
     }
     return $expression->evaluate($dataContext);
 }