从丑陋到优雅,让代码越变越美(客户端检测方法思考)

大家都知道,客户端检测不单可以让用户获得更好的体验,而且可以通过校验数据大大减少客户端和服务器端的往返次数,减少服务器负担。在这里,小弟打算回顾一下自己在客户端检测方面的学习历程和采用方法,如果大家有什么更好的方法或者建议,欢迎提出来共享!共同进步!

为了方便举例和说明,先构建一个简单的html页面,如下:

 

html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JS Verify</title>
</head>
<body>
    
<div>
        
<span>请输入用户名,年龄和自我介绍:</span>
        
<br />
        
<span>用户名:<input type="text" id="txtName" size="20" /></span>
        
<br />
        
<span>年龄:<input type="text" id="txtAge" size="5" /></span>
        
<br />
        
<span>自我介绍:</span>
        
<br />
        
<span><textarea id="txtIntro" rows="10" cols="50"></textarea></span>
        
<br />
        
<span><input type="button" value="提交信息" /></span>
    
</div>
</body>
</html>

 

第一阶段是:续项强写

每个人都基本会经过这个阶段,就是对检测内容每个都手工校验。很惭愧,自己也写过不少这样的代码。。这个阶段的代码如下:

 

Code1
function SubmitInfo()
{
    
var name = document.getElementById("txtName");
    
var age = document.getElementById("txtAge");
    
var intro = document.getElementById("txtIntro");
    
if(name == null || name.value == "")
    {
        alert(
"请输入用户名!");
        
return false;
    }
    
if(!/^[\u4E00-\u9FA5a-z0-9_]*$/gi.test(name.value))
    {
        alert(
"用户名只能由中文,英文,数字及下划线组成!");
        
return false;
    }
    
if(age == null || age.value == "")
    {
        alert(
"请输入年龄!");
        
return false;
    }
    
if(!/^[1-9]\d$/.test(age.value))
    {
        alert(
"年龄必须为正整数!");
        
return false;
    }
    
if(intro == null || intro.value == "")
    {
        alert(
"请输入自我介绍!");
        
return false;
    }
    alert(
"提交成功!");
    
return true;
}

 

 

不评价这个了。。因为每个人都可能因为写这些方法检测逻辑写得眼冒星星手抽筋的!弄的经常下班了还在扑哧扑哧的写啊写。。。。

 

第二阶段:集中消灭

相信不少初学者现在还是处于这个阶段,这阶段的同学们已经被第一阶段折磨怕了。很快就想出了集中消灭相同类型检测的方法。就是写检测函数,如下:

 

Code2
function isEmpty(obj)
{
    
if(obj == null || obj.value == "")
        
return false;
    
return true;
}

function isInt(val)
{
    
return /^[1-9]\d$/.test(val);
}

function isSafeString(val)
{
    
return /^[\u4E00-\u9FA5a-z0-9_]*$/gi.test(val);
}

 

同学们很可能还将上边代码独立成一个公共类,叫Common.js什么的,然后实际检测引用一下,就容易多了:

 

Code3
function SubmitInfo()
{
    
var name = document.getElementById("txtName");
    
var age = document.getElementById("txtAge");
    
var intro = document.getElementById("txtIntro");
    
if(!isEmpty(name))
    {
        alert(
"请输入用户名!");
        
return false;
    }
    
if(!isSafeString(name.value))
    {
        alert(
"用户名只能由中文,英文,数字及下划线组成!");
        
return false;
    }
    
if(!isEmpty(age))
    {
        alert(
"请输入年龄!");
        
return false;
    }
    
if(!isInt(age.value))
    {
        alert(
"年龄必须为正整数!");
        
return false;
    }
    
if(!isEmpty(intro))
    {
        alert(
"请输入自我介绍!");
        
return false;
    }
    alert(
"提交成功!");
    
return true;
}

 

看,不用每次写那些该死检测逻辑了。。要检测什么只要调用一下已经写好的公共检测方法就行了。轻松吧?!不过,还能更轻松吗?当然!请看:

 

第三阶段:链式的威力

看着一大堆if else总是心里觉得不舒服,对吧?一串串的又不是羊肉串,虽然不能吃,也要消灭它们!这时候,是Javascript的prototype出场的时候了。通过扩展prototype,可以获得简洁优雅的代码:

 

