public function recursiveAnalyse(array &$data) { if (isset($data['nonTerminal'])) { foreach ($data['terminals'] as &$trm) { $this->recursiveAnalyse($trm); } $type = TypeDetector::analyseExpression($data['terminals'], $this->varScope); $data['type'] = $type; } elseif (isset($data['value'])) { $data['type'] = Type::TYPE_MIXED; if ($data['code'] == T_VARIABLE) { if (!isset($this->varScope[$data['value']])) { $this->varScope[$data['value']] = new Variable($data['value']); } } elseif ($data['code'] == T_DNUMBER) { $data['type'] = Type::TYPE_FLOAT; } elseif ($data['code'] == T_LNUMBER) { $data['type'] = Type::TYPE_INT; } elseif ($data['code'] == T_CONSTANT_ENCAPSED_STRING) { $data['type'] = Type::TYPE_STRING; } elseif ($data['code'] == T_STRING) { $data['type'] = FunctionReturnType::get($data['value']); } } else { throw new PrecedenceException('Got unexpected structure. ' . print_r($data)); } }
static function analyseExpression($expr, Scope $scope) { $type = Type::TYPE_MIXED; if (!isset($expr['terminals'])) { if (isset($expr[0]) && !isset($expr[0]['terminals'])) { if ($expr[0]['code'] == T_VARIABLE) { // TODO - detect from scope $type = Type::TYPE_MIXED; } elseif ($expr[0]['code'] == T_LNUMBER) { $type = Type::TYPE_INT; } elseif ($expr[0]['code'] == T_DNUMBER) { $type = Type::TYPE_FLOAT; } elseif ($expr[0]['code'] == T_RPARENTHESIS) { $type = $expr[1]['type']; } elseif ($expr[0]['code'] == T_CONSTANT_ENCAPSED_STRING) { $type = Type::TYPE_STRING; } if ($expr[0]['code'] == T_RPARENTHESIS) { // Function call? if (count($expr) >= 3) { if (isset($expr[count($expr) - 1]['code']) && isset($expr[count($expr) - 2]['code']) && $expr[count($expr) - 1]['code'] == T_STRING && $expr[count($expr) - 2]['code'] == T_LPARENTHESIS) { $type = FunctionReturnType::get($expr[count($expr) - 1]['value']); } } } } else { var_dump($expr); if (isset($expr[1]) && isset($expr[2])) { $type = self::detectOperator($expr[1]['code'], $expr[0], $expr[2]); } elseif (isset($expr[1]) && isset($expr[1]['code'])) { // Neg, pre inc/dec $type = self::detectOperator($expr[1]['code']); } elseif (isset($expr[1]) && isset($expr[0]['code'])) { // post inc/dec $type = self::detectOperator($expr[0]['code']); } } } else { var_dump($expr); } return $type; }