JSON的组成
一个合法的JSON字符串可以包含这几种元素:
- 特殊符号,如 "{" "}" 表示一个JSON Object,"[" "]" 表示一个JSON Array,":"用于分隔key-value,"," 用于分隔两个元素
- 字符串,用引号引起来
- 数字,包含0-9,浮点数带有".",表示符号可带有"+" "-"
- 常量有true,false,null
分词(or 词法分析)
分词的主要目的是将字符串分割成一个个合法的元素,其中每一个特殊符号都为一个元素,一个完整的字符串表达是一个元素,一个完整的数字表达等等
不难发现,特殊元素都只包含一个字符,常量,数字的表示中间均不会出现空格或其他不相关字符,因此可以轻易地用表达的特征区分,例如数字可以匹配一段连续的且所有字符都是在0-9或有"." "+", "-"的子序列(至于表达是否合法,稍后再做处理)。而字符串较为特殊,字符串原则上讲可以包含任何字符,但字符串也有自己的特征,以 " 开始,又以两一个 " 结束,虽然字符串中间也可能出现 " 但若是合法表达,就必须使用 '\' 转义 ,注意处理转义字符就好了,下面是词法分析的代码
class __Tokener:
def __init__(self, json_str):
self.__str = json_str
self.__i = 0
self.__cur_token = None
def __cur_char(self):
if self.__i < len(self.__str):
return self.__str[self.__i]
return ''
def __move_i(self, step=1):
if self.__i < len(self.__str):
self.__i += step
def __next_string(self):
outstr = ''
trans_flag = False
self.__move_i()
while self.__cur_char() != '':
ch = self.__cur_char()
if ch == '\\': # 注意处理转义
trans_flag = True
else:
if not trans_flag:
if ch == '"':
break
else:
trans_flag = False
outstr += ch
self.__move_i()
return outstr
def __next_number(self):
expr = ''
while self.__cur_char().isdigit() or self.__cur_char() in ('.', '+', '-'):
expr += self.__cur_char()
self.__move_i()
self.__move_i(-1)
if '.' in expr: # 若数字表达非法,则下面的转换会抛出异常
return float(expr)
else:
return int(expr)
def __next_const(self):
outstr = ''
while self.__cur_char().isalpha():
outstr += self.__cur_char()
self.__move_i()
self.__move_i(-1)
if outstr in ('true', 'false', 'null'): # 如果不在之中的其他表达都是非法的
return {
'true': True,
'false': False,
'null': None
}[outstr]
raise Exception('Invalid symbol "%s"' % outstr)
def next(self):
is_white_space = lambda a_char: a_char in (