Code4
function SubmitInfo()
{
    
var name = document.getElementById("txtName");
    
var age = document.getElementById("txtAge");
    
var intro = document.getElementById("txtIntro");

    
if(!name.value.initVerify().isEmpty("请输入用户名!").isSafeString("用户名只能由中文,英文,数字及下划线组成!").verifyComplete())
        
return false;
    
    
if(!age.value.initVerify().isEmpty("请输入年龄!").isInt("年龄必须为正整数!").verifyComplete())
        
return false;
    
    
if(!intro.value.initVerify().isEmpty("请输入自我介绍!").verifyComplete())
        
return false;
    
    alert(
"提交成功!");
    
return true;
}

 

很简洁吧?相对前边一大串的羊肉串,是不是顺眼多了啊?哦,如何实现?其实很简单:

 

Code5
var validateStatus;
var validateMessage;

String.prototype.initVerify 
= function()
{
    validateStatus 
= true;
    validateMessage 
= "";
    
return this;
}

String.prototype.isEmpty 
= function(msg)
{
    
if(validateStatus)
    {
        
if(this == null || this == "")
        {
            validateStatus 
= false;
            validateMessage 
= msg;
        }
    }
    
return this;
}

String.prototype.isInt 
= function(msg)
{
    
if(validateStatus)
    {
        
if(!/^[1-9]\d$/.test(this))
        {
            validateStatus 
= false;
            validateMessage 
= msg;
        }
    }
    
return this;
}

String.prototype.isSafeString 
= function(msg)
{
    
if(validateStatus)
    {
        
if(!/^[\u4E00-\u9FA5a-z0-9_]*$/gi.test(this))
        {
            validateStatus 
= false;
            validateMessage 
= msg;
        }
    }
    
return this;
}

String.prototype.verifyComplete 
= function()
{
    
if(!validateStatus)
        alert(validateMessage);
    
return validateStatus;
}

 

怎么样?是不是很简单啊?这个prototype真是一个好东西啊!!链式编程,赞!!呵呵,怎么?你还不满足,代码太长?人心不足啊。我试试吧。。

第四阶段:自定义属性

这个阶段的提交函数如下:

 

Code6
function SubmitInfo()
{
    
if(!Verify(document.getElementById("txtName"))) return false;
    
if(!Verify(document.getElementById("txtAge"))) return false;
    
if(!Verify(document.getElementById("txtIntro"))) return false;
    
    alert(
"提交成功!");
    
return true;
}

 

想不通吧?怎么所有检测都一样啊?这不忽悠人吗?哈哈,要实现这个需要在html代码加点酱料:

 

Code7
    <div>
        
<span>请输入用户名,年龄和自我介绍:</span>
        <br />
        <span>用户名:<input type="text" id="txtName" size="20" verifyOptions='{"Empty":{"Flag":false,"Message":"请输入用户名!"},"SafeString":{"Message":"用户名只能由中文,英文,数字及下划线组成!"}}' /></span>
        
<br />
        <span>年龄:<input type="text" id="txtAge" size="5" verifyOptions='{"Empty":{"Flag":false,"Message":"请输入年龄!"},"Int":{"Message":"年龄必须为正整数!"}}' />岁</span>
        
<br />
        <span>自我介绍:</span>
        <br />
        <span><textarea id="txtIntro" rows="10" cols="50" verifyOptions='{"Empty":{"Flag":false,"Message":"请输入自我介绍!"}}' ></textarea></span>
        
<br />
        <span><input type="button" onclick="return SubmitInfo();" value="提交信息" /></span>
    
</div>

 

看到了吧,我们自定义了个叫verifyOption的属性,就是根据它们实现的分别对待的。就好像每个人都有银行卡,但是里面的钱都不一样一样(这个比喻好像比较牵强^_^)

还是看看Verify函数到底干了什么东西吧:

 

