在浏览器的背后(二) —— HTML语言的语法解析
当你看到这篇文章意味着我辜负了@教主的殷切期望周末木有去约会,以及苏老师@我思故我在北京鼓楼的落井下石成功了……
本文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语言的语法解析相关推荐
- eFPGA设计开源框架 FABulous 系列(二)Fabric建模语法解析
我是 雪天鱼,一名FPGA爱好者,研究方向是FPGA架构探索. 关注公众号[集成电路设计教程],拉你进"IC设计交流群". 通过 FABulous 所提供的唯一一个 demo 来学 ...
- go语言ast语法解析
通过Demo来了解语法解析的过程 了解 ast 语法解析,我们先从一个简单的 demo 开始,正向看看 ast 解析代码的过程,过程虽然不复杂,但是特别繁琐. 看下面的代码,真实的环境中 32 行的 ...
- Go语言 基础语法学习 (未完待更......
文章目录 一 Go语言结构 1 Go Hello world实例 2 执行Go程序 二 Go语言基础语法 1 Go标记 2 行分隔符 3 注释 4 标识符 5 一些关键字 6 Go语言的空格 7 格式 ...
- 用 C 语言开发一门编程语言 — 语法解析器
目录 文章目录 目录 前文列表 编程语言的本质 词法分析 语法分析 使用 MPC 解析器组合库 安装 快速入门 实现波兰表达式的语法解析 波兰表达式 正则表达式 代码实现 前文列表 <用 C 语 ...
- 服务计算作业二——GO语言TDD实践报告
服务计算作业二--GO语言TDD实践报告 服务计算作业二--GO语言TDD实践报告 教程学习 为一个重复字符五次的函数编写测试,并先使用最少的代码让失败的测试先跑起来(核心概念) 把代码补充完整,使得 ...
- Firefox ios 火狐浏览器iOS版本二次开发(二)
Firefox ios 火狐浏览器iOS版本二次开发(二) 编译 Firefox ios源代码下载地址: Firefox CSDN下载地址 Firefox ios版本采用的是swift语言来进行开发的 ...
- matlab语言实验二,实验二 MATLAB语言基础
实验二 MATLAB 语言基础 一.实验目的 基本掌握 MATLAB 向量.矩阵.数组的生成及其基本运算(区分数组运算和矩阵运算).常用的数学函数.了解字符串的操作. 二.实验内容 (1) 向量的生成 ...
- C语言文件操作解析(二)【转载】
http://www.cnblogs.com/dolphin0520/archive/2011/10/05/2199598.html C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件, ...
- C语言文件操作解析(二)
C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件,打开文件主要涉及到fopen函数.fopen函数的原型为 FILE* fopen(const char *path,const cha ...
最新文章
- 什么?听说这四个概念,很多 Java 老手都说不清!
- 皮一皮:夏天来了,蚊子叫了...
- python str byte编码_Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题...
- stl string的erase方法
- C++对象内存模型学习
- 第06课:动手实战基于 ML 的中文短文本分类
- SAP UI5 xml view content parse
- android自动登录不过登陆界面,【教程】Android 记住密码和自动登录界面的实现
- 初学者怎样看懂python代码_入门编程(初学者怎样看懂代码)
- 个位数统计(java)
- 游戏卡牌半小时拍出8700万天价,法院紧急叫停!
- 【统一异常处理】@ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常
- SQL Pass北京举办第六次线下活动,欢迎报名
- 奥维kml文件制作工具_如何将平面控制点导入Google Earth、奥维互动地图及手机奥维互动地图APP里面?...
- Bcm96xx 系列芯片 SDK介绍(一)
- 水晶报表导出PDF or Excel,并返回文件到用户的IE浏览器中
- Markdown——图片、文字显示居中的一种方法
- 全美航班停飞原因曝光/ 米哈游辟谣年终奖108薪/ 苹果正开发触摸屏Mac…今日更多新鲜事在此...
- Android 屏幕适配方案(七)
- 什么是分布式系统!以及分布式系统架构的优缺点
热门文章
- LIVE555再学习 -- FFmpeg + live555实现RTSP直播
- Java Graphics2D类的绘图方法
- CVE-2017-8890漏洞分析与利用(Root Android 7.x)
- Google Project Zero挖洞经验整理
- Android6.0源码分析—— Zygote进程分析(补充)
- java在记事本找不到_好烦,用记事本练习JDBC总是找不到类
- linux镜像文件不要大于4g,Systemback制作大于4G的Ubuntu系统镜像
- androidstudio sqlite where 条件_SQL 面试题:WHERE 和 HAVING、ON 有什么区别?
- ai算子是什么_肇观电子刷新端侧AI芯片性能记录并发布“5分钟部署”AI开发平台 - 企业资讯...
- 移动端网页打印代码_WEB移动端怎么是实现Console.log打印