private static function parseValue($val)
    {
        $parsedVal = null;

        // Cleanup
        $val = trim($val);

        if($val === '')
        {
            throw new Exception('Empty value not allowed');
        }

        // Boolean
        if($val == 'true' || $val == 'false')
        {
            $parsedVal = ($val == 'true');
        }
        // Literal multi-line string
        elseif(substr($val, 0, 3) == "'''" && substr($val, -3) == "'''")
        {
            $parsedVal = substr($val, 3, -3);

            // Trim first newline on multi-line string definition
            if($parsedVal[0] == "\n")
            {
                $parsedVal = substr($parsedVal, 1);
            }
        }
        // Literal string
        elseif($val[0] == "'" && substr($val, -1) == "'")
        {
            // No newlines allowed
            if(strpos($val, "\n") !== false)
            {
                throw new Exception('New lines not allowed on single line string literals.');
            }

            $parsedVal = substr($val, 1, -1);
        }
        // Multi-line string
        elseif(substr($val, 0, 3) == '"""' && substr($val, -3) == '"""')
        {
            $parsedVal = substr($val, 3, -3);

            // Trim first newline on multi-line string definition
            if($parsedVal[0] == "\n")
            {
                $parsedVal = substr($parsedVal, 1);
            }

            // Use json_decode to finally parse the string.
            $parsedVal = json_decode('"' . str_replace("\n", '\n', $parsedVal) . '"');
        }
        // String
        elseif($val[0] == '"' && substr($val, -1) == '"')
        {
            // TOML's specification says it's the same as for JSON format... so
            $parsedVal = json_decode($val);
        }
        // Numbers
        elseif(is_numeric(str_replace('_', '', $val)))
        {
            $val = str_replace('_', '', $val);

            $intVal = filter_var($val, FILTER_VALIDATE_INT);
            if($intVal !== false)
            {
                $parsedVal = $intVal;
            }
            else
            {
                $parsedVal = (float) $val;
            }
        }
        // Datetime. Parsed to UNIX time value.
        elseif(self::isISODate($val))
        {
            $parsedVal = new DateTime($val);
        }
        // Single line array (normalized)
        elseif($val[0] == '[' && substr($val, -1) == ']')
        {
            $parsedVal = self::parseArray($val);
        }
        // Inline table (normalized)
        elseif($val[0] == '{' && substr($val, -1) == '}')
        {
            $parsedVal = self::parseInlineTable($val);
        }
        else
        {
            throw new Exception('Unknown value type: ' . $val);
        }

        return $parsedVal;
    }