function _getNextToken() //返回的是规定的几种预定义字符 {,},[,],;,:,DATUM,EOF
{
$this->_token = EOF; // 赋值为EOF 0
$this->_tokenValue = null;
//添加全局变量 tokenvalue ,如果switch语句匹配的是非双引号,则tokenValue==null
/* 转义字符序列
* /t----------tab
* /b----------backspace
* /f----------formfeed
* /n----------换行
* /r----------回车
*/
//匹配特殊字符,这些字符仅在message时有用,对buddylist不可能出现。故if语句不起作用
if (preg_match('/([/t/b/f/n/r ]+)/', $this->_source, $matches, PREG_OFFSET_CAPTURE, $this->_offset) && $matches[0][1] == $this->_offset)
// 在原始字符串中匹配第一个正则表达式(由若干个连续的特殊字符组成),并要求
//从this->offset开始匹配,并且刚好有特殊字符
//第一次执行该_getNextToken()方法时匹配到的是LBRACE
{
$this->_offset += strlen($matches[0][0]); //$matches[0][0] 匹配到的字符串
//匹配到的长度累加
}
if ($this->_offset >= $this->_sourceLength) //到头了
{
return EOF;
}
$str = $this->_source; //原始字符串
$str_length = $this->_sourceLength; //原始字符串长度
//偏移量,注意,i的位置位于正则表达式结束的地方!对decode一个buddylist而言,i==0
$i = $this->_offset;
$start = $i; //开始位置
switch ($str[$i]) //现在的位置,得到现在的token,并赋值给token ,此处仅检验一个字符
//注意:在swtich语句中使用的是i,this->_offset并未改变
{
case '{':
$this->_token = LBRACE;
break;
case '}':
$this->_token = RBRACE;
break;
case '[':
$this->_token = LBRACKET;
break;
case ']':
$this->_token = RBRACKET;
break;
case ',':
$this->_token = COMMA;
break;
case ':':
$this->_token = COLON;
break;
case '"': //双引号哦!
$result = ''; //空
do //将遍历结果存在result中
{
if ($i++ >= $str_length) // 转向下一个字符,防止越界
{
break;
}
$chr = $str[$i]; //得到当前字符
if ($chr == '//') //如果当前字符为反斜杠/,注意下一个字符为转义字符
// result 加上改转义字符
{
if ($i++ >= $str_length) //防止越界,i指向下一个字符
{
break;
}
$chr = $str[$i]; //得到字符
switch ($chr)
{
case '"' : // 反斜杠后的双引号
$result .= '"';
break;
case '//': // 反斜杠
$result .= '//';
break;
case '/' :
$result .= '/';
break;
case 'b' :
$result .= chr(8); // 退格
break;
case 'f' :
$result .= chr(12); //formFeed
break;
case 'n' :
$result .= chr(10); //换行
break;
case 'r' :
$result .= chr(13); //回车
break;
case 't' :
$result .= chr(9); //制表
break;
}
}
else if ($chr == '"') // 不跟在反斜杠后的双引号,字符串匹配结束,case语句终止
{
break; //跳出循环,得到一个字符串
}
else //既不是转义字符,也不是双引号
{
$result .= $chr; //得到当前字符
}
}
while ($i < $str_length); //直到字符串结束
$this->_token = DATUM; //常规字符
//$this->_tokenValue = substr($str, $start + 1, $i - $start - 1);
$this->_tokenValue = $result; //注意!result是个字符串
break;
case 't': //tab
if (($i + 3) < $str_length && substr($str, $start, 4) == 'true')
{
$this->_token = DATUM;
}
$this->_tokenValue = true;
$i += 3;
break;
case 'f':
if (($i + 4) < $str_length && substr($str, $start, 5) == 'false')
{
$this->_token = DATUM;
}
$this->_tokenValue = false;
$i += 4;
break;
case 'n':
if (($i + 3) < $str_length && substr($str, $start, 4) == 'null')
{
$this->_token = DATUM;
}
$this->_tokenValue = NULL;
$i += 3;
break;
}
if ($this->_token != EOF) //switch语句中的case得到匹配
{
$this->_offset = $i + 1; // Consume the last token character 证明了,swtich语句中有匹配的必定是第一个字符
return($this->_token);
}
// 未得到匹配
$chr = $str[$i]; //当前字符
// this->_token==EOF,switch语句都没有执行,表明该字符非token,注意,_getNextToke()一开始就this->_token==EOF
if (preg_match('/-?([0-9]*)(/.[0-9]*)?(([eE])[-+]?[0-9]+)?/s', $str, $matches, PREG_OFFSET_CAPTURE, $start) && $matches[0][1] == $start)
{
// it's a nubmer on this position ,当前字符为数字 , eg : ---3.3.3e+33
$datum = $matches[0][0];
$val = intval($datum); // 转为整型
$fVal = floatval($datum); //转为浮点型
$this->_tokenValue = ($val == $fVal ? $val : $fVal); //以高精度为准
$this->_token = DATUM;
$this->_offset = $start + strlen($datum);
}
return($this->_token);
}
}
JSON PHP 完全注释(一)
最新推荐文章于 2021-03-24 12:43:31 发布