/** * 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'))); }
private static function divideString($tokenStream) { $newTokenStream = array(); foreach ($tokenStream as $node) { if ($node->type != ExpType::$RAW) { // bypass the proceed nodes array_push($newTokenStream, $node); continue; } $str = $node->value; $state = 0; // 0: seeking, 1: found "'", 2: found '"' $pos = 0; for ($i = 0; $i < strlen($str); $i++) { if ($str[$i] != "'" && $str[$i] != '"') { continue; } $targetState = $str[$i] == "'" ? 1 : 2; if ($state == 0) { // found "'" or '"' $state = $targetState; if ($pos != $i) { // output the previous segment $newnode = new Token(ExpType::$RAW, substr($str, $pos, $i - $pos)); array_push($newTokenStream, $newnode); } $pos = $i + 1; } elseif ($state == $targetState) { // test whether it has been escaped if (ExpLexer::isEscaped($str, $i)) { continue; } // bypass the escaped ones // output the string segment $string = ExpType::coerceToString(new Token(ExpType::$RAW, substr($str, $pos, $i - $pos))); array_push($newTokenStream, $string); $pos = $i + 1; $state = 0; } } if ($state != 0) { // there's open quote exists throw new ExpLexerException("Unterminated string: " . $str); } if ($pos != strlen($str)) { // output the remaining segment $newnode = new Token(ExpType::$RAW, substr($str, $pos, strlen($str) - $pos)); array_push($newTokenStream, $newnode); } } return $newTokenStream; }