当你看到这篇文章意味着我辜负了@教主的殷切期望周末木有去约会,以及苏老师@我思故我在北京鼓楼的落井下石成功了……

本文demo powered by 已经结婚的@老赵的不再维护的wind.js

物是人非啊……

说回正经事,在上一篇文章中,我们取得了初步成果,毫无意义的字符变成了有意义的token。

接下来我们要把这些简单的词变成DOM树,这个过程我们是使用栈来实现的,任何语言几乎都有栈,为了给大家跑着玩我们还是用JS来实现吧,JS中的栈只要用数组就好了:

function HTMLSyntaticalParser(){var stack = [new HTMLDocument];this.receiveInput = function(token) {//TODO}this.getOutput = function(){return stack[0];}
}

为了构建DOM树,我们需要一个Node类,接下来我们所有的节点都会是这个Node类的实例。在完全符合标准的浏览器中,不一样的HTML节点对应了不同的Node的子类,我们为了简化,就不完整实现这个继承体系了。我们仅仅把Node分为Element和Text(如果是基于类的OOP的话,我们需要抽象工厂来创建对象。)

function Element(){this.childNodes = [];}function Text(value){    this.value = value || "";}

前面我们的token中,以下两个是需要成对匹配的:

  • tag start
  • tag end

于是我们的做法是遇到tag start就入栈,遇到tag end就出栈,并且校验一下是否匹配。

对于Text节点,我们则需要把相邻的Text节点合并起来,我们的做法是当字符token入栈时检查栈顶是否是Text节点,如果是的话就合并Text节点

同样我们来看看直观的解析过程:

<html maaa=a > <head> <title>cool</title> </head> <body> <img src="a" /> </body> </html> parse

当我们的源代码完全遵循xhtml时,这非常简单问题,然而HTML具有很强的容错能力,奥妙在于当tag end跟栈顶的start tag不匹配的时候如何处理。

于是有一个极其复杂的规则来的,幸好w3c又一次很贴心地把全部规则都整理的很好,我们只要翻译成对应的伪代码就好了:

http://www.w3.org/html/wg/drafts/html/master/syntax.html#tree-construction

略微干净的代码可以在这个gist找到:

https://gist.github.com/wintercn/5618683#file-htmlsyntaticalparser-js

转载于:https://www.cnblogs.com/winter-cn/p/3141990.html

在浏览器的背后(二) —— HTML语言的语法解析相关推荐

  1. eFPGA设计开源框架 FABulous 系列(二)Fabric建模语法解析

    我是 雪天鱼,一名FPGA爱好者,研究方向是FPGA架构探索. 关注公众号[集成电路设计教程],拉你进"IC设计交流群". 通过 FABulous 所提供的唯一一个 demo 来学 ...

  2. go语言ast语法解析

    通过Demo来了解语法解析的过程 了解 ast 语法解析,我们先从一个简单的 demo 开始,正向看看 ast 解析代码的过程,过程虽然不复杂,但是特别繁琐. 看下面的代码,真实的环境中 32 行的 ...

  3. Go语言 基础语法学习 (未完待更......

    文章目录 一 Go语言结构 1 Go Hello world实例 2 执行Go程序 二 Go语言基础语法 1 Go标记 2 行分隔符 3 注释 4 标识符 5 一些关键字 6 Go语言的空格 7 格式 ...

  4. 用 C 语言开发一门编程语言 — 语法解析器

    目录 文章目录 目录 前文列表 编程语言的本质 词法分析 语法分析 使用 MPC 解析器组合库 安装 快速入门 实现波兰表达式的语法解析 波兰表达式 正则表达式 代码实现 前文列表 <用 C 语 ...

  5. 服务计算作业二——GO语言TDD实践报告

    服务计算作业二--GO语言TDD实践报告 服务计算作业二--GO语言TDD实践报告 教程学习 为一个重复字符五次的函数编写测试,并先使用最少的代码让失败的测试先跑起来(核心概念) 把代码补充完整,使得 ...

  6. Firefox ios 火狐浏览器iOS版本二次开发(二)

    Firefox ios 火狐浏览器iOS版本二次开发(二) 编译 Firefox ios源代码下载地址: Firefox CSDN下载地址 Firefox ios版本采用的是swift语言来进行开发的 ...

  7. matlab语言实验二,实验二 MATLAB语言基础

    实验二 MATLAB 语言基础 一.实验目的 基本掌握 MATLAB 向量.矩阵.数组的生成及其基本运算(区分数组运算和矩阵运算).常用的数学函数.了解字符串的操作. 二.实验内容 (1) 向量的生成 ...

  8. C语言文件操作解析(二)【转载】

    http://www.cnblogs.com/dolphin0520/archive/2011/10/05/2199598.html C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件, ...

  9. C语言文件操作解析(二)

    C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件,打开文件主要涉及到fopen函数.fopen函数的原型为 FILE* fopen(const char *path,const cha ...

最新文章

  1. 什么?听说这四个概念,很多 Java 老手都说不清!
  2. 皮一皮:夏天来了,蚊子叫了...
  3. python str byte编码_Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题...
  4. stl string的erase方法
  5. C++对象内存模型学习
  6. 第06课:动手实战基于 ML 的中文短文本分类
  7. SAP UI5 xml view content parse
  8. android自动登录不过登陆界面,【教程】Android 记住密码和自动登录界面的实现
  9. 初学者怎样看懂python代码_入门编程(初学者怎样看懂代码)
  10. 个位数统计(java)
  11. 游戏卡牌半小时拍出8700万天价,法院紧急叫停!
  12. 【统一异常处理】@ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常
  13. SQL Pass北京举办第六次线下活动,欢迎报名
  14. 奥维kml文件制作工具_如何将平面控制点导入Google Earth、奥维互动地图及手机奥维互动地图APP里面?...
  15. Bcm96xx 系列芯片 SDK介绍(一)
  16. 水晶报表导出PDF or Excel,并返回文件到用户的IE浏览器中
  17. Markdown——图片、文字显示居中的一种方法
  18. 全美航班停飞原因曝光/ 米哈游辟谣年终奖108薪/ 苹果正开发触摸屏Mac…今日更多新鲜事在此...
  19. Android 屏幕适配方案(七)
  20. 什么是分布式系统!以及分布式系统架构的优缺点

热门文章

  1. LIVE555再学习 -- FFmpeg + live555实现RTSP直播
  2. Java Graphics2D类的绘图方法
  3. CVE-2017-8890漏洞分析与利用(Root Android 7.x)
  4. Google Project Zero挖洞经验整理
  5. Android6.0源码分析—— Zygote进程分析(补充)
  6. java在记事本找不到_好烦,用记事本练习JDBC总是找不到类
  7. linux镜像文件不要大于4g,Systemback制作大于4G的Ubuntu系统镜像
  8. androidstudio sqlite where 条件_SQL 面试题:WHERE 和 HAVING、ON 有什么区别?
  9. ai算子是什么_肇观电子刷新端侧AI芯片性能记录并发布“5分钟部署”AI开发平台 - 企业资讯...
  10. 移动端网页打印代码_WEB移动端怎么是实现Console.log打印