Code8
function Verify(obj)
{
    
if(obj.attributes["verifyOptions"== undefined)
    {
        alert(
"请定义verifyOptions!")
        
return false;
    }
    
var options = obj.attributes["verifyOptions"].nodeValue;
    
if(!options.isEmpty("检测参数不正确!"))
        
return false;
    
    options 
= options.parseJSON();
    
    
if(options.Empty != undefined && options.Empty.Flag == false)
    {
        
if(!obj.value.isEmpty(options.Empty.Message))
            
return false;
    }
    
if(options.Int != undefined)
    {
        
if(!obj.value.isInt(options.Int.Message))
            
return false;
    }
    
if(options.SafeString != undefined)
    {
        
if(!obj.value.isSafeString(options.SafeString.Message))
            
return false;
    }
    
return true;
}

 

就是检测自定义属性里面的设置,根据设置来进行相应检测。这下大家满足了吧?每次检测都一律一句Verify(*)就搞掂了!!QA的MM说检测不对?哦,不用急不用急,修改一下自定义属性verifyOption就好了。哈哈~~~

第五阶段:可配置

怎么还有第五阶段?疯狂了疯狂了~~(小子去死!!番茄,鸡蛋都丢上来了~~)唉,大家要注意文明礼貌嘛,丢着我没有关系,丢着花花草草也不好嘛。

 

Code9
<div>
    
<span>请输入用户名,年龄和自我介绍:</span>
    <br />
    <span>用户名:<input type="text" id="txtName" size="20" /></span>
    
<br />
    <span>年龄:<input type="text" id="txtAge" size="5" />岁</span>
    
<br />
    <span>自我介绍:</span>
    <br />
    <span><textarea id="txtIntro" rows="10" cols="50"></textarea></span>
    
<br />
    <span><input id="btnSubmit" type="button" value="提交信息" /></span>
</div>

 

第五阶段的html代码已经回复清爽了,毕竟自定义属性好像不太友善,不标准!既然不标准就放弃吧!是不是有同学怀疑,这样检测函数岂不是要写更对逻辑,一定比较臃肿吧?好吧,大家看检测函数:

 

Code10
function SubmitInfo()
{
    
if(!VerifyComplete())
        
return false;
    
    alert(
"提交成功!");
    
return true;
}

 

不是吧??骗人的吧?但是,事实如此,第五阶段就是这样简洁,这样优雅的实现了和上边几个阶段同样的功能。不相信,那就来看看吧!不过,第五阶段为了方便,引用了JQuery,找东西,它的搜索器还真好用。

这个阶段我们的检测配置都写到一个变量里面了:

 

Code11
var verifyConfig = [
{
"Id":"txtName""Option":{"Empty":{"Flag":false,"Message":"请输入用户名!"},"SafeString":{"Message":"用户名只能由中文,英文,数字及下划线组成!"}}},
{
"Id":"txtAge""Option":{"Empty":{"Flag":false,"Message":"请输入年龄!"},"Int":{"Message":"年龄必须为正整数!"}}},
{
"Id":"txtIntro""Option":{"Empty":{"Flag":false,"Message":"请输入自我介绍!"}}}]; 

 

这个变量我叫配置变量,建议大家将这些变量都放到同一个文件,叫verifyConfig.js?反正我是这么叫的,要修改检测逻辑,就修改这个配置文件就好了,当然,例子由于要强调第五阶段的简洁,就将VerifyComplete()函数参数设置为空,其实它应该有一个参数,用来传入设置变量。这样才通用。

最后奉上VerifyComplete()函数:

 

Code12
function VerifyComplete()
{
    
var controls = $(":input");
    
var verifyFlag = true;
    $.each(controls, 
function(i, n) {
        
if(verifyFlag)
            verifyFlag 
= Verify(n);
    });
    
return verifyFlag;
}


function Verify(obj)
{
    
var options;
    $.each(verifyConfig, 
function(i, n) {
        
if(n.Id == obj.id)
            options 
= n.Option;
    });
    
    
if(options == undefined)
        
return true;
    
    
if(options.Empty != undefined && options.Empty.Flag == false)
    {
        
if(!obj.value.isEmpty(options.Empty.Message))
            
return false;
    }
    
if(options.Int != undefined)
    {
        
if(!obj.value.isInt(options.Int.Message))
            
return false;
    }
    
if(options.SafeString != undefined)
    {
        
if(!obj.value.isSafeString(options.SafeString.Message))
            
return false;
    }
    
    
return true;
}

 

斗胆第一次上首页,希望能得到大家指点,进入第六阶段。第六阶段是怎么样?我还真想不到!

附上上述完整代码:点击下载

 

再次浏览自己的代码,发现很多类似:

 

WarningCode
if(xxx)
   
return true;
else
   
return false;

 

上边的代码是很笨蛋的.直接一句:

 

RightCode
return xxx;

或者

return !xxx;

 

就好了..何必大费周章呢.汗死了...自己撞一下墙再反思...哦,还有类似:

 

WarningCode
if(xxx == true)
   

 

也是很笨蛋的,只要xxx是bool值.就直接:

 

RightCode
if(xxx)
   

 

好了...罚自己面壁思过!

posted @ 2009-03-16 21:25 KenBlove 阅读(4342) 评论(65) 编辑 收藏

 回复 引用 查看   
#1楼 2009-03-16 21:41 LeoLWang      
相当帅!
 回复 引用   
#2楼 2009-03-16 21:49 cnHui[未注册用户]
不错
 回复 引用   
#3楼 2009-03-16 22:01 gavin.chen[未注册用户]
不想.楼主的思想是对的,代码要能用性强点.
 回复 引用 查看   
#4楼 2009-03-16 22:10 ·风信子·      
楼主爆强。
不过我现在习惯用jQuery的validate插件,呵呵。jQuery好强大

 回复 引用 查看   
#5楼 2009-03-16 22:29 T2噬菌体      
很有启发性的文章
 回复 引用 查看   
#6楼 2009-03-16 22:36 温景良(Jason)      
相当好,很有启发性
 回复 引用 查看   
#7楼 2009-03-16 22:43 Jeffrey Zhao      
第六阶段:良好的可测试性,客户端单元测试。
第七阶段,就是将验证脚本与服务器DSL集成——其实就是编写服务器端辅助方法,让验证逻辑与被验证内容集中式管理,并可以和服务器端模型进行集成。再进一步,则自动从服务器模型中提取metadata并自动生成验证。不过这好像就越来越远离“客户端”验证了。关于这些我一直打算写文章,不过最近可写的东西越来越多,等没东西写了会补上的。

 回复 引用 查看   
#8楼 2009-03-16 22:45 Jeffrey Zhao      
忘了一说,写的很好,真的很好,我喜欢这种文章。
 回复 引用 查看   
#9楼[楼主] 2009-03-16 23:01 KenBlove      
多谢 Jeffrey Zhao ~客户端单元测试?还真没有试过,要好好研究一下。至于第七阶段,就已经和服务器端编程开始融合了,还没有研究到这个阶段,期待拜读你的文章~
 回复 引用 查看   
#10楼[楼主] 2009-03-16 23:03 KenBlove      
更要多谢大家支持~~差点忘记了,还有TVB,Paco。。。
 回复 引用   
#11楼 2009-03-16 23:12 入门级[未注册用户]
没用过JQ,不过据说很强大
弱弱滴问一句,JQuery如何对付Grid生成滴Table。

 回复 引用 查看   
#12楼 2009-03-16 23:13 virus      
我靠
有点小伟大啊
佩服了
这不就是JQuery的起源吗
prototype

 回复 引用 查看   
#13楼 2009-03-16 23:14 任暖      
谢谢分享
 回复 引用 查看   
#14楼 2009-03-16 23:15 virus      
绝对的要好好学习
 回复 引用   
#15楼 2009-03-16 23:29 GreetJob!![未注册用户]
Great Job!!!! COOOOOOOOOOOOOOL
 回复 引用 查看   
#16楼 2009-03-16 23:50 Inrie(洪小军)      
赞一个,很喜欢这样风格的文章!
 回复 引用   
#17楼 2009-03-17 00:23 Soncy@中山[未注册用户]
支持,代码优雅就是美!
 回复 引用 查看   
#18楼 2009-03-17 00:51 S.Sams      
这种文章风格不错, 非常类似 jQuery 的写法.
写成一个独立的扩展, 再加上单元测试就完美了.

 回复 引用 查看   
#19楼 2009-03-17 08:34 沉默杨仔      
太强了。学习中。。。
 回复 引用 查看   
#20楼 2009-03-17 08:38 sunlovesea      
一个地方简单了,另一个地方就复杂了...
还要考虑一下后期的可维护行...毕竟不是开发者一个人后期维护..

 回复 引用 查看   
#21楼 2009-03-17 08:39 sunlovesea      
这样步步深入的文章很好.有点像大话设计模式的风格..
 回复 引用 查看   
#22楼 2009-03-17 09:06 假正经哥哥      
很不错哦,最后的思路和Jquery Validation 殊途同归。。
但是这样演变的过程,更易于读者理解

 回复 引用   
#23楼 2009-03-17 09:14 hrmai[未注册用户]
如果有玉我就扔一块给你。

 回复 引用 查看   
#24楼 2009-03-17 09:14 Shpix      
很好,楼主的思想很有启发
 回复 引用 查看   
#25楼 2009-03-17 09:16 Mervin      
这样的话,自定义的提示信息好像给抹杀了吧。。
 回复 引用 查看   
#26楼[楼主] 2009-03-17 09:19 KenBlove      
@sunlovesea
只要分层控制得好,可维护度应该是一种比一种更好,而且更容易修改可扩展的.

 回复 引用 查看   
#27楼[楼主] 2009-03-17 09:21 KenBlove      
@Mervin
自定义提示信息是配置信息的一部分,所以不存在这个问题.另外,这里为了举例我只是简单的alert出一个提示,其实可以将alert用一个function代替,这样就更容易控制提示的显示方式了.

 回复 引用 查看   
#28楼 2009-03-17 09:32 痴情客      
我现在走的是可配置路线,呵呵

因为一个文本框可能会验证 为空,合法性,是否存在,那么要走并列的,可配置的。


 回复 引用 查看   
#29楼 2009-03-17 09:33 痴情客      
你这种方法还是没有解决本质问题
 回复 引用 查看   
#30楼 2009-03-17 09:40 菌哥      
这种循序渐进的风格,真是太喜欢了
 回复 引用 查看   
#31楼 2009-03-17 09:45 老鼠      
楼主测试4有问题
 回复 引用 查看   
#32楼[楼主] 2009-03-17 10:10 KenBlove      
@痴情客
请指教,本质问题是指什么问题?

 回复 引用 查看   
#33楼 2009-03-17 10:12 Dreampuf      
在html中可以通过设置属性时加个{}就能直接使用双引号?.
 回复 引用 查看   
#34楼[楼主] 2009-03-17 10:16 KenBlove      
@老鼠
所有例子只在IE7和FF3下测试过,不知道你说的有问题是什么问题? 我只是提出一种思想,具体检测不严密请见谅哦^_^

 回复 引用 查看   
#35楼[楼主] 2009-03-17 10:18 KenBlove      
@Dreampuf
看漏了吧,外边有对单引号呢~

 回复 引用 查看   
#36楼 2009-03-17 10:20 黑羽飘舞      
很好的内容,思路比较清晰
 回复 引用 查看   
#37楼 2009-03-17 10:21 杆子      
很好
 回复 引用 查看   
#38楼 2009-03-17 10:27 ChenMo      
写验证js确实累人,希望你能弄个完整的可用插件,以飨懒人——应该没有爱好写验证之人。

我提个关于易用性的意见,看过数个验证类的插件,每每摩手欲试的时候,总觉得整体还是不尽人意,对于较为庞杂的表单,相信如果参照文中这般配置一番,还是需要颇多的键盘敲击量,未见得有多少可以益助省力省事。验证辅助类的插件在功能强大基础上,宜应使用简易,可扩展能力强,学习及记忆时间短,及可重用已写过的验证(即便是复制粘贴亦无不可)。

因为可能待验证的表单过大,加上“错误信息”等内容,配置必然势趋庞大,宜应精简结构,惜俭字符,所有操作集汇在一个函数中,该函数名最好莫如简短为一个字母 v。

例如:
对于我个人而言一个 json 不如节约为一行字符串:
【添加验证】
$(".txtbox").v("e:请输入数字;i(1-120):请输入1-120之间的数;");

e => 存在则不为空
i => 整型

【全局配置】
$.v(...配置项...);

【触发验证】
$.v();

【新建验证规则】
$.va("t", /p\d{4}/,"请正确输入车间编号(4位)。");

【使用刚才新建的规则】
$("#pid").v("t");

【修改规则】
$.vu("t", /p\d{5}/, "请正确输入车间编号(5位)。");

【删除规则】
$.vr("t");



若能做到当我一想到要验证一堆 input 的时候,便有心静不惊之感:
别害怕,v 一下。

 回复 引用 查看   
#39楼 2009-03-17 10:45 Anytao      
很好很强大,有点多态的意思,所以其实js也可以很OO,就是这个道理吧
 回复 引用 查看   
#40楼[楼主] 2009-03-17 10:49 KenBlove      
@ChenMo
有道理,大道至简.而且从理论上是可以实现你想要的.我也对配置文件的繁杂有点讨厌,但是分析字符串难于分析Jason,犹豫之间还是选择了用jason演示.

 回复 引用   
#41楼 2009-03-17 11:05 YokerWu[未注册用户]
我曾经也写过,不过感觉还是楼主研究得细啊。
http://yoker.sc0826.com/article.asp?id=263

 回复 引用 查看   
#42楼 2009-03-17 11:11 狗尾草.      
好文,说实话,没怎么深入研究过脚本。受启发了!
 回复 引用 查看   
#43楼 2009-03-17 11:45 vincent_赵      
感谢楼主,又浅到深,学到了~
 回复 引用 查看   
#44楼 2009-03-17 11:59 江大鱼      
很不错的文章,想让js看起来很美确实很难,但楼主做到了
 回复 引用 查看   
#45楼 2009-03-17 12:57 AlexChen      
看这个文章很舒服,内容也很好,很有启发性...
持续关注中...
拜读了...:-)

 回复 引用 查看   
