<?xml version="1.0" encoding="gb2312" standalone="yes"?>
<!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:v="http://www.eglic.com/">
<head>
<title></title>
<meta name="Generator" content="EditPlus" />
<meta name="Author" content="eglic" />
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta name="CharSet" content="GB2312" />
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<style type="text/css">
@media all{

}
</style>
<script language="javascript" src="/scripts/default.js"></script>
<script language="javascript" src="/scripts/xml.js"></script>
<script language="javascript">//<!--
var s=" //绑定VBScript的编码转换函数\n" +
" AttachVBFunctionsToWindow();\n" +
" //准备全局变量\n" +
" var http=CreateHTTPPoster();\n" +
" var TokenID=\'\';\n" +
" //申请令牌\n" +
" http.open(\'POST\',\'http://localhost:8001/RAP.do?action=Initialize\',false);\n" +
" http.send();\n" +
" if(http.status!=200){\n" +
" alert(\'初始化失败 [\'+http.status+\']\');\n" +
" }else{\n" +
" var dom=CreateXMLParser();\n" +
" dom.loadXML(http.responseText);\n" +
" TokenID=dom.documentElement.text;\n" +
" alert(\'得到的令牌是:\'+TokenID);\n" +
" }\n" +
" //释放令牌\n" +
" http.open(\'POST\',\'http://localhost:8001/RAP.do?action=Dispose\',false);\n" +
" http.setRequestHeader(\"Content-Type\",\"application/x-www-form-urlencoded\");\n" +
" http.send(\'TokenID=\'+TokenID);\n" +
" if(http.status!=200){\n" +
" alert(\'销毁令牌时发生错误 [\'+http.status+\']\');\n" +
" }else{\n" +
" var dom=CreateXMLParser();\n" +
" var sxml=Bytes2BSTR(http.responseBody); //这里包含有中文,需要用VBScript函数解码\n" +
" dom.loadXML(sxml);\n" +
" /*alert(dom.documentElement.text);*/\n" +
" }\n";
/*
NodeType定义:
0 未定义
1 执行语句
2 字符串
3 单行注释
4 多行注释
*/
function CodeNode(){
this.SourceCode='';
this.NodeType=0;
this.ChildNodes=null;
}
var RootNode=new CodeNode();

