示例#1
0
 /**
  * Tests ExpType::coerce
  */
 public function testCoerce()
 {
     // coerce number
     $this->assertEquals($this->tokens['int'], ExpType::coerceToNumber($this->tokens['int']));
     $this->assertEquals($this->tokens['float'], ExpType::coerceToNumber($this->tokens['float']));
     $this->assertEquals(new Token(ExpType::$INT, 2), ExpType::coerceToNumber(new Token(ExpType::$RAW, '2')));
     $this->assertEquals(new Token(ExpType::$INT, 2), ExpType::coerceToNumber(new Token(ExpType::$STRING, '2')));
     $this->assertEquals(new Token(ExpType::$INT, 1), ExpType::coerceToNumber(new Token(ExpType::$BOOL, true)));
     $this->assertEquals(new Token(ExpType::$INT, 0), ExpType::coerceToNumber(new Token(ExpType::$BOOL, false)));
     $this->assertEquals(new Token(ExpType::$INT, 0), ExpType::coerceToNumber(new Token(ExpType::$NULL, null)));
     $this->assertEquals(new Token(ExpType::$FLOAT, 1.0), ExpType::coerceToNumber(new Token(ExpType::$RAW, '1.0')));
     $this->assertEquals(new Token(ExpType::$FLOAT, 1.0), ExpType::coerceToNumber(new Token(ExpType::$STRING, '1.0')));
     // coerce string
     $this->assertEquals($this->tokens['string'], ExpType::coerceToString($this->tokens['string']));
     $this->assertEquals(new Token(ExpType::$STRING, '2'), ExpType::coerceToString(new Token(ExpType::$RAW, '2')));
     $this->assertEquals(new Token(ExpType::$STRING, '2'), ExpType::coerceToString(new Token(ExpType::$INT, 2)));
     $this->assertEquals(new Token(ExpType::$STRING, '2'), ExpType::coerceToString(new Token(ExpType::$FLOAT, 2.0)));
     $this->assertEquals(new Token(ExpType::$STRING, '2.5'), ExpType::coerceToString(new Token(ExpType::$FLOAT, 2.5)));
     $this->assertEquals(new Token(ExpType::$STRING, 'true'), ExpType::coerceToString(new Token(ExpType::$BOOL, true)));
     $this->assertEquals(new Token(ExpType::$STRING, 'false'), ExpType::coerceToString(new Token(ExpType::$BOOL, false)));
     $this->assertEquals(new Token(ExpType::$STRING, 'null'), ExpType::coerceToString(new Token(ExpType::$NULL, null)));
     // coerce bool
     $this->assertEquals($this->tokens['bool'], ExpType::coerceToBool($this->tokens['bool']));
     $this->assertEquals(new Token(ExpType::$BOOL, true), ExpType::coerceToBool(new Token(ExpType::$RAW, 'True')));
     $this->assertEquals(new Token(ExpType::$BOOL, true), ExpType::coerceToBool(new Token(ExpType::$RAW, 'true')));
     $this->assertEquals(new Token(ExpType::$BOOL, false), ExpType::coerceToBool(new Token(ExpType::$RAW, 'False')));
     $this->assertEquals(new Token(ExpType::$BOOL, false), ExpType::coerceToBool(new Token(ExpType::$RAW, 'false')));
     $this->assertEquals(new Token(ExpType::$BOOL, true), ExpType::coerceToBool(new Token(ExpType::$STRING, 'false')));
     $this->assertEquals(new Token(ExpType::$BOOL, false), ExpType::coerceToBool(new Token(ExpType::$STRING, '')));
     $this->assertEquals(new Token(ExpType::$BOOL, true), ExpType::coerceToBool(new Token(ExpType::$INT, 2)));
     $this->assertEquals(new Token(ExpType::$BOOL, false), ExpType::coerceToBool(new Token(ExpType::$INT, 0)));
     $this->assertEquals(new Token(ExpType::$BOOL, true), ExpType::coerceToBool(new Token(ExpType::$FLOAT, 2.0)));
     $this->assertEquals(new Token(ExpType::$BOOL, false), ExpType::coerceToBool(new Token(ExpType::$FLOAT, 0.0)));
     $this->assertEquals(new Token(ExpType::$BOOL, false), ExpType::coerceToBool(new Token(ExpType::$NULL, null)));
     // coerce null
     $this->assertEquals($this->tokens['null'], ExpType::coerceToNull($this->tokens['null']));
     $this->assertEquals($this->tokens['null'], ExpType::coerceToNull(new Token(ExpType::$RAW, 'null')));
 }