#46楼 2009-03-17 13:12 Carrod      
好东西,支持。
@ChenMo
配置倒也关系不大,而且可以另外开发个小工具进行配置管理嘛。

 回复 引用 查看   
#47楼[楼主] 2009-03-17 13:35 KenBlove      
配置生成工具是个好想法!!还可以后台生成配置输出到页面,这样,貌似有可能后台就可以控制前台的JS检测了.
 回复 引用 查看   
#48楼 2009-03-17 13:41 dachuan      
好文,拜读了!
 回复 引用 查看   
#49楼 2009-03-17 15:13 ChenMo      
--引用--------------------------------------------------
Carrod: 好东西,支持。
@ChenMo
配置倒也关系不大,而且可以另外开发个小工具进行配置管理嘛。
--------------------------------------------------------

若能结合配置工具,还能生个表单雏形出来,那当真是一石多鸟,一箭多雕。

 回复 引用 查看   
#50楼 2009-03-17 15:27 ChenMo      
有时因数据采集量大,虽然分布散落到各个表单,然而需验证的项总数超逾百十有余,烦不胜烦。又总不能不做验证,稀松了事,咱们程序员有强烈责任感者甚(顺便包含自个进去),所以希望看到一个好用易用的验证工具,诸君多努力了,我迫不及待、殷切期望、翘首期盼等着用,至于我自己,坦然没这能力与时间,即便有时间我想弄弄别的,不想动程序。
 回复 引用   
