事件驱动:Parse-Handler模型(如:xml之SAX模型)该模型主要有Parser和Handler两个组件。其原型大体如下:
class
xxxHandler
{ public : // any event sended from Parser ... }; class xxxParser { public : xxxxParser(InputSource * source); HRESULT parse(xxxxHandler * handler) { // analyze source and send event to handler ... } }; 该模型不规定Handler类型的详细规格,由Parser的实现者根据具体情况而定。 Tokenizer模型(如:编译器的词法分析器)这种模型仅涉及一个Tokenizer组件。该组件负责将文本分解为一个个token。其原型大体如下:
class
xxxTokenizer
{ public : xxxTokenizer(InputSource * source); // // 成功返回S_OK,如果遇到eof返回S_FALSE。 // HRESULT next(TOKEN * token); }; 其中分析的结果以一个结构体TOKEN表示。这个结构体如何设计,同样视具体情况而定。通常它看起来是这样的:
struct
TOKEN
{ UINT type; union { DATATYPE1 data1; // 当type = type1时 DATATYPE2 data2; // 当type = type2时 ... }; }; 有了Tokenizer,我们就可以轻易的遍历整个文档:
void visit(InputSource *
source)
{ TOKEN token; xxxTokenizer tokenizer(source); while (tokenizer.next( & token) == S_OK) { print(token); } } token应当如何划分,其粒度如何,完全取决于设计者的考量。以以下一段xml文本为例:
< elem // element start
attr = " value " // attr-value pair content // content </ elem > // element end 也可以将attr-value pair细分为三个token:attr, assign-symbol, value。 从广义上来说,我们文件系统提供的字节流本身已经是一个Tokenizer了,只不过它划分的token是一个个并无多少逻辑含义的character。 而我们后面提到的DOM模型,也可以算是一个Tokenizer。只不过它划分的token只有一个,就是DOM树,与文件系统的字节流走的是另一个极端。 Tokenizer方式与Parse-Handler方式设计思路,最大的不同在于具体处理信息的人主被动地位相异。在Tokenizer模式下,信息处理者调用Tokenizer得到分析数据,如果相邻的token存在上下文关系,你可以根据需要去取得下一个token,故处于主动地位。 而Parse-Handler模式相关死板一些,一方面Handler类实现者才是真正试图处理信息的人,但是实际上对信息的划分(token)却是由Parse规定的,未必完全符合Handler类的需求。另一方面在token存在上下文关系,当前接受的数据信息不足时,Handler类无法随心所欲的取得下一个token(因为从流程上它是被动的数据接受方),而只能暂时缓存数据,等待下一条信息的到来。 文档对象:DOM模型 DOM模型是最高级的一种模型。它的思路是将文档完整地读入内存,并提供数据访问接口。 这里提到DOM模型消耗的内存最多,这种说法并不全面。例如,在将它与Parse-Handler模型相比时,我们只是计算了Parser的开销,而Handler类是客户实现的,内存开销多少,无从计算。 另一方面,由于DOM模型可以按自己的方式组织数据,它在内存开销上的可优化余地很大,并且客户在使用它时通常不再需要大量的内存分配操作;而Parse-Handler模型中,Handler类的实现者出现蹩脚的设计可能性非常高,计入Handler类的内存开销的话,有时甚至可能远远超过采用DOM模型。 因此我个人认为相对于DOM的能力而言,内存问题在DOM模型中并不算一个了不起的缺陷。实现者可以有很多技巧来进行内存优化。 但是DOM模型有一个问题,就是它一开始就将文档完整的读入了内存,使得它无法胜任那些对响应时间要求较高、希望能够渐进处理的应用。而这一点是采用Parse-Handler模型和Tokenizer模型的好处。 后记 这篇文章写得比较早,因为最近写 WINX可视化开发工具 相关的设计稿时用到,所以整理了下。我个人在文本文件和各种文档格式的文件打交道较多,多年来也算是形成了一定的经验。我个人现在越来越倾向于采用DOM模型来处理文件。原因在于采用DOM模型有很多优点:
|
文本分析的三种典型设计模式
最新推荐文章于 2024-07-02 22:50:37 发布