js语法检查器

将以下代码拷贝到新的HTML文件中打开即可看到效果!

   1 <!DOCTYPE html>
   2 <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
   3 <head>
   4 <meta charset="utf-8" />
   5 <title>JS语法检查器</title>
   6 <style>
   7 .js-color-reservedword {
   8 color: #0823fc;
   9 }
  10 .js-color-identifier {
  11 color: #ff8013;
  12 }
  13 .js-color-exception {
  14 text-decoration: underline;
  15 color: red;
  16 }
  17 .js-color-numericliteral {
  18 color: #6df407;
  19 }
  20 .js-color-stringliteral {
  21 color: #fc9090;
  22 }
  23 .js-color-comment {
  24 color: green;
  25 }
  26 .js-color-functionname {
  27 color: #f8f408;
  28 }
  29 .js-color-punctuator {
  30 color: #e804fa;
  31 }
  32 .js-color-regularexpressionliteral {
  33 color: #73b2ee;
  34 }
  35 .js-color-linecount {
  36 color: pink;
  37 }
  38 .js-code-line-border {
  39 border: 1px solid #cbeeb0;
  40 }
  41 .code-text, .code-div {
  42 width: 600px;
  43 height: 600px;
  44 }
  45 div, span {
  46 margin: 0px;
  47 padding: 0px;
  48 }
  49 pre{
  50 margin: 0;
  51 padding: 0;
  52 display: block;
  53 }
  54 .js-code-edit, textarea {
  55 font-size: 15px;
  56 color: black;
  57 background-color: white;
  58 width: 49%;
  59 height: 600px;
  60 float: left;
  61 border: none;
  62 outline: 1px solid black;
  63 overflow: auto;
  64 margin-left: 0.8%;
  65 }
  66 button {
  67 width: 240px;
  68 height: 50px;
  69 margin-top: 20px;
  70 }
  71 </style>
  72 </head>
  73 <body>
  74 <textarea spellcheck="false">
  75 function paintAST(ast){
  76 var result = "<pre>" + _paintAST(ast) + "</pre>";
  77 return result.replace(/<pre><\/pre>/, '<pre><br></pre>');
  78 function _paintAST(ast){
  79 var str = '';
  80 for(var name in ast){
  81 if(_typeof(ast[name], 'Object') && ast[name].value){
  82 if(ast[name].type == 'LineTerminator'){ str += ast[name].value.replace(/\s/g, '</pre><pre>'); }
  83 else{
  84 var className = 'js-color-' + ast[name].type.toLowerCase(),
  85 value = ast[name].value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
  86 str += '<span class="' + className +'" ' + (ast[name].msg? 'title="' + ast[name].msg + '"': '') +'>' + value + '</span>';
  87 }
  88 }
  89 else if(_typeof(ast[name], 'Array') || _typeof(ast[name], 'Object')){ str += _paintAST(ast[name]); }
  90 }
  91 return str;
  92 }
  93 function _typeof(obj, type){
  94 return Object.prototype.toString.call(obj).indexOf(type) > -1;
  95 }
  96 }
  97 </textarea>
  98 <div class="js-code-edit" spellcheck="false"></div>
  99 <button>Test</button>
 100 <script>
 101 var btn = document.querySelector('button');
 102 document.querySelector('.js-code-edit').innerHTML = JsCodeEdit(document.querySelector('textarea').value);
 103 btn.onclick = function (e) {
 104 //var sTime = Date.now();
 105 document.querySelector('.js-code-edit').innerHTML = JsCodeEdit(document.querySelector('textarea').value);
 106 //alert((Date.now() - sTime));
 107 }
 108 function JsCodeEdit(string) {
 109 var ast = parserJSCode(string);
 110 return paintAST(ast);//将表达式树转换成HTML
 111 return printAST(ast);//返回表达式树
 112 }
 113 function printAST(ast) {
 114 return JSON.stringify(ast);
 115 }
 116 function paintAST(ast){
 117 var result = "<pre>" + _paintAST(ast) + "</pre>";
 118 return result.replace(/<pre><\/pre>/, '<pre><br></pre>');
 119 function _paintAST(ast){
 120 var str = '';
 121 for(var name in ast){
 122 if(_typeof(ast[name], 'Object') && ast[name].value){
 123 if(ast[name].type == 'LineTerminator'){ str += ast[name].value.replace(/\s/g, '</pre><pre>'); }
 124 else{
 125 var className = 'js-color-' + ast[name].type.toLowerCase(),
 126 value = ast[name].value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
 127 str += '<span class="' + className +'" ' + (ast[name].msg? 'title="' + ast[name].msg + '"': '') +'>' + value + '</span>';
 128 }
 129 }
 130 else if(_typeof(ast[name], 'Array') || _typeof(ast[name], 'Object')){ str += _paintAST(ast[name]); }
 131 }
 132 return str;
 133 }
 134 function _typeof(obj, type){
 135 return Object.prototype.toString.call(obj).indexOf(type) > -1;
 136 }
 137 }
 138 function parserJSCode(string) {
 139 if (!string || typeof string != 'string') { return { AST: { type: 'Program', body: [] } }; }
 140 var globalVariable = { strictModel: false, currInstance: '' };
 141 var AST = { type: 'Program', body: [] }, i = 0;
 142 var PARSER_FINSH = 'Parser js code is finshed!';
 143 var startFun = new Function();
 144 try{ startFun.program(AST.body); 
 145 }
 146 catch(e){
 147 if(e != PARSER_FINSH){ console.error(e); }
 148 }
 149 return AST;
 150 function peek(parent, getReg) {
 151 if(eol()){ throw PARSER_FINSH; }
 152 var haveLineTerminator = false;
 153 do{
 154 var space = getSpace(),
 155 terminator = getLineTerminator(),
 156 comm = comment();
 157 pushItem(parent, space), pushItem(parent, terminator), pushItem(parent, comm);
 158 if(!space && ! terminator && !comm){ break; }
 159 }while(!eol());
 160 if(eol()){ throw PARSER_FINSH; }
 161 var returnObj = identifierName() || stringLiteral() || numericLiteral() || punctuator() ||
 162 (getReg && regularExpressionLiteral()) || divPunctuator() || unknowToken();
 163 returnObj.haveLineTerminator = haveLineTerminator;
 164 return returnObj;
 165 
 166 function stringLiteral() {
 167 var str = { type: '', value: '', msg: '' };
 168 if (/['"']/g.test(string[i])) {
 169 str.type = 'StringLiteral', str.value += string[i];
 170 var ch = string[i];
 171 for (i++; !eol() && string[i] != ch && !isLineTerminator(string[i]) ; i++) {
 172 if (string[i] == '\\') {
 173 str.value += string[i] + (string[++i] ? string[i] : '');
 174 var len = (string[i] == 'u' ? 4 : string[i] == 'x' ? 2 : 0)
 175 for (i++; !eol() && len > 0 && string[i] != ch; len--, i++) {
 176 str.value += string[i];
 177 if (!isHex(string[i])) { str.msg = len == 2 ? 'Invalid Hex const!' : 'Invalid Unicode const!'; }
 178 }
 179 i--;
 180 }
 181 else { str.value += string[i]; }
 182 }
 183 if (string[i] == ch) { str.value += ch; i++; }
 184 else { str.msg = 'add ' + ch + ' to end string!'; }
 185 }
 186 return str.value ? str : '';
 187 }
 188 function identifierName() {
 189 var identifier = { type: '', value: '', msg: '' };
 190 if (!(/[a-zA-Z_$\\]/g.test(string[i]))) { return ''; }
 191 identifier.type = 'IdentifierName', identifier.value += string[i] == '\\' ? '' : string[i];
 192 for (string[i] == '\\' ? i : i++; !eol() && /[a-zA-Z_$\d\\]/g.test(string[i]) ; i++) {
 193 identifier.value += string[i];
 194 if (string[i] == '\\') {
 195 if (string[i + 1] != 'u') { identifier.msg = 'Invalid Unicode!'; continue; }
 196 identifier.value += string[++i];
 197 var count = 0;
 198 for (i++; !eol() && isHex(string[i]) ; count++, i++) { identifier.value += string[i]; }
 199 i--;
 200 identifier.msg = (count < 4 ? 'Invalid Unicode!' : '');
 201 }
 202 }
 203 if (identifier.value && isReservedWord(identifier.value)) { identifier.type = 'Reservedword'; }
 204 else if (identifier.value) { identifier.type = 'Identifier'; }
 205 return identifier.value ? identifier : '';
 206 }
 207 function numericLiteral() {
 208 var numeric = { type: '', value: '', msg: '' };
 209 //if (!(/[.\d+-]/g.test(string[i])) || (string[i] == '.' && !isDigit(string[i + 1]))) { return ''; }
 210 //if(/[+-]/g.test(string[i])){
 211 //if (!(/[.\d]/g.test(string[i + 1])) || (string[i + 1] == '.' && !isDigit(string[i + 2]))) { return ''; }
 212 //numeric.value += string[i++];
 213 //}
 214 if (!(/[.\d]/g.test(string[i])) || (string[i] == '.' && !isDigit(string[i + 1]))) { return ''; }
 215 numeric.type = 'NumericLiteral', numeric.value += string[i];
 216 if (string[i] == '0' && /[xX]/g.test(string[i + 1])) {
 217 var hex = string[++i];
 218 for (i++; !eol() && isHex(string[i]) ; i++) { hex += string[i]; }
 219 if (hex.length > 1) { numeric.value += hex; }
 220 else { i--; }
 221 return numeric.value ? numeric : '';
 222 }
 223 var numericArr = ['', '', '', ''], firstZero = string[i] == '0';
 224 for (i++; !eol() && isDigit(string[i]) ; i++) { numericArr[0] += string[i]; }
 225 if (string[i] == '.') {
 226 numericArr[1] = '.';
 227 numeric.msg = (firstZero && numericArr[0] ? 'Invalid numeric!' : '');
 228 i++;
 229 }
 230 for (; !eol() && isDigit(string[i]) ; i++) { numericArr[2] += string[i]; }
 231 if (/[eE]/g.test(string[i])) {
 232 if (/[^\d+-]/g.test(string[i + 1])) {
 233 numeric.value += numericArr.join('');
 234 return numeric.value ? numeric : '';
 235 }
 236 else if (/[+-]/g.test(string[i + 1]) && !isDigit(string[i + 2])) {
 237 numeric.value += numericArr.join('');
 238 return numeric.value ? numeric : '';
 239 }
 240 numericArr[3] += string[i] + string[++i];
 241 for (i++; !eol() && isDigit(string[i]) ; i++) { numericArr[3] += string[i]; }
 242 }
 243 numeric.value += numericArr.join('');
 244 return numeric.value ? numeric : '';
 245 }
 246 function punctuator() {
 247 var punc = { type: '', value: '', msg: '' };
 248 if (/[\[\]{}().,;:\?~]/g.test(string[i])) { return { type: 'Punctuator', value: string[i++], msg: '' } }
 249 var sI = i, str = '';
 250 str = string[i] + string[i + 1] + string[i + 2] + string[i + 3];
 251 if (str == '>>>=') { punc.value = str; }
 252 else {
 253 str = string[i] + string[i + 1] + string[i + 2];
 254 if (['===', '!==', '>>>', '<<=', '>>='].indexOf(str) > -1) { punc.value = str; }
 255 else {
 256 str = string[i] + string[i + 1];
 257 if (['<=', '>=', '==', '!=', '++', '--', '>>', '<<', '&&', '||', '+=', '-=', '*=', '%=', '&=', '|=', '^='].indexOf(str) > -1) { punc.value = str; }
 258 else {
 259 str = string[i];
 260 if (['=', '+', '-', '*', '%', '&', '|', '^', '!', '>', '<'].indexOf(str) > -1) { punc.value = str; }
 261 else { str = ''; }
 262 }
 263 }
 264 }
 265 i += str.length;
 266 if (punc.value) { punc.type = 'Punctuator'; }
 267 return punc.value ? punc : '';
 268 }
 269 function divPunctuator() {
 270 if (string[i] == '/') {
 271 if (string[++i] == '=') { i++; return { type: 'Punctuator', value: '/=', msg: '' }; }
 272 return { type: 'Punctuator', value: '/', msg: '' };
 273 }
 274 return false;
 275 }
 276 function regularExpressionLiteral() {
 277 if (string[i] != '/' || /[*\/]/.test(string[i + 1]) || isLineTerminator(string[i + 1])) { return ''; }
 278 return getRegExp(string[i]);
 279 function getRegExp(ch) {
 280 var regExp = { type: 'RegularExpressionLiteral', value: string[i++], msg: '' };
 281 while (!eol() && string[i] != '/' && string[i] != ch && !isLineTerminator(string[i])) {
 282 if (string[i] == '\\') {
 283 regExp.value += string[i++];
 284 if (isLineTerminator(string[i])) { regExp.msg = 'Error RegularExpressionLiteral'; break; }
 285 regExp.value += string[i++];
 286 }
 287 else if (/[\[\(]/g.test(string[i])) {
 288 var ch = string[i] == '[' ? ']' : ')';
 289 var r = getRegExp(ch);
 290 ch = '/';
 291 regExp.value += r.value;
 292 regExp.msg = r.msg;
 293 if (r.end) { return regExp; }
 294 }
 295 else { regExp.value += string[i++]; }
 296 }
 297 if ((ch == ']' && string[i] == ch) || (ch == ')' && string[i] == ch)) { regExp.value += string[i++] }
 298 else if (string[i] == '/') {
 299 regExp.value += string[i++]
 300 while (!eol() && /[a-zA-Z\d$_]/g.test(string[i])) {
 301 regExp.value += string[i]
 302 if (!(/[gim]/g.test(string[i++]))) { regExp.msg = 'Invaild Character'; }
 303 }
 304 regExp.end = true;
 305 }
 306 else { regExp.msg = 'Error RegularExpressionLiteral'; regExp.end = true; }
 307 return regExp;
 308 }
 309 }
 310 function comment() {
 311 var comment = { type: 'Comment', value: '', msg: '' };
 312 if (string[i] == '/' && string[i + 1] == '/') {
 313 comment.value += '//';// comment.type = 'SingleLineComment';
 314 for (i += 2; !eol() && !isLineTerminator(string[i]) ; i++) { comment.value += string[i]; }
 315 }
 316 else if (string[i] == '/' && string[i + 1] == '*') {
 317 comment.value += '/*';// comment.type = 'MuliteLineComment';
 318 for (i += 2; !eol() && (string[i] != '*' || string[i + 1] != '/') ; i++) { comment.value += string[i]; }
 319 comment.value += eol() ? '' : '*/';
 320 i += 2;
 321 }
 322 return comment.value ? comment : '';
 323 }
 324 function unknowToken(){
 325 return { type: 'UnknowToken', value: string[i++], msg: 'Exception UnknowToken!' };
 326 }
 327 function getSpace(){
 328 var space = { type: 'Space', value: '', msg: '' };
 329 while(!eol() && isSpace(string[i])){
 330 space.value += string[i++];
 331 }
 332 return space.value? space: '';
 333 }
 334 function getLineTerminator(){
 335 var terminator = { type: 'LineTerminator', value: '', msg: '' };
 336 while(!eol() && isLineTerminator(string[i])){
 337 haveLineTerminator = true;
 338 terminator.value += string[i++];
 339 }
 340 return terminator.value ? terminator: '';
 341 }
 342 }
 343 function Expression(parent, p) {
 344 this.expression = expression;
 345 this.assignmentExpression = assignmentExpression;
 346 this.leftHandSideExpression = leftHandSideExpression;
 347 function primaryExpression(parent, p) {
 348 if (p && equal(p.value, '/')) { i--; p = null; }
 349 p = p ? p : peek(parent, true);
 350 var op = isItemInArray(['NumericLiteral', 'StringLiteral', 'Identifier', 'RegularExpressionLiteral'], p.type) ? p.type : p.value;
 351 switch (op) {
 352 case 'this': pushItem(parent, p); break;
 353 case 'true':
 354 case 'false': pushItem(parent, p); break;
 355 case 'null': pushItem(parent, p); break;
 356 case 'Identifier': pushItem(parent, p); break;
 357 case 'StringLiteral':
 358 case 'RegularExpressionLiteral':
 359 case 'NumericLiteral': pushItem(parent, p); break;
 360 case '[': return arrayLiteral(parent, p);
 361 case '{': return objectLiteral(parent, p);
 362 case '(': return argument(parent, p, true);
 363 default: return p;//return exception
 364 }
 365 }
 366 function arrayLiteral(parent, p) {
 367 var arrayLiteral = { type: 'ArrayLiteral', items: [] };
 368 parent.push(arrayLiteral), parent = arrayLiteral.items;
 369 pushItem(parent, p);
 370 do {
 371 p = peek(parent);
 372 if (equal(p.value, ',')) { p = pushItem(parent, p); }
 373 else if (equal(p.value, ']')) { return pushItem(parent, p); }
 374 else {
 375 p = assignmentExpression(parent, p);
 376 if(p){
 377 if(equal(p.value, ']')){ return pushItem(parent, p); }
 378 else if (equal(p.value, ',')) { p = pushItem(parent, p); }
 379 else{ p = pushItem(parent, p, 'Invalid Character!'); }
 380 }
 381 }
 382 }
 383 while (true);
 384 }
 385 //function elementList(){ }
 386 function objectLiteral(parent, p) {
 387 var obj = { type: 'ObjectLiteral', child: [] };
 388 parent.push(obj), parent = obj.child;
 389 p = pushItem(parent, p) || peek(parent);
 390 if(equal(p.value, '}')){ return pushItem(parent, p); }
 391 else{
 392 do{
 393 p = propertyAssignment(parent, p) || peek(parent);
 394 if(equal(p.value, ',')){
 395 p = pushItem(parent, p) || peek(parent);
 396 if(equal(p.value, '}')){ return pushItem(parent, p); }
 397 }
 398 else if(equal(p.value, '}')){ return pushItem(parent, p); }
 399 else{ p = pushItem(parent, p, 'Excepted }'); }
 400 }while(true);
 401 }
 402 }
 403 //function propertyNameAndValueList(parent, p) { }
 404 function propertyAssignment(parent, p) {
 405 var propertyName = ['Identifier', 'Reservedword', 'StringLiteral', 'NumericLiteral'];
 406 p = p? p: peek(parent);
 407 if(propertyName.indexOf(p.type) == -1){ p.msg = p.msg || 'Invalid Proerty Name!'; }
 408 if(equal(p.value, 'get') || equal(p.value, 'set')){ return _GetAndSet(p.value, p); }
 409 else{
 410 p = pushItem(parent, p) || peek(parent);
 411 if(!equal(p.value, ':')){ p.msg = p.msg || 'Excepted :'; }
 412 else{ p = pushItem(parent, p); }
 413 return assignmentExpression(parent, p);
 414 }
 415 function _GetAndSet(functionName, p){
 416 p = pushItem(parent, p) || peek(parent);
 417 if(equal(p.value, ':')){
 418 p = pushItem(parent, p);
 419 return assignmentExpression(parent, p);
 420 }
 421 else if(propertyName.indexOf(p.type) == -1){ p.msg = p.msg || 'Invalid' + functionName + 'property name!'; }
 422 else { p = pushItem(parent, p); }
 423 p = p? p: peek(parent);
 424 if(!equal(p.value, '(')){ p.msg = p.msg || 'Excepted ('; }
 425 else{ p = pushItem(parent, p); }
 426 p = p? p: peek(parent);
 427 if(equal(functionName, 'set')){
 428 if(!equal(p.type, 'Identifier')){ p.msg = p.msg || 'Set property must one parameter!'; }
 429 else{ p = pushItem(parent, p); }
 430 }
 431 p = p? p: peek(parent);
 432 if(!equal(p.value, ')')){ p.msg = p.msg || 'Excepted )'; }
 433 else{ p = pushItem(parent, p); }
 434 p = p? p: peek(parent);
 435 if(!equal(p.value, '{')){ p.msg = p.msg || 'Excepted {'; }
 436 else{ p = pushItem(parent, p); }
 437 p = (new Function()).functionBody(parent, p) || peek(parent);
 438 if(!equal(p.value, '}')){ p.msg = p.msg || 'Excepted }'; }
 439 else{ p = pushItem(parent, p); }
 440 return p;
 441 }
 442 }
 443 //function propertyName(parent, p) { }
 444 function memberExpression(parent, p, isNewExpressionCall) {
 445 p = primaryExpression(parent, p);
 446 if(p){
 447 if(equal(p.value, 'function')){ p = (new Function()).functionExpression(parent, p); }
 448 else if(equal(p.value, 'new')){
 449 p = pushItem(parent, p);
 450 p = memberExpression(parent, p);
 451 return argument(parent, p);
 452 }
 453 else{
 454 p.msg = p.msg || 'Excepted primary expression!';
 455 return p;
 456 }
 457 }
 458 else{ p = peek(parent); }
 459 return memberExtendExpression(parent, p);
 460 }
 461 function newExpression(parent, p) {
 462 while(equal(p.value, 'new')){
 463 p = pushItem(parent, p) || peek(parent);
 464 }
 465 return memberExpression(parent, p);
 466 }
 467 function callExpression(parent, p) {
 468 p = argument(parent, p);
 469 return memberExtendExpression(parent, p);
 470 }
 471 function argument(parent, p, primaryCall) {
 472 setFunctionType(parent);
 473 var arg = {type: 'Argumments', child: []};
 474 parent.push(arg), parent = arg.child;
 475 p = p? p: peek(parent);
 476 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 477 else { p.msg = p.msg || 'Excepted ('; }
 478 p = p? p: peek(parent);
 479 if(!equal(p.value, ')')){
 480 p = argumentList(parent, p) || peek(parent);
 481 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 482 else {
 483 p.msg = p.msg || 'Excepted )';
 484 return p;
 485 }
 486 }
 487 else{ p = pushItem(parent, p, primaryCall? 'Excepted expression!': ''); }
 488 }
 489 function memberExtendExpression(parent, p){
 490 p = p? p: peek(parent);
 491 while(['(', '[', '.'].indexOf(p.value) > -1){
 492 if(equal(p.value, '(')){ p = argument(parent, p); }
 493 else if(equal(p.value, '[')){
 494 pushItem(parent, p);
 495 p = expression(parent) || peek(parent);
 496 if(equal(p.value, ']')){ p = pushItem(parent, p); }
 497 else{ p.msg = p.msg || 'Excepted ]'; }
 498 }
 499 else{
 500 p = pushItem(parent, p) || peek(parent);
 501 if(equal(p.type, 'Identifier') || equal(p.type, 'Reservedword')){ p = pushItem(parent, p); }
 502 else{ p.msg = p.msg || 'Excepted IdentifierName!'; }
 503 }
 504 p = p? p: peek(parent);
 505 }
 506 return p;
 507 }
 508 function setFunctionType(parent, part){
 509 var parts = ['Comment', 'WhiteSpace', 'Lineterminate'];
 510 for(var index = parent.length - 1; index > -1 && parts.indexOf(parent[index].type) > -1; index--) ;
 511 if(parent[index] && equal(parent[index].type, 'Identifier')){ parent[index].type = 'FunctionName'; }
 512 }
 513 function argumentList(parent, p) {
 514 do{
 515 p = assignmentExpression(parent, p) || peek(parent);
 516 if(!equal(p.value, ',')){ return p; }
 517 p = pushItem(parent, p);
 518 }while(true);
 519 }
 520 function leftHandSideExpression(parent, p) {
 521 p = p? p: peek(parent);
 522 if(equal(p.value, 'new')){ return newExpression(parent, p); }
 523 p = memberExpression(parent, p) || peek(parent);
 524 if(equal(p.value, '(')){ return callExpression(parent, p); }
 525 return p;
 526 }
 527 function postfixExpression(parent, p) {
 528 p = leftHandSideExpression(parent, p) || peek(parent);
 529 if(['++', '--'].indexOf(p.value) == -1){
 530 var assignmentOperator = ['=', '*=', '/=', '%=', '+=', '-=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
 531 if(assignmentOperator.indexOf(p.value) > -1){
 532 p = pushItem(parent, p);
 533 p = assignmentExpression(parent, p);
 534 }
 535 return p;
 536 }
 537 pushItem(parent, p, p.haveLineTerminator? 'No line terminator here!': '');
 538 }
 539 function unaryExpression(parent, p) {
 540 var unaryOp = ['++', '--', '+', '-', '!', '~', 'typeof', 'delete', 'void'];
 541 p = p ? p : peek(parent);
 542 if (unaryOp.indexOf(p.value) > -1) {
 543 p = pushItem(parent, p);
 544 return unaryExpression(parent);
 545 }
 546 else { return postfixExpression(parent, p); }
 547 }
 548 /*function multiplicativeExpression(parent, p){}
 549 function additiveExpression(parent, p){}
 550 function shiftExpression(parent, p){}
 551 function relationalExpression(parent, p){}
 552 function RelationalExpressionNoIn(parent, p){}
 553 function equalityExpression(parent, p){}
 554 function equalityExpressionNoIn(parent, p){}
 555 function bitwiseANDExpression(parent, p){}
 556 function bitwiseANDExpressionNoIn(parent, p){}
 557 function bitwiseXORExpression(parent, p){}
 558 function bitwiseXORExpressionNoIn(parent, p){}
 559 function bitwiseORExpression(parent, p){}
 560 function bitwiseORExpressionNoIn(parent, p){}
 561 function logicalANDExpression(parent, p){}
 562 function logicalANDExpressionNoIn(parent, p){}
 563 function logicalORExpression(parent, p) {}
 564 function logicalORExpressionNoIn(parent, p) {}
 565 function logicalExpression(parent, p) {}
 566 function logicalORExpressionNoIn(parent, p){}*/
 567 function operationExpression(parent, p, noIn) {
 568 var logicalOp = ['||', '&&', '|', '^', '&', '==', '!=', '===', '!==', '<', '>', '<=', '>=', 'instanceof', '<<', '>>', '>>>', '+', '-', '*', '/', '%'];
 569 if(!noIn){ logicalOp.push('in'); }
 570 do{
 571 p = unaryExpression(parent, p) || peek(parent, p);
 572 if(logicalOp.indexOf(p.value) == -1){ return p; }
 573 p = pushItem(parent, p);
 574 }while(true);
 575 }
 576 function conditionalExpression(parent, p, noIn) {
 577 p = operationExpression(parent, p, noIn) || peek(parent, p);
 578 if(!equal(p.value, '?')){ return p; }
 579 p = pushItem(parent, p);
 580 p = assignmentExpression(parent, p, noIn) || peek(parent, p);
 581 if(equal(p.value, ':')){ p = pushItem(parent, p); }
 582 else { p.msg = p.msg || 'Excepted :'; }
 583 return assignmentExpression(parent, p, noIn);
 584 }
 585 //function conditionalExpressionNoIn(parent, p){}
 586 function assignmentExpression(parent, p, noIn) {
 587 return conditionalExpression(parent, p, noIn);
 588 }
 589 //function assignmentExpressionNoIn(parent, p){}
 590 function expression(parent, p, noIn) {
 591 var exp = { type: 'Expression', expressions: [] };
 592 parent.push(exp), parent = exp.expressions;
 593 do{
 594 p = assignmentExpression(parent, p, noIn) || peek(parent);
 595 if(equal(p.value, ',')){ p = pushItem(parent, p); }
 596 else { return p; }
 597 }while(true);
 598 }
 599 //function expressionNoIn(parent, p){}
 600 }
 601 function Statement(parent, p) {
 602 var _Exp = new Expression();
 603 this.statement = statement;
 604 this.isStatementStart = isStatementStart;
 605 
 606 function statement(parent, p) {
 607 p = p ? p : peek(parent);
 608 switch (p.value) {
 609 case '{': return block(parent, p);
 610 case 'var': return variableStatement(parent, p);
 611 case ';': return emptyStatement(parent, p);
 612 case 'if': return ifStatement(parent, p);
 613 case 'do':
 614 case 'while':
 615 case 'for': return iterationStatement(parent, p);
 616 case 'continue': return continueStatement(parent, p);
 617 case 'break': return breakStatement(parent, p);
 618 case 'return': return returnStatement(parent, p);
 619 case 'with': return withStatement(parent, p);
 620 case 'switch': return switchStatement(parent, p);
 621 case 'throw': return throwStatement(parent, p);
 622 case 'try': return tryStatement(parent, p);
 623 case 'debugger': return debuggerStatement(parent, p);
 624 //case 'label': return labelStatement(parent, p);
 625 case 'function': return pushItem(parent, p, 'Invalid statement start!');
 626 default:
 627 if(equal(p.type, 'Identifier')){
 628 var currIndex = i, test;
 629 try{
 630 test = peek([]);
 631 }catch(e){
 632 test = {value: 'not :'}
 633 }
 634 i = currIndex;
 635 if(equal(test.value, ':')){ return labelStatement(parent, p); }
 636 }
 637 if(!isExpressionStart(p)){ return p; }
 638 return expressionStatement(parent, p);
 639 }
 640 }
 641 function block(parent, p) {
 642 var b = { type: 'BlockStatement', statement: [] };
 643 parent.push(b), parent = b.statement;
 644 p = p ? p : peek(parent);
 645 if(equal(p.value, '{')){ p = pushItem(parent, p); }
 646 else { p.msg = p.msg || 'Excepted {'; }
 647 p = p ? p : peek(parent);
 648 if(equal(p.value, '}')){ return pushItem(parent, p); }
 649 p = statementList(parent, p);
 650 if(equal(p.value, '}')){ return pushItem(parent, p); }
 651 else { p.msg = p.msg || 'Excepted }'; }
 652 return p;
 653 }
 654 function statementList(parent, p) {
 655 do{
 656 p = statement(parent, p);
 657 if(p && !isStatementStart(p)){ return p; }
 658 }while(true);
 659 }
 660 function variableStatement(parent, p) {
 661 var varDeclar = { type: 'VariableDeclaration', declarList: [] };
 662 p = p ? p : peek(parent);
 663 parent.push(varDeclar), parent = varDeclar.declarList;
 664 p = pushItem(parent, p) || peek(parent);
 665 p = variableDeclarationList(parent, p) || peek(parent);
 666 if(!equal(p.value, ';')){
 667 if(!p.haveLineTerminator && !equal(p.value, '}')){ p.msg = p.msg || 'Excepted ;'; }
 668 }
 669 else{ p = pushItem(parent, p); }
 670 return p;
 671 }
 672 function variableDeclarationList(parent, p, noIn) {
 673 p = p ? p : peek(parent);
 674 do {
 675 p = variableDeclaration(parent, p, noIn) || peek(parent);
 676 if(!equal(p.value, ',')){
 677 if(equal(p.value, ';') || p.haveLineTerminator){ return p; }
 678 else if(!equal(p.type, 'Identifier')){ p = pushItem(parent, p, 'Excepted ,'); }
 679 else { p.msg = p.msg || 'Excepted ,'; }
 680 }
 681 else { p = pushItem(parent, p); }
 682 } while (true);
 683 }
 684 function variableDeclaration(parent, p, noIn) {
 685 p = p ? p : peek(parent);
 686 if (!equal(p.type, 'Identifier')) {
 687 if(!p.msg){
 688 if(equal(p.type, 'Reservedword')){ p.msg = 'Identifier can not be reservedword!'; }
 689 else{ p.msg = 'Excepted identifier!' }
 690 }
 691 }
 692 else { p = pushItem(parent, p); }
 693 p = p ? p : peek(parent);
 694 if(!equal(p.value, '=')){ return p; }
 695 p = pushItem(parent, p);
 696 return _Exp.assignmentExpression(parent, p, noIn);
 697 }
 698 function emptyStatement(parent, p) {
 699 var emptyState = { type: p.type, value: p.value };
 700 parent.push(emptyState);
 701 }
 702 function expressionStatement(parent, p) {
 703 p = _Exp.expression(parent, p) || peek(parent);
 704 if(equal(p.value, ';')){ return pushItem(parent, p); }
 705 else if(!equal(p.value, '}') && !p.haveLineTerminator) { p.msg = p.msg || 'Excepted ;'; }
 706 return p;
 707 }
 708 function ifStatement(parent, p) {
 709 var ifState = { type: 'IfStatement', statement: [] };
 710 parent.push(ifState), parent = ifState.statement;
 711 p = pushItem(parent, p) || peek(parent);
 712 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 713 else{ p.msg = p.msg || 'Excepted ('; }
 714 p = _Exp.expression(parent, p) || peek(parent);
 715 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 716 else { p.msg = p.msg || 'Excepted )'; }
 717 p = statement(parent, p) || peek(parent);
 718 if(!equal(p.value, 'else')){ return p; }
 719 p = pushItem(parent, p);
 720 return statement(parent);
 721 }
 722 function iterationStatement(parent, p) {
 723 var loop = { type: 'IterationStatement', statement: [] };
 724 parent.push(loop), parent = loop.statement;
 725 pushItem(parent, p);
 726 p = p? p: peek(parent);
 727 if (equal(p.value, 'do')) { return doStatement(parent); }
 728 else if (equal(p.value, 'while')) { return whileStatement(parent); }
 729 else if (equal(p.value, 'for')) { return forStatement(parent); }
 730 else { p.msg = p.msg || 'Excepted do or while or for!'; }
 731 return p;
 732 
 733 function doStatement(parent, p) {
 734 p = statement(parent, p) || peek(parent);
 735 if(!equal(p.value, 'while')){ p.msg = p.msg || 'Excepted While!'; }
 736 else { p = pushItem(parent, p); }
 737 return whileStatement(parent, p);
 738 }
 739 function whileStatement(parent, p) {
 740 p = p? p: peek(parent);
 741 if(!equal(p.value, '(')){ p.msg = p.msg || 'Excepted ('; }
 742 else{ p = pushItem(parent, p); }
 743 p = _Exp.expression(parent, p) || peek(parent);
 744 if(!equal(p.value, ')')){ p.msg = p.msg || 'Excepted )'; }
 745 else{ p = pushItem(parent, p); }
 746 return statement(parent, p);
 747 }
 748 function forStatement(parent, p) {
 749 p = p? p: peek(parent);
 750 if(!equal(p.value, '(')){ p.msg = p.msg || 'Excepted ('; }
 751 else{ p = pushItem(parent, p); }
 752 p = p? p: peek(parent);
 753 if(equal(p.value, 'var')){
 754 p = pushItem(parent, p);
 755 p = variableDeclaration(parent, p, true) || peek(parent);
 756 if(equal(p.value, ',') || equal(p.value, ';')){
 757 while(equal(p.value, ',')){
 758 p = pushItem(parent, p);
 759 p = variableDeclaration(parent, p, true) || peek(parent);
 760 }
 761 }
 762 }
 763 else if(!equal(p.value, ';')){
 764 var currIndex = i, test;
 765 try{
 766 test = _Exp.leftHandSideExpression([], p) || peek([]);
 767 }catch(e){
 768 test = { value: 'not in' };
 769 }
 770 i = currIndex;
 771 if(equal(test.value, 'in')){ p = _Exp.leftHandSideExpression(parent, p) || peek(parent); }
 772 else { p = _Exp.expression(parent, p, true) || peek(parent); }
 773 }
 774 if(equal(p.value, 'in')){
 775 pushItem(parent, p);
 776 p = _Exp.expression(parent);
 777 }
 778 else if(equal(p.value, ';')){
 779 p = pushItem(parent, p) || peek(parent);
 780 if(!equal(p.value, ';')){
 781 p = _Exp.expression(parent, p) || peek(parent);
 782 if(equal(p.value, ';')){ p = pushItem(parent, p); }
 783 else { p.msg = p.msg || 'Excepted ;'; }
 784 }
 785 else { p = pushItem(parent, p); }
 786 p = p? p: peek(parent);
 787 if(!equal(p.value, ')')){ p = _Exp.expression(parent, p); }
 788 }
 789 else{ p.msg = p.msg || 'Excepted ;'; }
 790 p = p? p: peek(parent);
 791 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 792 else { p.msg = p.msg || 'Excepted )'; }
 793 return statement(parent, p);
 794 }
 795 }
 796 function continueStatement(parent, p) {
 797 var con = { type: 'ContinueStatement', statement: [] };
 798 parent.push(con), parent = con.statement;
 799 p = pushItem(parent, p) || peek(parent);
 800 if(p.haveLineTerminator){ return p; }
 801 else if(equal(p.type, 'Identifier')){ p = pushItem(parent, p); }
 802 p = p? p: peek(parent);
 803 if(p.haveLineTerminator){ return p; }
 804 else if(equal(p.value, ';')){ p = pushItem(parent, p); }
 805 else if(!equal(p.value, '}')) { p.msg = p.msg || 'Excepted ;'; }
 806 return p;
 807 }
 808 function breakStatement(parent, p) {
 809 var b = { type: 'BreakStatement', statement: [] };
 810 parent.push(b), parent = b.statement;
 811 p = pushItem(parent, p) || peek(parent);
 812 if(p.haveLineTerminator){ return p; }
 813 else if(equal(p.type, 'Identifier')){ p = pushItem(parent, p); }
 814 p = p? p: peek(parent);
 815 if(p.haveLineTerminator){ return p; }
 816 else if(equal(p.value, ';')){ p = pushItem(parent, p); }
 817 else if(!equal(p.value, '}')) { p.msg = p.msg || 'Excepted ;'; }
 818 return p;
 819 }
 820 function returnStatement(parent, p) {
 821 var r = { type: 'ReturnStatement', statement: [] };
 822 parent.push(r), parent = r.statement;
 823 p = pushItem(parent, p) || peek(parent);
 824 if(p.haveLineTerminator){ return p; }
 825 else if(equal(p.value, ';')){ p = pushItem(parent, p); }
 826 else if(!equal(p.value, '}')){
 827 p = _Exp.expression(parent, p) || peek(parent);
 828 if(p.haveLineTerminator){ return p; }
 829 else if(equal(p.value, ';')){ p = pushItem(parent, p); }
 830 else if(!equal(p.value, '}')){ p.msg = p.msg || 'Excepted ;'; }
 831 }
 832 return p;
 833 }
 834 function withStatement(parent, p) {
 835 var w = { type: 'WhithStatement', statement: [] };
 836 parent.push(w), parent = w.statement;
 837 p = pushItem(parent, p) || peek(parent);
 838 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 839 else{ p.msg = p.msg || 'Excepted ('; }
 840 p = _Exp.expression(parent, p) || peek(parent);
 841 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 842 else{ p.msg = p.msg || 'Excepted )'; }
 843 return statement(parent, p);
 844 }
 845 function switchStatement(parent, p) {
 846 var s = { type: 'SwitchStatement', statement: [] };
 847 parent.push(s), parent = s.statement;
 848 p = pushItem(parent, p) || peek(parent);
 849 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 850 else{ p.msg = p.msg || 'Excepted ('; }
 851 p = _Exp.expression(parent, p) || peek(parent);
 852 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 853 else{ p.msg = p.msg || 'Excepted )'; }
 854 return caseBlock(parent, p);
 855 }
 856 function caseBlock(parent, p) {
 857 var c = { type: 'CaseStatement', statement: [] };
 858 globalVariable.currInstance = 'caseBlock';
 859 parent.push(c), parent = c.statement;
 860 p = p? p: peek(parent);
 861 if(equal(p.value, '{')){ p = pushItem(parent, p); }
 862 else{ p.msg = p.msg || 'Excepted {'; }
 863 p = p? p: peek(parent);
 864 if(equal(p.value, '}')){ return pushItem(parent, p); }
 865 var haveDefault = false;
 866 do{
 867 p = p? p: peek(parent);
 868 if(equal(p.value, 'case')){
 869 pushItem(parent, p);
 870 p = _Exp.expression(parent);
 871 }
 872 else if(equal(p.value, 'default')){
 873 if(haveDefault){ p.msg = p.msg || 'Repeat default keyword!'; }
 874 p = pushItem(parent, p);
 875 haveDefault = true;
 876 }
 877 else if(equal(p.value, '}')){ return pushItem(parent, p); }
 878 p = p? p: peek(parent);
 879 if(equal(p.value, ':')){ p = pushItem(parent, p); }
 880 else { p.msg = p.msg || 'Excepted :'; }
 881 p = statementList(parent, p);
 882 }while(true);
 883 }
 884 function labelStatement(parent, p) {
 885 var l = { type: 'LablelStatement', statement: [] };
 886 parent.push(l), parent = l.statement;
 887 p = pushItem(parent, p) || peek(parent);
 888 if(equal(p.value, ':')){ p = pushItem(parent, p); }
 889 else { p.msg = p.msg || 'Excepted :'; }
 890 return statement(parent, p);
 891 }
 892 function throwStatement(parent, p) {
 893 var t = { type: 'ThrowStatement', statement: [] };
 894 parent.push(t), parent = t.statement;
 895 p = pushItem(parent, p) || peek(parent);
 896 if(p.haveLineTerminator){ p.msg = p.msg || 'No lineTerminator here!'; return p; }
 897 p = _Exp.expression(parent, p) || peek(parent);
 898 if(p.haveLineTerminator){ return p; }
 899 else if(equal(p.value, ';')){ return pushItem(parent, p); }
 900 else if(!equal(p.value, '}')){ p.msg = p.msg || 'Excepted ;'; }
 901 return p;
 902 }
 903 function tryStatement(parent, p) {
 904 var t = { type: 'TryStatement', statement: [] }, haveCatch = false;
 905 parent.push(t), parent = t.statement;
 906 pushItem(parent, p);
 907 p = block(parent) || peek(parent);
 908 if(equal(p.value, 'catch')){
 909 haveCatch = true;
 910 p = pushItem(parent, p);
 911 p = catchStatement(parent, p);
 912 }
 913 p = p? p: peek(parent);
 914 if(equal(p.value, 'finally')){
 915 p = pushItem(parent, p);
 916 p = block(parent, p);
 917 }
 918 else if(!haveCatch) { p.msg = p.msg || 'Excepted catch or finally!'; }
 919 return p;
 920 }
 921 function catchStatement(parent, p) {
 922 var c = { type: 'CatchStatement', statement: [] };
 923 parent.push(c), parent = c.statement;
 924 p = pushItem(parent, p) || peek(parent);
 925 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 926 else{ p.msg = p.msg || 'Excepted ('; }
 927 p = p? p: peek(parent);
 928 if(equal(p.type, 'Identifier')){ p = pushItem(parent, p); }
 929 else { p.msg = p.msg || 'Excepted identifier!'; }
 930 p = p? p: peek(parent);
 931 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 932 else{ p.msg = p.msg || 'Excepted )'; }
 933 return block(parent, p);
 934 }
 935 function debuggerStatement(parent, p) {
 936 var d = { type: 'DebuggerStatement', statement: [] };
 937 parent.push(d), parent = d.statement;
 938 p = pushItem(parent, p) || peek(parent);
 939 if(p.haveLineTerminator){ return p; }
 940 else if(equal(p.value, ';')){ return pushItem(parent, p); }
 941 else if(!equal(p.value, '}')){ p.msg = p.msg || 'Excepted ;'; }
 942 return p;
 943 }
 944 function isExpressionStart(p){
 945 var valueArray = ['this', 'null', 'true', 'false', '{', '[', '(', 'new', '++', '--', '+', '-', '!', '~', 'typeof', 'delete', 'void', '/'],
 946 typeArray = ['Identifier', 'StringLiteral', 'StringLiteral', 'RegularExpressionLiteral'];
 947 return typeArray.indexOf(p.type) > -1 || valueArray.indexOf(p.value) > -1;
 948 }
 949 function isStatementStart(p){
 950 var keyValue = ['var', 'return', ';', 'if', 'for', 'do', 'while', 'switch', 'with', 'debugger', 'continue', 'break', 'throw', 'try'];
 951 return isExpressionStart(p) || keyValue.indexOf(p.value) > -1;
 952 }
 953 }
 954 function Function(parent, p) {
 955 this.functionExpression = functionExpression;
 956 this.program = program;
 957 this.functionBody = functionBody;
 958 
 959 function functionDeclaration(parent, p) {
 960 var f = { type: 'FunctionDeclaration', declaration: [] };
 961 parent.push(f), parent = f.declaration;
 962 p = pushItem(parent, p) || peek(parent);
 963 if(equal(p.type, 'Identifier')){
 964 p.type = 'FunctionName';
 965 p = pushItem(parent, p);
 966 }
 967 else{ p.msg = p.msg || 'Excepted function name!' }
 968 p = p? p: peek(parent);
 969 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 970 else{ p.msg = p.msg || 'Excepted (' }
 971 p = p? p: peek(parent);
 972 if(!equal(p.value, ')')){ p = formalParameterList(parent, p) || peek(parent); }
 973 p = p? p: peek(parent);
 974 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 975 else{ p.msg = p.msg || 'Excepted )' }
 976 p = p? p: peek(parent);
 977 if(equal(p.value, '{')){ p = pushItem(parent, p); }
 978 else{ p.msg = p.msg || 'Excepted {' }
 979 p = functionBody(parent, p) || peek(parent);
 980 if(equal(p.value, '}')){ p = pushItem(parent, p); }
 981 else{ p.msg = p.msg || 'Excepted }' }
 982 return p;
 983 }
 984 function functionExpression(parent, p) {
 985 var f = { type: 'FunctionDeclaration', declaration: [] };
 986 parent.push(f), parent = f.declaration;
 987 p = pushItem(parent, p) || peek(parent);
 988 if(equal(p.type, 'Identifier')){
 989 p.type = 'FunctionName';
 990 p = pushItem(parent, p);
 991 }
 992 p = p? p: peek(parent);
 993 if(equal(p.value, '(')){ p = pushItem(parent, p); }
 994 else{ p.msg = p.msg || 'Excepted (' }
 995 p = p? p: peek(parent);
 996 if(!equal(p.value, ')')){ p = formalParameterList(parent, p) || peek(parent); }
 997 p = p? p: peek(parent);
 998 if(equal(p.value, ')')){ p = pushItem(parent, p); }
 999 else{ p.msg = p.msg || 'Excepted )' }
1000 p = p? p: peek(parent);
1001 if(equal(p.value, '{')){ p = pushItem(parent, p); }
1002 else{ p.msg = p.msg || 'Excepted {' }
1003 p = functionBody(parent, p) || peek(parent);
1004 if(equal(p.value, '}')){ p = pushItem(parent, p); }
1005 else{ p.msg = p.msg || 'Excepted }' }
1006 return p;
1007 }
1008 function formalParameterList(parent, p) {
1009 do{
1010 p = p? p: peek(parent);
1011 if(equal(p.type, 'Identifier')){ p = pushItem(parent, p); }
1012 else { p.msg = p.msg || 'Function parameter muste be identifier!'; }
1013 p = p? p: peek(parent);
1014 if(equal(p.value, ',')){ p = pushItem(parent, p); }
1015 else if(equal(p.value, ')')){ return p; }
1016 else { p = pushItem(parent, p, 'Excpted ,'); }
1017 }while(true);
1018 }
1019 function functionBody(parent, p) {
1020 p = p? p: peek(parent);
1021 if(equal(p.value, '}')){ return p; }
1022 var f = { type: 'FunctionBody', body: [] }, strictModel = globalVariable.strictModel;
1023 parent.push(f), parent = f.body;
1024 p = p? p: peek(parent);
1025 if(equal(p.value, '"use strict"') || equal(p.value, "'use strict'")){ globalVariable.strictModel = true; }
1026 p = sourceElements(parent, p);
1027 globalVariable.strictModel = strictModel;
1028 return p;
1029 }
1030 function program(parent){
1031 var p = peek(parent);
1032 if(equal(p.value, '"use strict"') || equal(p.value, "'use strict'")){ globalVariable.strictModel = true; }
1033 do{
1034 p = sourceElements(parent, p);
1035 if(p){ p = pushItem(parent, p, 'Syntax error!'); }
1036 }while(true);
1037 }
1038 function sourceElements(parent, p) {
1039 do{
1040 p = sourceElement(parent, p);
1041 if(p && !isSourceElementStart(p)){ return p; }
1042 }while(true);
1043 }
1044 function sourceElement(parent, p) {
1045 p = p ? p : peek(parent);
1046 if(equal(p.value, 'function')){ return functionDeclaration(parent, p); }
1047 else { return (new Statement()).statement(parent, p); }
1048 }
1049 function isSourceElementStart(p){
1050 if(equal(p.value, 'function')){ return true; }
1051 else{
1052 var state = new Statement();
1053 return state.isStatementStart(p);
1054 }
1055 }
1056 }
1057 function eol(pos) {
1058 i = pos ? pos : i;
1059 return i >= string.length;
1060 }
1061 function isHex(ch) {
1062 return /[0-9a-fA-F]/g.test(ch);
1063 }
1064 function isSpace(ch) {
1065 return ['\u0009', '\u000B', '\u0009C', '\u0020', '\u00A0', '\uFEFF'].indexOf(ch) > -1;
1066 }
1067 function isLineTerminator(ch) {
1068 return ['\u000A', '\u000D', '\u2028', '\u2029'].indexOf(ch) > -1;
1069 }
1070 function isWhiteSpace(ch){
1071 return isSpace(ch) || isLineTerminator(ch);
1072 }
1073 function isItemInArray(array, item) {
1074 return array.indexOf(item) > -1;
1075 }
1076 function isDigit(ch) {
1077 return /\d/g.test(ch);
1078 }
1079 function isReservedWord(word) {
1080 if (!word) { return false; }
1081 var keyWord = ["break", "do", "instanceof", "pof", "case", "else", "new", "var", "catch", "finally", "return", "void", 'continue', "for",
1082 "switch", "while", "debugger", "function", 'this', 'with', 'default', "if", "throw", "delete", "in", "try"],
1083 nullReserved = ['null'],
1084 booleanReserved = ['true', 'false'],
1085 futureReserved = ["class", "enum", "extends", "super", "export", "import"],
1086 strictReserved = ["implements", 'let', "private", "public", "interface", "package", "protected", "static", 'yield'],
1087 reserved = keyWord.concat(nullReserved).concat(futureReserved).concat(booleanReserved),
1088 strictModel = globalVariable.strictModel;
1089 if (strictModel) { reserved = reserved.concat(strictReserved); }
1090 return reserved.indexOf(word) > -1;
1091 }
1092 function equal(e1, e2, deep) {
1093 return deep ? e1 === e2 : e1 == e2;
1094 }
1095 function pushItem(parent, p, msg) {
1096 if (!p || !p.value) { return; }
1097 var o = { type: p.type, value: p.value };
1098 if (p.msg || msg) {
1099 o.type = 'Exception';
1100 o.msg = p.msg || msg;
1101 }
1102 parent.push(o);
1103 }
1104 }
1105 </script>
1106 </body>
1107 </html>

 

posted @ 2017-11-07 17:38  春日野穹  阅读(1133)  评论(0)    收藏  举报