function ParseCodeStringToTree(s,n){
n.SourceCode=s;
n.ChildNodes=new Array();
var StrFlag="";
var CmtFlag="";
var tmp="";
for(var i=0;i<s.length;i++){
var c=s.charAt(i);
if(c=='\r' || c=='\n'){ //遇到回车
if(StrFlag!='' && SteFlag=='')  //在字符串未结束之前遇到换行,抛出语法错误
throw new Error('在字符串 '+tmp+' 附近遇到语法错误');
if(CmtFlag=='//'){ //在单行注释内遇到回车,结束单行注释
n.ChildNodes[n.ChildNodes.length]=new CodeNode();
n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
n.ChildNodes[n.ChildNodes.length-1].NodeType=3
CmtFlag='';
tmp='';
}//其他情况暂不考虑
}
if(c=='"' || c=="'"){ //遇到引号
if(StrFlag=='') { //这是遇到的第一个引号,字符串的开始
n.ChildNodes[n.ChildNodes.length]=new CodeNode();
n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
n.ChildNodes[n.ChildNodes.length-1].NodeType=1
tmp=c;
StrFlag=c; //重新开始一个分析
continue;
}
if(StrFlag==c && i>0 && s.charAt(i-1)!='\\'){ //字符串已经开始,并且当前字符串是结束符
n.ChildNodes[n.ChildNodes.length]=new CodeNode();
n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+c;
n.ChildNodes[n.ChildNodes.length-1].NodeType=2
tmp='';
StrFlag='';
continue;
}
//其他情况表示字符串还没结束,继续下一个字符
}
if(c=='/' && i<s.length-1 && s.charAt(i+1)=='/'){ //遇到疑是单行注释符号
if(CmtFlag!=''){ //在注释块内出现,继续
tmp+=c;
continue;
}else if(StrFlag!='') { //还在字符串内,继续
tmp+=c;
continue;
}else{ //不在字符串内,确定是单行注释
n.ChildNodes[n.ChildNodes.length]=new CodeNode();
n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
n.ChildNodes[n.ChildNodes.length-1].NodeType=1
tmp='//';
i++;
CmtFlag='//';
continue;
}
}
if(c=='/' && i<s.length-1 && s.charAt(i+1)=='*'){ //遇到疑是多行注释符号
if(CmtFlag!=''){ //在注释块内出现,继续
tmp+=c;
continue;
}else if(StrFlag!='') { //还在字符串内,继续
tmp+=c;
continue;
}else{ //不在字符串内,确定是多行注释开始
n.ChildNodes[n.ChildNodes.length]=new CodeNode();
n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
n.ChildNodes[n.ChildNodes.length-1].NodeType=1
tmp='/*';
i++;
CmtFlag='/*';
continue;
}
}
if(c=='*' && i<s.length-1 && s.charAt(i+1)=='/'){ //遇到疑是多行注释的结束符
if(StrFlag!=''){ //在字符串内出现,继续
tmp+=c;
continue;
}else if(CmtFlag==''){ //突然冒出来的,语法错误
throw new Error('出现意外的多行注释结束符');
}else if(CmtFlag=='//'){ //在单行注释内出现 */ 不管,继续
tmp+=c;
continue;
}else if(CmtFlag=='/*'){ //当前注释标志是 /* ,确认是多行注释结束符
n.ChildNodes[n.ChildNodes.length]=new CodeNode();
n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+'*/';
n.ChildNodes[n.ChildNodes.length-1].NodeType=4
i++;
CmtFlag='';
tmp='';
continue;
}
}
tmp+=c;
}
}
ParseCodeStringToTree(s,RootNode);
//输出函数
function PrintCode(n){
var a=new Array('未定义','执行语句','字符串','单行注释','多行注释');
document.write(a[n.NodeType]+':<textarea cols="130" rows="8">'+n.SourceCode+'</textarea><br />');
}
//输出
PrintCode(RootNode);
for(var i=0;i<RootNode.ChildNodes.length;i++){
PrintCode(RootNode.ChildNodes[i]);
}
//--></script>
</head>
<body>
</body>
</html>

