[Asm] 纯文本查看 复制代码
//mshell json模块
//by: zixing
//2020-09-22
use array;
class Tokener
jsonstr
_cur_token
i
function init(str)
this.jsonstr = str;
this.i=0;
_cur_token = null;
end;
function cur_char()
if i<len(jsonstr) then
return substr(jsonstr,i,1);
else
return "";
end;
end;
function move_i(step=1)
if i<len(jsonstr) then
i+=step;
end;
end;
function next_string()
outstr = '';
trans_flag = false;
move_i();
while cur_char()#'' do
ch = cur_char();
if ch = '\\' then
trans_flag = true;
else
if trans_flag=false then
if ch = '"' then
break;
end;
else
trans_flag=false;
end;
end;
outstr = outstr+ch;
move_i();
end;
return outstr;
end;
function next_number()
expr = '';
ls = ['0','1','2','3','4','5','6','7','8','9','.', '+', '-','e','E'];
while array.index(ls,cur_char())>-1 do
expr = expr+cur_char();
move_i();
end;
move_i(-1);
return num(expr);
end;
function isalpha(cchar)
numchar = code(cchar,0);
if ((numchar>=65) and (numchar<=90)) or ((numchar>=97) and (numchar<=122)) then
return true;
else
return false;
end;
end;
function next_const()
outstr = '';
while isalpha(cur_char()) do
outstr = outstr+cur_char();
move_i();
end;
move_i(-1);
ls = ['true', 'false', 'null'];
if array.index(ls,outstr)>-1 then
t = ['true': true, 'false': false,'null': null];
return t[outstr];
end;
end;
function next()
ls = ['\x20', '\n', '\r', '\t'];
while array.index(ls,cur_char())>-1 do
move_i();
end;
ch = cur_char();
if ch = '' then
cur_token = null;
elsif array.index(['{', '}', '[', ']', ',', ':'],ch)>-1 then
cur_token = ch;
elsif ch = '"' then
cur_token = next_string();
elsif isalpha(ch) then
cur_token = next_const();
elsif array.index(['0','1','2','3','4','5','6','7','8','9','.', '+', '-','e','E'],ch)>-1 then
cur_token = next_number();
else
print "Invalid symbol "+ch;
end;
move_i();
_cur_token = cur_token;
return cur_token # null;
end;
function cur_token()
//print(_cur_token);
return _cur_token;
end;
end;
class JsonDecoder
function __json_array(tokener:Tokener) forward
function __json_object(tokener:Tokener)
obj = [];
if tokener.cur_token() # '{' then
print('Json must start with "{"');
return;
end;
while true do
tokener.next();
tk_temp = tokener.cur_token();
//print 'tk_temp:'+tk_temp;
if tk_temp = '}' then
return [];
end;
if not isstr(tk_temp) then
print 'invalid key ' + tk_temp;
return;
end;
key = tk_temp;
tokener.next();
if tokener.cur_token()#':' then
print 'expect ":" after "'+key+'"';
return;
end;
tokener.next();
val = tokener.cur_token();
//print 'val:'+val;
if val = '[' then
val = this.__json_array(tokener);
elsif val = '{' then
val = this.__json_object(tokener);
end;
obj[key] = val;
tokener.next();
tk_split = tokener.cur_token();
if tk_split = ',' then
a = 0; //continue
else
if tk_split = '}' then
break;
else
if tk_split = null then
print 'missing "}" at at the end of object';
return;
end;
end;
print 'unexpected token "'+tk_split+'" at key "'+key+'"';
return;
end;
end;
return obj;
end;
function __json_array(tokener:Tokener)
if tokener.cur_token()#'[' then
print 'Json array must start with "["';
return;
end;
arr = [];
while true do
tokener.next();
tk_temp = tokener.cur_token();
if tk_temp = ']' then
return [];
end;
if tk_temp = '{' then
val = this.__json_object(tokener);
elsif tk_temp = '[' then
val = this.__json_array(tokener);
elsif array.index([',', ':', '}'],tk_temp)>-1 then
print 'unexpected token "'+tk_temp+'"' ;
return;
else
val = tk_temp;
end;
append(arr,val);
tokener.next();
tk_end = tokener.cur_token();
if tk_end = ',' then
a = 1; //continue
end;
if tk_end = ']' then
break;
else
if tk_end = null then
print 'missing "]" at the end of array';
return;
end;
end;
end;
return arr;
end;
function decode(json_str)
tokener:Tokener = Tokener(json_str);
if not tokener.next() then
return null;
end;
first_token = tokener.cur_token();
if first_token = '{' then
decode_val = this.__json_object(tokener);
elsif first_token = '[' then
decode_val = this.__json_array(tokener);
else
print 'Json must start with "{"';
return;
end;
if tokener.next() then
print 'unexpected token "'+tokener.cur_token()+'"';
return;
end;
return decode_val;
end;
function loads(json_str)
return decode(json_str);
end;
end;