text: sys.load("js/parser.js");
  sys.load("js/ExpressionParser2Tonyu.js");
  sys.load("js/GrammarTonyu.js");
  sys.load("js/XMLBuffer.js");
  sys.load("js/IndentBuffer.js");
  sys.load("js/disp.js");
  sys.load("js/profiler.js");
  
  TT=function () {
  	function profileTbl(parser, name) {
  		var tbl=parser._first.tbl;
  		for (var c in tbl) {
  			tbl[c].profile();//(c+" of "+tbl[name);
  		}
  	}
  	var sp=Parser.StringParser;
  	var SAMENAME="SAMENAME";
  	var DIV=1,REG=2;
      var space=sp.reg(/^(\s*(\/\*([^\/]|[^*]\/|\r|\n)*\*\/)*(\/\/.*\n)*)*/).setName("space");
      function tk(r, name) {
          var pat;
          var fst;
          if (typeof r=="string") {
              pat=sp.str(r);
              if (r.length>0) fst=r.substring(0,1);
              if (!name) name=r;
          } else {
              pat=sp.reg(r);
              if (!name) name=r+"";
          }
          var res=space.and(pat).ret(function(a, b) {
              var res={};
              res.pos=b.pos;
              if (typeof res.pos!="number") throw "no pos for "+name+" "+disp(b);
              res.len=b.len;
              res.text=b.src.str.substring(res.pos, res.pos+res.len);
              if (typeof res.text!="string") throw "no text("+res.text+") for "+name+" "+disp(b);
              res.toString=function (){
                  return this.text;
              };
              return res;
          });
          if (fst) res=res.first(space, fst);
          return res.setName(name);//.profile();
      }
      var parsers={},posts={};
      function dtk2(prev, name, parser, post) {
      	//console.log("2reg="+prev+" name="+name);
      	if (typeof parser=="string") parser=tk(parser);
      	parsers[prev]=or(parsers[prev], parser.ret(function (res) {
      		res.type=name;
      		return res;
      	}).setName(name) );
      }
      function dtk(prev, name, parser, post) {
      	if(name==SAMENAME) name=parser;
      	for (var m=1; m<=prev; m*=2) {
      		//prev=1  -> m=1
      		//prev=2  -> m=1x,2
      		//XXprev=3  -> m=1,2,3
      		if ((prev&m)!=0) dtk2(prev&m, name,parser,post);
      	}
      	posts[name]=post;
      }
      function or(a,b){
      	if (!a) return b;
      	return a.or(b);
      }
  
      var all=Parser.create(function (st) {
      	var mode=REG;
      	var res=[];
      	while (true) {
          	st=parsers[mode].parse(st);
          	if (!st.success) break;
          	var e=st.result[0];
      		mode=posts[e.type];
      		res.push(e);
      	}
      	st=space.parse(st);
      	console.log(st.src.maxPos+"=="+st.src.str.length)
      	st.success=st.src.maxPos==st.src.str.length;
      	st.result[0]=res;
      	return st;
      });
      /*function exprHead(name, parser) {
      	dtk(REG, name, parser, DIV);
      }
      function exprMid(name, parser) {
      	dtk(DIV, name, parser, REG);
      }
      function exprTail(name, parser) {
      	dtk(DIV, name, parser, DIV);
      }*/
      var reserved={"function":true, "var":true , "return":true, "typeof": true, "if":true,
              "for":true,
              "else": true,
              "super": true,
              "while":true,
              "break":true,
              "do":true,
              "switch":true,
              "try": true,
              "catch": true,
              "finally": true,
              "in": true,
              fiber:true,
              "native": true,
              "instanceof":true,
              "new": true,
              "is": true,
              "true": true,
              "false": true,
              "null":true,
              "this":true,
              "undefined": true,
              "usethread": true,
              "constructor": true,
              ifwait:true,
              nowait:true,
              arguments:true,
              "delete": true,
              "extends":true,
              "includes":true
      };
  
  	var num=tk(/^[0-9\.]+/).ret(function (n) {
          n.type="number";
          n.value=parseInt(n.text);
          return n;
      }).first(space,"0123456789");
  	var literal=tk({exec: function (s) {
          var head=s.substring(0,1);
          if (head!=='"' && head!=="'") return false;
          for (var i=1 ;i<s.length ; i++) {
              var c=s.substring(i,i+1);
              if (c===head) {
                  return [s.substring(0,i+1)];
              } else if (c==="\\") {
                  i++;
              }
          }
          return false;
      },toString:function(){return"literal";}
      }).first(space,"\"'");
      var regex=tk({exec: function (s) {
          if (s.substring(0,1)!=='/') return false;
          for (var i=1 ;i<s.length ; i++) {
              var c=s.substring(i,i+1);
              if (c==='/') {
                  return [s.substring(0,i+1)];
              } else if (c==="\\") {
                  i++;
              }
          }
          return false;
      },toString:function(){return"regex";}
      }).first(space,"/");
  
  	dtk(REG|DIV, "number", num,DIV );
  	dtk(REG,  "regex" ,regex,DIV );
  	dtk(REG|DIV,  "literal" ,literal,DIV );
  
  	dtk(REG|DIV,SAMENAME ,"++",DIV );
  	dtk(REG|DIV,SAMENAME ,"--",DIV );
  
  	dtk(REG|DIV,SAMENAME ,"!==",REG );
  	dtk(REG|DIV,SAMENAME ,"===",REG );
  	dtk(REG|DIV,SAMENAME ,"+=",REG );
  	dtk(REG|DIV,SAMENAME ,"-=",REG );
  	dtk(REG|DIV,SAMENAME ,"*=",REG );
  	dtk(REG|DIV,SAMENAME ,"/=",REG );
  	dtk(REG|DIV,SAMENAME ,"%=",REG );
  	dtk(REG|DIV,SAMENAME ,">=",REG );
  	dtk(REG|DIV,SAMENAME ,"<=",REG );
  	dtk(REG|DIV,SAMENAME ,"!=",REG );
  	dtk(REG|DIV,SAMENAME ,"==",REG );
  	dtk(REG|DIV,SAMENAME ,">>",REG );
  	dtk(REG|DIV,SAMENAME ,"<<",REG );
  
  	dtk(REG|DIV,SAMENAME ,"&&",REG );
  	dtk(REG|DIV,SAMENAME ,"||",REG );
  
  
  	dtk(REG|DIV,SAMENAME ,"(",REG );
  	dtk(REG|DIV,SAMENAME ,")",DIV );
  
  
  	dtk(REG|DIV,SAMENAME ,"[",REG );
  	dtk(REG|DIV,SAMENAME ,"]",REG );
  
  	dtk(REG|DIV,SAMENAME ,"{",REG );
  	//dtk(REG|DIV,SAMENAME ,"}",REG );  // if () { .. }  /[a-z]/.exec()
  	dtk(REG|DIV,SAMENAME ,"}",DIV ); //in tonyu:  a{x:5}/3
  
  	dtk(REG|DIV,SAMENAME ,">",REG );
  	dtk(REG|DIV,SAMENAME ,"<",REG );
  	dtk(REG|DIV,SAMENAME ,"+",REG );
  	dtk(REG|DIV,SAMENAME ,"-",REG );
  	dtk(REG|DIV, SAMENAME ,".",REG );
  	dtk(REG|DIV,SAMENAME ,"?",REG );
  
  	dtk(REG|DIV, SAMENAME ,"=",REG );
  	dtk(REG|DIV, SAMENAME ,"*",REG );
  	dtk(REG|DIV, SAMENAME ,"%",REG );
  	dtk(DIV, SAMENAME ,"/",REG );
  
  	dtk(DIV|REG, SAMENAME ,"^",REG );
  	dtk(DIV|REG, SAMENAME ,"~",REG );
  
  	dtk(DIV|REG, SAMENAME ,"\\",REG );
  	dtk(DIV|REG, SAMENAME ,":",REG );
  	dtk(DIV|REG, SAMENAME ,";",REG );
  	dtk(DIV|REG, SAMENAME ,",",REG );
  	dtk(REG|DIV,SAMENAME ,"!",REG );
  	dtk(REG|DIV,SAMENAME ,"&",REG );
  	dtk(REG|DIV,SAMENAME ,"|",REG );
  
  	dtk(REG|DIV, "symbol", tk(/^[a-zA-Z_$][a-zA-Z0-9_$]*/,"ident_reg").except(function (s) {
          return reserved.hasOwnProperty(s.text);
      }).first(space/*, "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$"*/), DIV);
      dtk(REG|DIV, "tk_constructor", "constructor", REG);
      var resvs=[];
      for (var n in reserved) {
      	if (n!="constructor") resvs.push(n);
      }
      resvs.sort(function (a,b) {
      	return b.length-a.length;
      });
      resvs.forEach(function (n) {
      	dtk(REG|DIV, SAMENAME, n, REG);
      });
  
  	//profileTbl( parsers[REG],"reg");
  	//profileTbl( parsers[DIV],"div");
  	//profileTbl( parsers[REG|DIV],"regdiv");
  	//parsers[REG|DIV]=parsers[REG].or(parsers[DIV]);
      function parse(str) {
      	//if (str.length>100000) return;
      	var t1=new Date().getTime();
  		var res=Parser.StringParser.parse(all, str);
  		console.log("Time="+(new Date().getTime()-t1));
  		if (res.success) {
  			/*res.result[0].forEach(function (e) {
  				if (e.type=="REGEX" || e.type=="DIV") {
  					console.log(e.type+"\t"+ str.substring(e.pos-5,e.pos+6));
  					//console.log( e.text+"\t"+e.type+"\t"+e.pos+"-"+e.len);
  				}
  			});*/
  		} else {
  			console.log("Stopped at "+str.substring( res.src.maxPos-5, res.src.maxPos+5));
  		}
  		return res;
  		//console.log(Profiler.report());
  		//console.log( disp(res.result[0]) );
      }
      return {parse:parse, extension:"js"};
  }();