全部博文(584)
分类: LINUX
2010-11-11 11:33:01
1.4.1 确定要实现的基本功能
鉴于对浏览器开发难度的充分考虑,以及现有人员的水平,拟定实现以下功能,以及需要考虑但暂不予实现的功能。 需要实现的包括: (1) 界面:包括窗口,菜单,输入框,工具条,滚动条等的支持。 (2) 词法分析:必须实现实用的HTML词法分析,支持HTML4.0全部元素。 (3) 实现简单网页的布局:实现对简单网页的查看。 (4) 支持基本IO,支持采用线程的网络传输。 需要考虑的功能: (1) JavaScript支持 (2) 汉字支持 (3) 图片格式支持 (4) 表单支持 (5) 页面元素的消息响应 1.4.2 人员分工 由于情况的变动,造成了人员比较紧张,在前期准备工作中,人力充沛,使得收集的资料比较完备,打下了较好的基础。在后期简化了目标,虽然人员减少,但也能够实现主要的工作。考虑到网络是比较独立的部份,把它分出去由专人负责。 |
第二章 HTML词法分析器的设计及其应用
HTML词法分析是浏览器设计的基础环节之一,也是整个设计过程中重要的前端工作,其数据结构的拟定与接下来的语法分析和布局算法密切相关,词法分析的效率与准确性、容错性也关系到整个浏览器设计的质量。
下面将介绍一个HTML词法分析器——Bit Token的设计思路。
Bit Token是Netbit Browser的HTML词法分析器,使用标准C编程,Netbit Browser是基于Linux/Gtk的浏览器,开放源码项目,
2.1 Bit Token的组成及其功能
Bit Token作为Netbit Browser的词法分析部份,负责对接收的HTML代码进行词法分析,主要的目的是提取网页中元素的名称及其属性,并以恰当的形式(即按一定的数据结构)加以保存,也就是完成了将数据流离散化、结构化的过程。
主要由以下几个部分组成:
1、初始化:完成对数据结构的初始化,主要是分配内存,变量赋初值。
2、主体的数据流分析:逐字符的进行判断,确定数据的归属类型。
3、元素的分析:提取元素的名称、属性和值域。
4、释放:主要是对内存的释放。
2.2 数据结构
typedef struct BitTokenContext
{char * strBuffer; //当前正在处理的HTML代码
int bufferLength;
int curPosition;
char * global_strBuffer; //全局HTML代码
int global_bufferLength;
int global_curPosition;
BitTokenList *tokenList; //元素节点链表
BitTokenList *tokenList_tail;
BitPTagList pTagList; //元素名称表,指向静态数据
}BitTokenContext,*BitPTokenContext;
BitTokenContext是用于存储当前待分析网页全局属性的数据结构,其中TokenList是核心的元素节点链表。词法分析的目的就是生成这样一个链表。下面给出该链表的数据结构,是很简单的双向链表。
typedef struct TokenList
{ BitToken *token; //元素节点
struct TokenList *priou;
struct TokenList *next;
}BitTokenList,*BitPTokenList;
以下是元素节点的数据结构:
typedef struct BitToken
{int type; //节点类型,如定义的HTML_BODY,HTML_TXT等。
char *pData; //如果是HTML_TXT型元素,则为其内容,否则为空
BOOL end; //是否是结束元素,如
BitTokenAttrList *attrList; //元素属性链表,因为可能有多个属性,所以使用链表存储
BitTokenAttrList *attrList_tail;
}BitToken,*BitPToken;
请注意,以上出现tail标记的指针变量,如BitTokenList * tokenList_tail等,其作用是用于保存链表结尾节点指针,便于在释放内存时,直接找到链尾,提高了算法的效率。
2.3 算法
2.3.1 基本算法:
首先介绍基本的算法:
(1) 从存储网页的字符串中,顺序读入一个字符
(2) 如果遇到 < ,认为遇到TAG(元素),处理该元素,使用函数Token_ConsumTag(),处理完毕后,指针移到该元素尾。
(3) 如果遇到回车、空格,则跳过。
(4) 如果遇到 > ,则跳过(不应该出现此情况,为了容错)。
(5) 如果非以上情况,则认为遇到文字,处理这段文字,使用函数Token_Consum_PlainText()。处理完毕,指针指向下一个元素首。
(6) 循环以上操作,直到该网页分析完毕。
由此看来,主算法十分简单而清晰,主要是Token_ConsumTag()和Token_Consum_PlainText()这两个函数起关键作用,由于其中涉及到许多细节问题,此处不予详述。
2.3.2 算法效率与改进:
采用以上的基本算法,是可用的,但当网页比较大的时候,比如600K,该算法的效率成倍下降,这主要是由于要处理的字符串太大,在内存中完成查找、 替换、复制、移动等操作,响应时间明显下降。对此的改进办法就是分段进行词法分析,不仅极大的提高了效率(在某些情况下约提高30倍),也有利于浏览器整 体设计,因为当网页较大时,若等待全部内容传输完毕,再一次性完成词法分析和布局,用户会感到等待时间过长,一般现在成熟的浏览器都采用边传输,边分析, 边显示。
分段进行词法分析的算法复杂度明显增加,比如,当每段定为1024字节,在第1024字节处,可能正好将一个完整元素截断,按常规分析方法会造成错误。解决的办法是,采用回溯,确认要分析的部份至少包含1个完整元素。
具体做法是:判断1024字节处是否为元素结束字符 ‘>’,如果不是,则判断前一个字节,直到找到元素结束字符为止,这样可保证至少包含一个元素。
采用分段进行词法分析,实际每次分析的代码会不足1024字节,余下的部份汇入到下一段的分析过程即可,直到所有内容被分析完毕。
2.4词法分析的结果
下面是一段很简单的HTML代码。
分析后,数据存储结构如下
:
<img> |
<a> |
text |
a> |
src |
go.gif |
width |
200 |
height |
100 |
href |
|
data |
首都在线 |
可以看到,词法分析的结果是一个元素节点链表,每个节点的属性也形成了一个链表,元素节点是有先后顺序的,元素属性的先后顺序是无所谓的。
词法分析将网页的文本数据流以清晰的结构表现出来,这样,在后面的应用中就可以很容易的遍历各节点,并轻松地获得各元素节点的属性。
2.5 HTML词法分析的应用
2.5.1 应用举例:
HTML词法分析程序通常应用于浏览器设计、网页制作软件设计等领域,本人以一个使用VC开发的软件“HTML智能分析”来举例说明,下载网址:
。
“HTML智能分析”同样使用Bit Token词法分析器,“HTML智能分析”是一个网页信息提取、处理软件。
具有以下主要功能:
1、智能提取网页中的文字信息,智能排版,并可在进行编辑后保存。
2、统计网页的有关信息。
3、根据用户设置的版式,将分析和编辑的结果,自动生成新的网页。
用户可使用该软件来将HTML转为TXT格式,其对HTML中文字内容的提取准确、快速、不含冗余信息,版式工整清晰,保持本来面貌。
其主要设计思路是,在Bit Token词法分析器的基础上,结合浏览器布局的基本算法,对影响到TXT版面效果的元素进行处理。
比如
标记,代表所包含的内容浏览器应不予分析,按TXT格式输出,而如表格等元素则意味着需要换行。而 在HTML中,在无 这种特殊情况时,回车都是忽略不记的。这就造成了矛盾。使用常规的简单算法进行HTML到TXT的转换无法解决 这些问题。造成转换后的版式“失真“。而“HTML智能分析”却能很好的解决。
由于“HTML智能分析”使用了底层的词法分析技术,还可以很容易的过滤掉标记。目前的Bit Token由于开发时间所限,未对其加以特殊处理,存在一些问题,但由于浏览器对Javascript的支持是较复杂的工作,目前的Netbit Browser尚不予实现,因而没有导致明显问题,而“HTML智能分析”这个软件只是需要对Javascript进行删除操作,也不会造成影响。尽管如 此,对