解决方案 »

  1.   

    这样可能看的更清楚<script language="javascript">//<!--
    var s=" //绑定VBScript的编码转换函数\n" +
    " AttachVBFunctionsToWindow();\n" +
    " //准备全局变量\n" +
    " var http=CreateHTTPPoster();\n" +
    " var TokenID=\'\';\n" +
    " //申请令牌\n" +
    " http.open(\'POST\',\'http://localhost:8001/RAP.do?action=Initialize\',false);\n" +
    " http.send();\n" +
    " if(http.status!=200){\n" +
    " alert(\'初始化失败 [\'+http.status+\']\');\n" +
    " }else{\n" +
    " var dom=CreateXMLParser();\n" +
    " dom.loadXML(http.responseText);\n" +
    " TokenID=dom.documentElement.text;\n" +
    " alert(\'得到的令牌是:\'+TokenID);\n" +
    " }\n" +
    " //释放令牌\n" +
    " http.open(\'POST\',\'http://localhost:8001/RAP.do?action=Dispose\',false);\n" +
    " http.setRequestHeader(\"Content-Type\",\"application/x-www-form-urlencoded\");\n" +
    " http.send(\'TokenID=\'+TokenID);\n" +
    " if(http.status!=200){\n" +
    " alert(\'销毁令牌时发生错误 [\'+http.status+\']\');\n" +
    " }else{\n" +
    " var dom=CreateXMLParser();\n" +
    " var sxml=Bytes2BSTR(http.responseBody); //这里包含有中文,需要用VBScript函数解码\n" +
    " /*dom.loadXML(sxml);\n" +
    " alert(dom.documentElement.text);*/\n" +
    " }\n";
    /*
    NodeType定义:
    0 未定义
    1 执行语句
    2 字符串
    3 单行注释
    4 多行注释
    */
    function CodeNode(){
    this.SourceCode='';
    this.NodeType=0;
    this.ChildNodes=null;
    }
    var RootNode=new CodeNode();

    function ParseCodeStringToTree(s,n){
    n.SourceCode=s;
    n.ChildNodes=new Array();
    var StrFlag="";
    var CmtFlag="";
    var tmp="";
    for(var i=0;i<s.length;i++){
    var c=s.charAt(i);
    if(c=='\r' || c=='\n'){ //遇到回车
    if(StrFlag!='' && SteFlag=='')  //在字符串未结束之前遇到换行,抛出语法错误
    throw new Error('在字符串 '+tmp+' 附近遇到语法错误');
    if(CmtFlag=='//'){ //在单行注释内遇到回车,结束单行注释
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=3
    CmtFlag='';
    tmp='';
    }//其他情况暂不考虑
    }
    if(c=='"' || c=="'"){ //遇到引号
    if(StrFlag=='') { //这是遇到的第一个引号,字符串的开始
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1
    tmp=c;
    StrFlag=c; //重新开始一个分析
    continue;
    }
    if(StrFlag==c && i>0 && s.charAt(i-1)!='\\'){ //字符串已经开始,并且当前字符串是结束符
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+c;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=2
    tmp='';
    StrFlag='';
    continue;
    }
    //其他情况表示字符串还没结束,继续下一个字符
    }
    if(c=='/' && i<s.length-1 && s.charAt(i+1)=='/'){ //遇到疑是单行注释符号
    if(CmtFlag!=''){ //在注释块内出现,继续
    tmp+=c;
    continue;
    }else if(StrFlag!='') { //还在字符串内,继续
    tmp+=c;
    continue;
    }else{ //不在字符串内,确定是单行注释
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1
    tmp='//';
    i++;
    CmtFlag='//';
    continue;
    }
    }
    if(c=='/' && i<s.length-1 && s.charAt(i+1)=='*'){ //遇到疑是多行注释符号
    if(CmtFlag!=''){ //在注释块内出现,继续
    tmp+=c;
    continue;
    }else if(StrFlag!='') { //还在字符串内,继续
    tmp+=c;
    continue;
    }else{ //不在字符串内,确定是多行注释开始
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1
    tmp='/*';
    i++;
    CmtFlag='/*';
    continue;
    }
    }
    if(c=='*' && i<s.length-1 && s.charAt(i+1)=='/'){ //遇到疑是多行注释的结束符
    if(StrFlag!=''){ //在字符串内出现,继续
    tmp+=c;
    continue;
    }else if(CmtFlag==''){ //突然冒出来的,语法错误
    throw new Error('出现意外的多行注释结束符');
    }else if(CmtFlag=='//'){ //在单行注释内出现 */ 不管,继续
    tmp+=c;
    continue;
    }else if(CmtFlag=='/*'){ //当前注释标志是 /* ,确认是多行注释结束符
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+'*/';
    n.ChildNodes[n.ChildNodes.length-1].NodeType=4
    i++;
    CmtFlag='';
    tmp='';
    continue;
    }
    }
    tmp+=c;
    }
    }
    ParseCodeStringToTree(s,RootNode);
    //输出函数
    function HTMLEncode(s,c){
    var t=s.replace('&','&amp;');
    t=t.replace(' ','&nbsp;');
    t=t.replace('<','&lt');
    t=t.replace('<','&gt');
    t=t.replace('\t','&nbsp;&nbsp;&nbsp;&nbsp;');
    t=t.replace('\n','<br />');
    t=t.replace('\r','<br />');
    return '<font color="'+c+'">'+t+'</font>';
    }
    function PrintCode(n){
    var a=new Array('black','black','#A00000','#0000A0','#00A000'); document.write(HTMLEncode(n.SourceCode,a[n.NodeType]));
    }
    //输出
    for(var i=0;i<RootNode.ChildNodes.length;i++){
    PrintCode(RootNode.ChildNodes[i]);
    }
    //--></script>
      

  2.   

    给输出的颜色加上注释function PrintCode(n){
    /*指定各种类型语句的输出颜色
    未定义: 黑色
    普通执行语句: 黑色
    字符串 深红色
    单行注释 深蓝色
    多行注释 深绿色
    */
    var a=new Array('black','black','#A00000','#0000A0','#00A000');
    document.write(HTMLEncode(n.SourceCode,a[n.NodeType]));
    }
      

  3.   

    补充:
    1、
    上面的代码在 ParseCodeStringToTree函数,主for循环后面
    最后剩下的字符串忘记放到ChildNodes里面去,补充上 tmp+=c;
    }
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();   //这一行
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp; //这一行
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1      //这一行
    }
    ParseCodeStringToTree(s,RootNode);2、在解析过程中因为过程复杂,时间仓促,丢了几个回车或者制表符
       等有空再来补上
      

  4.   

    丢了这三行是有逻辑错误的,因为我给的这段实例代码的多行注释出现在最后
    从最后一个多行注释结束后,只有几个花括号
    如果不仔细就会发现丢了几个花括号 :D补上这三行,代码就基本上完整了,但是因为我用了太多的continue和
    太多的if,没时间去想更好的构造,丢了一些制表符和回车一直都没找到是那儿丢的
    希望只是丢制表符和回车,不是其他的PS:好久没练习过JS,突然有这么个问题可以动动脑筋,今晚可以睡个安稳觉了,最近太颓废
      

  5.   

    回家仔细研究了一下,解决两个问题
    1、对于 以\\'结束的字符串理解错误,就是字符串结尾是两个\,
       但是原程序会以为字符串没有结束
    2、丢字符问题,发现不是解析错误,是最后格式化显示的时候replace函数搞的鬼完整代码如下,可以自己在文本框里粘贴一段代码试试
    ==================================================================================
    <?xml version="1.0" encoding="gb2312" standalone="yes"?>
    <!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns:v="http://www.eglic.com/">
    <head>
    <title></title>
    <meta name="Generator" content="EditPlus" />
    <meta name="Author" content="eglic" />
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <meta name="CharSet" content="GB2312" />
    <link rel="stylesheet" type="text/css" href="/styles/default.css" />
    <style type="text/css">
    @media all{
    * {font-size:12px;font-family:Courier New;}
    }
    </style>
    <script language="javascript" src="/scripts/default.js"></script>
    <script language="javascript" src="/scripts/xml.js"></script>
    <script language="javascript">//<!--
    /*
    NodeType定义:
    0 未定义
    1 执行语句
    2 字符串
    3 单行注释
    4 多行注释
    */
    function CodeNode(){
    this.SourceCode='';
    this.NodeType=0;
    this.ChildNodes=null;
    }
    var RootNode=new CodeNode(); function ParseCodeStringToTree(s,n){
    n.SourceCode=s;
    n.ChildNodes=new Array();
    var StrFlag="";
    var CmtFlag="";
    var tmp="";
    for(var i=0;i<s.length;i++){
    var c=s.charAt(i);
    if(c=='\r' || c=='\n'){ //遇到回车
    if(StrFlag!='') //在字符串未结束之前遇到换行,抛出语法错误
    throw new Error('在字符串 '+tmp+' 附近遇到语法错误:未结束的字符串常量');
    if(CmtFlag=='//'){ //在单行注释内遇到回车,结束单行注释
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+c;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=3;
    CmtFlag='';
    tmp='';
    continue;
    }//其他情况暂不考虑
    }
    if(c=='"' || c=="'"){ //遇到引号
    if(StrFlag=='') { //这是遇到的第一个引号,字符串的开始
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1;
    tmp=c; //将单引号赋给新的字符串
    StrFlag=c; //重新开始一个分析
    continue;
    }
    if((StrFlag==c && i>0 && s.charAt(i-1)!='\\') ||
    (StrFlag==c && i>1 && s.charAt(i-1)=='\\' && s.charAt(i-2)=='\\')){ //字符串已经开始,并且当前字符串是结束符
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+c;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=2;
    tmp='';
    StrFlag='';
    continue;
    }
    //其他情况表示字符串还没结束,继续下一个字符
    }
    if(c=='/' && i<s.length-1 && s.charAt(i+1)=='/'){ //遇到疑是单行注释符号
    if(CmtFlag!=''){ //在注释块内出现,继续
    tmp+=c;
    continue;
    }else if(StrFlag!='') { //还在字符串内,继续
    tmp+=c;
    continue;
    }else{ //不在字符串内,确定是单行注释
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1;
    tmp='//';
    i++;
    CmtFlag='//';
    continue;
    }
    }
    if(c=='/' && i<s.length-1 && s.charAt(i+1)=='*'){ //遇到疑是多行注释符号
    if(CmtFlag!=''){ //在注释块内出现,继续
    tmp+=c;
    continue;
    }else if(StrFlag!='') { //还在字符串内,继续
    tmp+=c;
    continue;
    }else{ //不在字符串内,确定是多行注释开始
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1;
    tmp='/*';
    i++;
    CmtFlag='/*';
    continue;
    }
    }
    if(c=='*' && i<s.length-1 && s.charAt(i+1)=='/'){ //遇到疑是多行注释的结束符
    if(StrFlag!=''){ //在字符串内出现*/,继续
    tmp+=c;
    continue;
    }else if(CmtFlag==''){ //突然冒出来的,语法错误
    throw new Error('出现意外的多行注释结束符');
    }else if(CmtFlag=='//'){ //在单行注释内出现 */ 不管,继续
    tmp+=c;
    continue;
    }else if(CmtFlag=='/*'){ //当前注释标志是 /* ,确认是多行注释结束符
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp+'*/';
    n.ChildNodes[n.ChildNodes.length-1].NodeType=4;
    i++;
    CmtFlag='';
    tmp='';
    continue;
    }
    }
    tmp+=c;
    }
    n.ChildNodes[n.ChildNodes.length]=new CodeNode();
    n.ChildNodes[n.ChildNodes.length-1].SourceCode=tmp;
    n.ChildNodes[n.ChildNodes.length-1].NodeType=1
    }
    //输出函数
    function HTMLEncode(s,c){
    //这里要用正则表达式,否则替换不完整
    //可能String.replace方法默认就是用正则的
    var t=s.replace(/\&/gim,'&amp;');
    t=t.replace(/\x20/gim,'&nbsp;');
    t=t.replace(/\t/gim,'&nbsp;&nbsp;&nbsp;&nbsp;');
    t=t.replace(/\</gim,'&lt');
    t=t.replace(/\>/gim,'&gt');
    t=t.replace(/\n/gim,'<br />');
    t=t.replace(/\r/gim,'<br />');

    return '<font color="'+c+'">'+t+'</font>';
    }
    function PrintCode(n){
    /*指定各种类型语句的输出颜色
    未定义: 黑色
    普通执行语句: 黑色
    字符串 深红色
    单行注释 深蓝色
    多行注释 深绿色
    */
    var a=new Array('black','black','#A00000','#00A000','#00A000');
    return (HTMLEncode(n.SourceCode,a[n.NodeType]));
    }
    //输出
    function Analyse(){
    var o='';
    ParseCodeStringToTree(document.getElementById('sSource').value,RootNode);
    for(var i=0;i<RootNode.ChildNodes.length;i++){
    o+=PrintCode(RootNode.ChildNodes[i]);
    }
    document.getElementById('out').innerHTML=o;
    }
    //--></script>
    </head>
    <body>
    <textarea id="sSource" cols="130" rows="10"></textarea><button onclick="JavaScript:Analyse();">着色</button>
    <pre id="out">
    </pre>
    </body>
    </html>