动手写的Python的HTML语法分析器(面向对象)
主要包括4个文件,util.py文件主要负责截取每个块。
rules.py文件定义两个类,超类Rule和分别对应的子类,子类定义了不同的划分块的要求,子类包换action函数,调用handler处理
handlers.py定义了处理类,超类定义了方法,子类通过名字调用
markup.py定义了超类parser,定义了子类basicTextParser,超类主要负责创造过滤器,添加规则,对每个块执行处理。
#handler.py# -*- coding: cp936 -*-class Handler:""" 处理从parser调用的方法对象 这个解析器会在每个块的开始部分调用start()和end()方法,使用合适的块名作为参数。sub()会用于 正则表达式替换中,当使用了'emphasis'这样的名字调用时,它会返回核实的替换函数"""def callback(self,prefix,name , *args): method = getattr(self , prefix + name , None)if callable(method):return method(*args)def start(self ,name): self.callback('start_',name)def end(self,name): self.callback('end_' ,name)def sub(self,name):def substitution(match): result = self.callback('sub_', name,match)if result is None: result = match.group(1)return resultreturn substitutionclass HTMLRenderer(Handler):""" 用于生成HTML的具体处理程序 类中所有的方法都可以通过超类处理程序的START()、end()、sub()方法来访问,他们实现了HTML的基本标签"""def start_document(self):print '<html><head><title>...</title></head><body>'def end_document(self):print '</body></html>'def start_paragraph(self):print '<p>'def end_paragraph(self):print '</p>'def start_heading(self):print '<h2>'def end_heading(self):print '<h2>'def start_list(self):print '<ul>'def end_list(self):print '</ul>'def start_listitem(self):print '<li>'def end_listitem(self):print '</li>'def start_title(self):print '<h1>'def end_title(self):print '</h1>'def sub_emphasis(self,match):return '<em>%s<em>' % match.group(1)def sub_url(self ,match):return '<a href="%s">%s</a>' % (match.group(1),match.group(1))def sub_mail(self,match):return '<a href="mailto:%s">%s</a>' % (match.group(1),match.group(1))def feed(self,data):print data
# -*- coding: cp936 -*-#rules.pyclass Rule:"""所有规则的基类"""def action(self,block ,handler): handler.start(self.type) handler.feed(block) handler.end(self.type)return True class HeadingRule(Rule):""" 标题占一行,且标题的数目不大于70个字符,且最后不能以冒号结尾""" type = 'heading'def condition(self,block):return not '\n' in block and len(block)<=70 and not block[-1]==':' class TitleRule(HeadingRule):""" 题目是文档的第一个块,前提他是大标题""" type = 'title' first= True def condition(self,block):if not self.first:return False self.first = Falsereturn HeadingRule.condition(self, block) class ListItemRule(Rule): type ='listitem' def condition(self,block):return block[0]=='-'def action(self,block,handler): handler.start(self.type) handler.feed(block[1:].strip()) handler.end(self.type)return Trueclass ListRule(ListItemRule): type = 'list' inside = Falsedef condition(self,block):return Truedef action(self,block,handler):if not self.inside and ListItemRule.condition(self, block): handler.start(self.type) self.inside=Trueelif self.inside and not ListItemRule.condition(self, block): handler.end(self.type) self.inside=Falsereturn False class ParagraphRule(Rule): type ='paragraph'def condition(self,block):return True
#util.pydef lines(file):for line in file:yield lineyield '\n' def blocks(file): block =[]for line in lines(file):if line.strip(): block.append(line)elif block:yield ''.join(block).strip() block=[]
#markup.pyimport sys , re from handlers import *from util import *from rules import * class Parser:""" the processer of this , read data ,then use rule , and control to process data block"""#initial def __init__(self,handler): self.handler = handler self.rules =[] self.filters =[]#addrule to the Parser def addRule(self,rule): self.rules.append(rule)#add filter to the Parser def addFilters(self,patten,name):def filter(block , handler):return re.sub(patten,handler.sub(name),block) self.filters.append(filter)def parse(self,file): self.handler.start('document')for block in blocks(file):for filter in self.filters: block = filter(block , self.handler)for rule in self.rules:if rule.condition(block): last = rule.action(block,self.handler)if last:break self.handler.end('document') class BasicTextParser(Parser):def __init__(self,hanler): Parser.__init__(self,handler) self.addRule(ListRule()) self.addRule(ListItemRule()) self.addRule(TitleRule()) self.addRule(HeadingRule()) self.addRule(ParagraphRule()) self.addFilters(r'\*(.+?)\*', 'emphasis') self.addFilters(r'(http://[\.a-zA-z/]+)', 'url') self.addFilters(r'([\.a-zA-Z/]+@[\.a-zA-z]+[a-zA-Z]+)', 'mail') handler = HTMLRenderer()parser = BasicTextParser(handler)f= open(r'D://python27/input.txt')parser.parse(f)
转载于:https://www.cnblogs.com/lzhenf/archive/2012/03/06/2382056.html
动手写的Python的HTML语法分析器(面向对象)相关推荐
- 老用别人的库?今天手把手教你动手写一个Python库,真香!
引子 学习编程以来,接触过Basic,C/C++,Swift,JavaScript和Python五种语言,其中最爱的当属Python,简洁的语法和丰富的库让我一直沉迷于此,尽管最近实习工作中用的是C+ ...
- 编译器入门 语法分析器 java_从零开始写个编译器吧 - Parser 语法分析器
Parser(语法分析器)的编写相对于 Tokenizer (词法分析器)要复杂得多,因此,在编写之前可能也会铺垫得更多一些.当然,本系列旨在"写出"一个编译器,所以理论方面只会简 ...
- 【转】Vczh Library++3.0之可配置语法分析器(前言)
从网上无意间看到这个系列的文章,作者非常有想法,转下来慢慢研究,好好学习. 祝大家学习愉快,做自己的爱好 ^_^ ! 花了差不多两个星期的时间将一个可配置语法分析器(Combinator)写好了.这个 ...
- 自制编译器:语法分析器(二)
这篇博文拖了好久才写完,其一是语法分析器本身的难度实在有点超出我的预料,以至于反复重构多次才完成,其二是因为弄了个xbox玩,占用了一部分的课余时间= =!. 本篇博文将分为以下几个部分来描述一下语法 ...
- 小白天堂之编写词法语法分析器何其简单(一)
写小白天堂系列的文章算是从这一篇开始吧,但是写这个词法语法分析器实在是因为编译原理老师扣啊,哎,没办法,只能直接写代码,当时正好将Javascript的语法基本撸了一边,所以就决定写一个JS的词法语法 ...
- 从0开始的python学习:编译原理实验4:语法分析器1--预测分析器构造
这里刚开始试用python的函数功能,可能把局部变量和全局变量给写乱了,后期交之前还想再优化的时候发现越改越乱,太真实的hhh 实验四:语法分析器1–预测分析器构造 实验目的: 通过编写一个预测分析器 ...
- 自己动手开发编译器(十)miniSharp语法分析器
经过前面四篇的铺垫,我们终于拥有了编写语法分析器的强大工具,现在可以正式开发一门编程语言的语法分析器了.我们先来定义miniSharp的语法规则,然后根据LL文法的特点进行一些调整,最后借助解析器组合 ...
- lr1分析器c语言实验报告怎么写,编译原理课程的设计构造LR分析法语法分析器.doc...
编译原理课程的设计构造LR分析法语法分析器 太 原 学 院 课程设计报告书 课程名称 设计题目 构造LR(0)分析法语法分析器 专业班级 学 号 姓 名 指导教师 2016年 12 月 15日 目 录 ...
- 基于Python实现的类Pascal语言的词法分析和语法分析器
类Pascal语言的语法分析器 功能 使用Python实现的类Pascal语言的词法分析和语法分析器. 语法分析实现的功能有: 利用文法推导式构造LR(1)分析表 使用LR(1)分析表对输入的Toke ...
最新文章
- Automatic Judge 模拟
- jhipster 配置 mysql_java – 将jhipster后端和前端分成两个项目?
- Pytorch中 .numpy() .item() .cpu() 区别
- java开发工作经历_开发人员在寻找第二份工作时会经历什么
- 关系查询处理 查询优化 论文_论文导读基于查询负载的分布式RDF图分割和分配...
- 布鲁斯的秘密-序章:我是布鲁斯
- PHP报错:Invalid body indentation level (expecting an indentation level of at least 4)
- 【物理应用】基于matlab粒子群配电网重构【含Matlab源码 764期】
- 短期通过PMP考试?
- IP地址规划的重要性
- 多个html合并一个PDF,如何将多个网页合并成一个PDF文件
- 服务器共享文件夹给广域网,广域网文件共享服务器
- 前世回眸,今生结缘,滚滚红尘,谁人可依
- HTML小案例-使用CSS3实现网页加载loding动画
- Google SEO和SEM的不同之处?
- 【基于时间特征交互和引导细化的遥感变化检测 】2022TGRS
- WPS 宣布将推出“WPS AI”
- OpenGL/C++实战——C++实现太阳系行星系统
- 单向可控硅和双向可控硅的详细介绍(含引脚的分辨)
- 中国的程序员为何经常被叫做码农?