码迷,mamicode.com
首页 > Web开发 > 详细

一个JSON解析器

时间:2019-10-27 14:21:29      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:com   throw   als   syntax   number   hold   双引号   class   UNC   

 

来源

 

《JavaScript语言精粹(修订版)》

 

代码

 

  1 <!DOCTYPE html>
  2 <html>
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <title></title>
  7 </head>
  8 
  9 <body>
 10     <script>
 11         var json_parse = function () {
 12             var
 13                 at,
 14                 ch,
 15                 escapee = {
 16                     ": ",
 17                     \\: \\,
 18                     /: /,
 19                     b: b,
 20                     f: \f,
 21                     n: \n,
 22                     r: \r,
 23                     t: \t
 24                 },
 25                 text,
 26                 // 抛出异常
 27                 error = function (m) {
 28                     throw {
 29                         name: SyntaxError,
 30                         message: m,
 31                         at: at,
 32                         text: text
 33                     }
 34                 },
 35                 // 获取下一个字符
 36                 next = function (c) {
 37                     if (c && c !== ch) {
 38                         error(`Expected ${c} instead of ${ch}`);
 39                     }
 40                     ch = text.charAt(at);
 41                     at += 1;
 42                     return ch;
 43                 },
 44                 // 解析一个数字值
 45                 number = function () {
 46                     var number, string = ‘‘;
 47                     // 负号
 48                     if (ch === -) {
 49                         string = -,
 50                             next(-)
 51                     }
 52                     // 整数
 53                     while (ch >= 0 && ch <= 9) {
 54                         string += ch;
 55                         next();
 56                     }
 57                     // 小数
 58                     if (ch === .) {
 59                         string += .;
 60                         while (next() && ch >= 0 && ch <= 9) {
 61                             string += ch;
 62                         }
 63                     }
 64                     // 指数
 65                     if (ch === e || ch === E) {
 66                         string += ch;
 67                         next();
 68                         if (ch === - || ch === +) {
 69                             string += ch;
 70                             next();
 71                         }
 72                         while (ch >= 0 && ch <= 9) {
 73                             string += ch;
 74                             next();
 75                         }
 76                     }
 77                     number = +string;
 78                     if (isNaN(number)) {
 79                         error(Bad number)
 80                     } else {
 81                         return number;
 82                     }
 83                 },
 84                 // 解析一个字符串值
 85                 string = function () {
 86                     var hex,
 87                         i,
 88                         string = ‘‘,
 89                         uffff;
 90                     // 字符串必须以双引号开始
 91                     if (ch === ") {
 92                         while (next()) {
 93                             if (ch === ") {
 94                                 next();
 95                                 return string;
 96                             } else if (ch === \\) {
 97                                 next();
 98                                 // unicode码
 99                                 if (ch === u) {
100                                     uffff = 0;
101                                     for (i = 0; i < 4; i++) {
102                                         hex = parseInt(next(), 16);
103                                         if (!isFinite(hex)) {
104                                             break;
105                                         }
106                                         ufff = ufff * 16 + hex;
107                                     }
108                                     string += String.fromCharCode(ufff)
109                                 }
110                                 else if (typeof escapee[ch] === string) { // 转义字符
111                                     string += escapee[ch]
112                                 } else {
113                                     break;
114                                 }
115                             } else {
116                                 string += ch;
117                             }
118                         }
119                     }
120                     error(Bac string);
121                 },
122                 // 跳过空白
123                 white = function () {
124                     while (ch && ch <=  ) {
125                         next();
126                     }
127                 },
128                 // 解析 true、false、null
129                 word = function () {
130                     switch (ch) {
131                         case t:
132                             next(t);
133                             next(r);
134                             next(u);
135                             next(e);
136                             return true;
137                         case f:
138                             next(f);
139                             next(a);
140                             next(l);
141                             next(s);
142                             next(e);
143                             return true;
144                         case n:
145                             next(n);
146                             next(u);
147                             next(l);
148                             next(l);
149                             return true;
150                     }
151                     error(`Unexpected ${ch}`)
152                 },
153                 // 解析一个数组值
154                 array = function () {
155                     var array = [];
156                     if (ch === [) {
157                         next([);
158                         white();
159                         if (ch === ]) {
160                             next(]);
161                             return array;
162                         }
163                         while (ch) {
164                             array.push(value());
165                             white();
166                             if (ch === ]) {
167                                 next(]);
168                                 return array;
169                             }
170                             next(,);
171                             white();
172                         }
173                     }
174                     error(Bad array);
175                 },
176                 // 解析一个对象值
177                 object = function () {
178                     var key, object = {};
179                     if (ch === {) {
180                         next({);
181                         white();
182                         if (ch === }) {
183                             next(});
184                             return object;
185                         }
186                         while (ch) {
187                             key = string();
188                             white();
189                             next(:);
190                             object[key] = value();
191                             white();
192                             if (ch === }) {
193                                 next(});
194                                 return object;
195                             }
196                             next(,);
197                             white();
198                         }
199                     }
200                     error(Bad object);
201                 },
202                 // 解析一个JSON值。它可以是对象、数组、字符串、数字、一个词。
203                 value = function () {
204                     white();
205                     switch (ch) {
206                         case {:
207                             return object();
208                         case [:
209                             return array();
210                         case ":
211                             return string();
212                         case -:
213                             return number;
214                         default:
215                             return ch >= 0 && ch <= 9 ? number() : word();
216                     }
217                 };
218             // 返回json_parse函数
219             return function (source, reviver) {
220                 var result;
221                 text = source;
222                 at = 0;
223                 ch =  ;
224                 result = value();
225                 white();
226                 if (ch) { // 多余的非空白字符
227                     error(Syntax error);
228                 }
229                 return typeof reviver === function ? function walk(holder, key) {
230                     var k, v, value = holder[key];
231                     if (value && typeof value === object) {
232                         // 递归处理对象的属性
233                         for (k in value) {
234                             if (Object.hasOwnProperty.call(value, k)) {
235                                 v = walk(value, k);
236                                 if (v !== undefined) {
237                                     value[k] = v;
238                                 } else {
239                                     delete value[k]
240                                 }
241                             }
242                         }
243                     }
244                     // 处理对象
245                     return reviver.call(holder, key, value);
246                 }({ ‘‘: result }, ‘‘) : result;
247             }
248         }();
249         // \n是一个字符,\\n是两个字符
250         const str = {"name":"饮料","price":2.5,"cool":true,"description":["雪碧","可乐"],"escapseSlash":"\\/","escapeN":"\\n"};
251         console.log(json_parse(str, (key, val) => val))
252     </script>
253 </body>
254 
255 </html>

 

运行结果

 

技术图片

 

一个JSON解析器

标签:com   throw   als   syntax   number   hold   双引号   class   UNC   

原文地址:https://www.cnblogs.com/sea-breeze/p/11747206.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!