示例#2
0
 private static function evaluateLiterals(&$tokenStream)
 {
     for ($i = 0; $i < count($tokenStream); $i++) {
         $node = $tokenStream[$i];
         if ($node->type != ExpType::$RAW) {
             continue;
         }
         $str = strtolower($node->value);
         if ($str == 'true' || $str == 'false') {
             $tokenStream[$i] = ExpType::coerceToBool($node);
         } elseif ($str == 'null') {
             $tokenStream[$i] = ExpType::coerceToNull($node);
         } elseif (preg_match(ExpLexer::$NUMBER_PATTERN, $str) == 1) {
             $tokenStream[$i] = ExpType::coerceToNumber($node);
         } elseif (preg_match(ExpLexer::$IDENTITY_PATTERN, $str) == 1) {
             // is identity
             $tokenStream[$i]->type = ExpType::$IDENTITY;
         } else {
             // mal-format
             throw new ExpLexerException("Mal-format expression segment: " . $node->value);
         }
     }
 }
示例#3
0
 private function compute($operandStack, $operator)
 {
     $ARITHMETIC_OPS = array('+', ' - ', '*', '/', '%');
     // without unary operator ' -'
     $RELATIONAL_OPS = array('==', '!=', '<', '>', '<=', '>=');
     $LOGICAL_OPS = array('&&', '||');
     // without '!'
     $sym = $operator->value;
     if ($operator->type == ExpType::$UNARY_OP) {
         $operand = $this->evaluateIdentity(array_pop($operandStack));
     } else {
         $rhs = array_pop($operandStack);
         $rhs = $sym != '.' ? $this->evaluateIdentity($rhs) : $rhs;
         $lhs = $this->evaluateIdentity(array_pop($operandStack));
     }
     if ($sym == '.') {
         if ($lhs->type == ExpType::$NULL || $rhs->type == ExpType::$NULL) {
             // Dealing with null type
             $result = new Token(ExpType::$NULL, null);
         } else {
             if ($lhs->type == ExpType::$ARRAY) {
                 if ($rhs->type == ExpType::$INT || $rhs->type == ExpType::$STRING || $rhs->type == ExpType::$IDENTITY) {
                     $resval = isset($lhs->value[$rhs->value]) ? $lhs->value[$rhs->value] : null;
                 } else {
                     throw new ExpParserException("Can't reference key typ " . print_r($rhs, true) . " on array");
                 }
             } elseif ($lhs->type == ExpType::$OBJECT) {
                 if ($rhs->type == ExpType::$IDENTITY) {
                     eval('$resval = isset($lhs->value->' . $rhs->value . ')? $lhs->value->' . $rhs->value . ': null;');
                 } else {
                     throw new ExpParserException("Can't reference key typ " . print_r($rhs, true) . " on object");
                 }
             } else {
                 throw new ExpParserException("Can't perform ./[] operation on primitive type " . print_r($lhs, true));
             }
             $result = new Token(ExpType::detectType($resval), $resval);
         }
     } elseif ($sym == 'empty') {
         $result = new Token(ExpType::$BOOL, empty($operand->value));
     } elseif (in_array($sym, $ARITHMETIC_OPS)) {
         $lhs = ExpType::coerceToNumber($lhs);
         $rhs = ExpType::coerceToNumber($rhs);
         eval('$resval = $lhs->value ' . $sym . '$rhs->value;');
         $result = new Token(ExpType::detectType($resval), $resval);
     } elseif ($sym == ' -') {
         // Unary operator '-'
         $result = ExpType::coerceToNumber($operand);
         $result = new Token($result->type, -$result->value);
     } elseif (in_array($sym, $RELATIONAL_OPS)) {
         $result = new Token(ExpType::$BOOL);
         // special case: one of the operator is null
         if ($lhs->type == ExpType::$NULL && $rhs->type != ExpType::$NULL || $lhs->type != ExpType::$NULL && $rhs->type == ExpType::$NULL) {
             $result->value = in_array($sym, array('<', '>', '<=', '>=', '==')) ? false : true;
         }
         eval('$result->value = $lhs->value ' . $sym . ' $rhs->value;');
     } elseif (in_array($sym, $LOGICAL_OPS)) {
         $result = new Token(ExpType::$BOOL);
         $lhs = ExpType::coerceToBool($lhs);
         $rhs = ExpType::coerceToBool($rhs);
         eval('$result->value = $lhs->value ' . $sym . ' $rhs->value;');
     } elseif ($sym == '!') {
         $result = ExpType::coerceToBool($operand);
         $result = new Token(ExpType::$BOOL, !$result->value);
     } else {
         throw new ExpParserException("Uncovered operator: " . $sym);
     }
     array_push($operandStack, $result);
     return $operandStack;
 }