动手写的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)

posted on 2012-03-06 15:47 lzhenf 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lzhenf/archive/2012/03/06/2382056.html

动手写的Python的HTML语法分析器(面向对象)相关推荐

  1. 老用别人的库?今天手把手教你动手写一个Python库,真香!

    引子 学习编程以来,接触过Basic,C/C++,Swift,JavaScript和Python五种语言,其中最爱的当属Python,简洁的语法和丰富的库让我一直沉迷于此,尽管最近实习工作中用的是C+ ...

  2. 编译器入门 语法分析器 java_从零开始写个编译器吧 - Parser 语法分析器

    Parser(语法分析器)的编写相对于 Tokenizer (词法分析器)要复杂得多,因此,在编写之前可能也会铺垫得更多一些.当然,本系列旨在"写出"一个编译器,所以理论方面只会简 ...

  3. 【转】Vczh Library++3.0之可配置语法分析器(前言)

    从网上无意间看到这个系列的文章,作者非常有想法,转下来慢慢研究,好好学习. 祝大家学习愉快,做自己的爱好 ^_^ ! 花了差不多两个星期的时间将一个可配置语法分析器(Combinator)写好了.这个 ...

  4. 自制编译器:语法分析器(二)

    这篇博文拖了好久才写完,其一是语法分析器本身的难度实在有点超出我的预料,以至于反复重构多次才完成,其二是因为弄了个xbox玩,占用了一部分的课余时间= =!. 本篇博文将分为以下几个部分来描述一下语法 ...

  5. 小白天堂之编写词法语法分析器何其简单(一)

    写小白天堂系列的文章算是从这一篇开始吧,但是写这个词法语法分析器实在是因为编译原理老师扣啊,哎,没办法,只能直接写代码,当时正好将Javascript的语法基本撸了一边,所以就决定写一个JS的词法语法 ...

  6. 从0开始的python学习:编译原理实验4:语法分析器1--预测分析器构造

    这里刚开始试用python的函数功能,可能把局部变量和全局变量给写乱了,后期交之前还想再优化的时候发现越改越乱,太真实的hhh 实验四:语法分析器1–预测分析器构造 实验目的: 通过编写一个预测分析器 ...

  7. 自己动手开发编译器(十)miniSharp语法分析器

    经过前面四篇的铺垫,我们终于拥有了编写语法分析器的强大工具,现在可以正式开发一门编程语言的语法分析器了.我们先来定义miniSharp的语法规则,然后根据LL文法的特点进行一些调整,最后借助解析器组合 ...

  8. lr1分析器c语言实验报告怎么写,编译原理课程的设计构造LR分析法语法分析器.doc...

    编译原理课程的设计构造LR分析法语法分析器 太 原 学 院 课程设计报告书 课程名称 设计题目 构造LR(0)分析法语法分析器 专业班级 学 号 姓 名 指导教师 2016年 12 月 15日 目 录 ...

  9. 基于Python实现的类Pascal语言的词法分析和语法分析器

    类Pascal语言的语法分析器 功能 使用Python实现的类Pascal语言的词法分析和语法分析器. 语法分析实现的功能有: 利用文法推导式构造LR(1)分析表 使用LR(1)分析表对输入的Toke ...

最新文章

  1. Automatic Judge 模拟
  2. jhipster 配置 mysql_java – 将jhipster后端和前端分成两个项目?
  3. Pytorch中 .numpy() .item() .cpu() 区别
  4. java开发工作经历_开发人员在寻找第二份工作时会经历什么
  5. 关系查询处理 查询优化 论文_论文导读基于查询负载的分布式RDF图分割和分配...
  6. 布鲁斯的秘密-序章:我是布鲁斯
  7. PHP报错:Invalid body indentation level (expecting an indentation level of at least 4)
  8. 【物理应用】基于matlab粒子群配电网重构【含Matlab源码 764期】
  9. 短期通过PMP考试?
  10. IP地址规划的重要性
  11. 多个html合并一个PDF,如何将多个网页合并成一个PDF文件
  12. 服务器共享文件夹给广域网,广域网文件共享服务器
  13. 前世回眸,今生结缘,滚滚红尘,谁人可依
  14. HTML小案例-使用CSS3实现网页加载loding动画
  15. Google SEO和SEM的不同之处?
  16. 【基于时间特征交互和引导细化的遥感变化检测 】2022TGRS
  17. WPS 宣布将推出“WPS AI”
  18. OpenGL/C++实战——C++实现太阳系行星系统
  19. 单向可控硅和双向可控硅的详细介绍(含引脚的分辨)
  20. 中国的程序员为何经常被叫做码农?

热门文章

  1. Kubernetes系列之Helm介绍篇
  2. Javascript系列——对象元素的数组去重实现
  3. SSM+Netty项目结合思路
  4. Docker新手入门:基本用法
  5. iOS8 【xcode6中添加pch全局引用文件】
  6. spring+mybatis实现读写分离
  7. 产品经理应该干些啥?
  8. List接口常用实现类的特点和底层实现
  9. [SCOI2012]滑雪 (最小生成树 Kruskal)
  10. Actor模型(分布式编程)