#51楼 2009-03-17 15:53 刀仔
拜读
 回复 引用 查看   
#52楼[楼主] 2009-03-17 16:01 KenBlove      
我想实现的目标是:
1.如果用户想即时检测,那么请在页面Onload的时候调用VerifyInit(config);
2.如果想提交时候检测,那么请调用VerifyComplete(config).
只需两步完成客户端检测.
(当然,我会提供小工具帮助生成Jason格式的config.用户需要做的只是复制.)
^_^想想都兴奋~~

 回复 引用 查看   
#53楼 2009-03-17 16:20 ~数字人生~      
很详细的阐述~~谢谢分享

深入研究中...

 回复 引用 查看   
#54楼 2009-03-17 23:30 寂寞的小星星      
很好很强大。。。
 回复 引用 查看   
#55楼 2009-03-18 09:16 Develop....      
向楼主学习!!强
 回复 引用 查看   
#56楼 2009-03-18 17:56 xcb_isgreat      
写的很好 希望lz能多写些js文章 你对js理解的很深
 回复 引用   
#57楼 2009-03-18 22:13 gleery[未注册用户]
最后一种方法是复用逻辑的一个很好的方法,在很多语言里面都可以使用,他解决的主要问题就是微小的差别导致的大量类似的代码。这种方法我把他叫做参数话,即将不同的部分用参数来描述,逻辑代码中只需要根据参数来运作,从而实现了消除原有的重复代码的目的。这种思路在很多地方都可以看到,最典型的是编译器的复用,通过参数化,我们可以使用通用的词法生成器来生成自定义的词法解析器。
 回复 引用   
#58楼 2009-03-24 15:16 love24
很强.
我还是倾向第三阶段,呵

 回复 引用   
#59楼 2009-03-25 22:37 derekliao
顶哦顶,写不很不错哦~
 回复 引用   
#60楼 2009-03-30 21:12 xueyu[未注册用户]
So Cool!!!!!!!!
 回复 引用 查看   
#61楼 2009-09-26 09:39 阿诚      
好文、好文,受益匪浅,期待楼主更多佳作...
 回复 引用   
#62楼 2009-10-07 18:07 耳热热[未注册用户]
讲了半天都没下载,感情是光耍嘴啊,成品呢?
 回复 引用 查看   
#63楼[楼主] 2009-10-07 19:59 KenBlove      
引用耳热热:讲了半天都没下载,感情是光耍嘴啊,成品呢?

这个......可能你我缘分未够吧:-(

 回复 引用 查看   
#64楼 2010-03-12 09:46 Ju2ender      
很强大,关注你
 回复 引用 查看   
#65楼 2010-04-29 09:43 血吸虫      
很不错啊 很有启发