parser如何愉快地写个小parser

parser  时间:2021-05-28  阅读:()

htmlparser是怎么个用法..

HTMLParser具有小巧,快速的优点,缺点是相关文档比较少(英文的也少),很多功能需要自己摸索。

对于初学者还是要费一些功夫的,而一旦上手以后,会发现HTMLParser的结构设计很巧妙,非常实用,基本你的各种需求都可以满足。

  这里我根据自己这几个月来的经验,写了一点入门的东西,希望能对新学习HTMLParser的朋友们有所帮助。

(不过当年高考本人语文只比及格高一分,所以文法方面的问题还希望大家多多担待)   HTMLParser的核心模块.htmlparser.Parser类,这个类实际完成了对于HTML页面的分析工作。

这个类有下面几个构造函数:   public Parser ();   public Parser (Lexer lexer, ParserFeedback fb);   public Parser (URLConnection connection, ParserFeedback fb) throws ParserException;   public Parser (String resource, ParserFeedback feedback) throws ParserException;   public Parser (String resource) throws ParserException;   public Parser (Lexer lexer);   public Parser (URLConnection connection) throws ParserException;   和一个静态类public static Parser createParser (String html, String charset);   对于大多数使用者来说,使用最多的是通过一个URLConnection或者一个保存有网页内容的字符串来初始化Parser,或者使用静态函数来生成一个Parser对象。

ParserFeedback的代码很简单,是针对调试和跟踪分析过程的,一般不需要改变。

而使用Lexer则是一个相对比较高级的话题,放到以后再讨论吧。

  这里比较有趣的一点是,如果需要设置页面的编码方式的话,不使用Lexer就只有静态函数一个方法了。

对于大多数中文页面来说,好像这是应该用得比较多的一个方法。

安卓手机 parsererror怎么解决

你好,这个刷机可以解决, 你先打开手机的usb调试,把手机连接到电脑上 然后打开应用宝,在打开工具箱 它里面有几款不错的刷机工具,比如甜椒刷机,刷机精灵等 但是刷机有风险,刷机之前一定要先手机双清一下。

如何愉快地写个小parser

如何愉快地写个小parser 在前几日的文章『软件随想录』里,我随性写了一句:「现在似乎已经不是lex/ 或 bison/flex的时代了。

我亲眼看见一个同事在费力地用perl一行行解析某个系统的数据文件,却压根没想到写个BNF。

BNF对他来说,不是一种选择。

」 很多同学不解,问我:lex/不是写编译器 [1] 的么?我又不发明新的语言,它们对我有什么用? 从这个问题里,我们可以见到国内本科教育荼毒之深。

象牙塔里的讲编译原理的老师们,估计用lex/也就是写过个毫无用处的toy language,然后把自己的一知半解传递给了他们的学生,学生们学得半通不通,兴趣索然,考完试之后便把死记硬背的内容如数奉还给了老师。

别笑,我还真就是这么过来的。

我用lex/干的唯一一件事,就是TMD设计一个语言。

这世间的语言如此之多,实在容不下我等庸人再设计一门蹩脚的,捉急的,没有颜值,没有性能的语言。

况且2000年左右的时候还没有LLVM这种神器,也没有github这样的冥想盆去「偷」别人的思想,设计出来的蹩脚语言只能到语法分析这一步就停下来,没有任何实际用处。

后来lex/进化成flex/bison,在工作中我也无意中翻看了一本orelley叫『Flex & Bison』的书,这书的副标题赫然写着:text processing tools。

书的内容还是挺教条的,和实际的工作内容略微脱节,可text processing tools这个说法戳中了我:是啊,词法分析 - lexical parsing(lex/flex),语法分析 - grammar parsing(/bison)只是更好的文本处理工具(parser),是个高效处理带有语法的文本的DSL(Domain Specific Language)!它们和编译器没有半毛钱关系,只不过,它们的某一个应用场景是和编译器有关罢了。

我们不必将其想得过于高深! 我们想想文本处理有什么工具? Regular expression! 如今的编程语言,有哪个不支持regular expression呢?同样的,如今的程序员,哪个不用使用(没在代码里使用)regular expression呢? Regular expression也是一种文本处理工具,也是个DSL,只不过,它处理不了复杂的语法。

我们知道,自动化理论(automata theory)里,有FSA(Finite State Automata)和PDA(PushDown Automata),前者可以用regular expression表述,而后者可以处理CFG(Context Free Grammar)。

而CFG便是flex/bison要处理的对象! 遗憾的是,大部分语言都没有内置对CFG的处理,一旦文本处理的复杂度超过了regular expression可以表述的复杂度,我们便无能为力。

举个例子,如果要你解析这样一段文本,你该怎么做? 用regular expression自然是无能为力的,一个字符一个字符读入,按单词切分token,然后处理大括号,分号这样的语法,你相当于自己写了个解析器,很难保证高效和可扩展。

所以这种时候我们需要求助于第三方的flex/bison,或者类似的工具。

flex是lex演进过来的,做词法分析。

所谓的词法分析,说白了就是把文本切成一个个你认识的语法单元,比如上图里,server 就是这样一个语法单元,我们管这个单元叫token。

在flex里,我们可以这样描述上面文本里出现的token: 接下来就是语法分析的环节了。

语法分析做的是pattern matching的事情,和regular expression的pattern matching不同,它允许你定义一系列可递归的规则。

标准的unix下,语法分析的工具是bison,我们看看上述文本如何使用bison解析: 其主体代码还是很清晰的,一个 server {…} 就用 SERVER OP({) exp_list CP(}) 这样一条规则匹配,当解析器碰到 exp_list 这样一个它无法认识的内容时,它会寻找名为 exp_list 的规则继续匹配。

如果你经常使用函数式编程语言,你会发现,这种规则的撰写似曾相识。

bison使用的描述规则的语法是BNF的变体。

以下是编译和执行的结果,作为展示,我仅仅把语法树中我感兴趣的内容打印出来了: 从上面的编译过程里,你可以看到,flex/bison是一个C语言的DSL。

因此,你可以在处理词法和语法的过程中嵌入C代码,处理(transform)你需要的结果。

DSL和宿主语言之间必然要有一些约定俗成的接口,这也是 yytext,yyparser,yyterminate,yylex 等等变量和方法存在的原因。

它们看起来很奇怪,但如果你以一颗看待DSL的心去看待它们,变不那么别扭了。

(二) 可惜,如今大部分文艺青年都已经不用C了 —— 虽说很多语言都提供了对C的FFI(Foreign Function Interface),比如Python,你可以用flex/bison生成一个parser,然后用FFI包装。

然而,这毕竟很麻烦,如果我能用我喜爱的语言做parser,该多方便? 嗯,有需求的地方便有产品,看这个wiki page吧:/wiki/Comparison_of_parser_generators。

我具体讲讲四个有趣的工具。

首先是clojure下的神器instaparse。

instaparse是那种如果让你做个parser,不限定语言,那你一定要尝试使用的工具。

别的工具一天能做出来的效果,instaparse一小时就能搞定。

我们看个例子: 我们想parse满足一定规则的form,form {…},form可以有subform,每行一个规则,每个规则是 key=value [validator],validator是可选的,比如用 [] 括起来的是choices,用 () 括起来的是range。

通过这个form,我们可以生成两种数据,一种是form的schema,另一种是form的data。

所以关键的是,我们如何从form数据里解析出合适的数据结构,为生成schema和data做准备。

从上图里看到,使用instaparse,仅仅18行代码,我们就可以完成lexer/parser的定义。

instaparse支持EBNF/ABNF语法,可以很轻松地在生成的语法树中隐藏不需要的节点(注意 <> 的部分)。

我们看生成的结果: beautiful! clojure处理(transform)数据的能力非常强大,这样一棵树,可以很轻松地转换成一个DOM树(up),然后生成html的form。





在instaparse里,写一个parser变成了三个简单的步骤: 使用BNF定义语法 隐藏不需要的语法节点 transform生成的语法数 你也可以轻松visualize一棵树(节选了task部分): instaparse的强大之处不仅仅在于简单的语法,还在于你可以使用REPL来调试你的代码!用REPL来调试你的代码!用REPL来调试你的代码!当你使用flex/bison在make和editor之间来回切换,郁闷地寻找语法定义问题的时候,你就知道一个REPL是多么地重要了! 当然,在我的读者里,目测clojure程序员相当稀有,所以,绝大多数人只能看着instaparse眼馋。

好吧,接下来我们讲讲jison。

我想你应该猜到了,这货是javascript bison,bison在javascript上的变态。

先来个解析SQL里的 create table 的例子。

我们想实现这样的效果: 我们需要的是,如何把 create table 语法变换成一个数据结构,通过这个数据结构我可以很方便地生成一个html table。

嗯,实现这个只需要写一个jison的语法文件(和flex/bison相似),然后用jison编译即可: (仅包含了语法分析部分,略过了词法分析) (在nodejs下运行) (在chrome里运行) 很简单有木有。

这里我生成的解析树就是一个javascript object。

然后我拿着这个object可以进一步生成一个如上图所示的table。

用javascript/jison做parser有什么好处呢?你可以在浏览器端做复杂的input validation,你可以允许用户输入符合你定义的语法的文本,然后生成想要的东西,比如思维导图,或者这个项目:/bramp/js-sequence-diagrams。

如果你想定义一门语言生成javascript(我不建议你干这个),可以参考coffeescript,它 也使用了jison。

接下来我们讲一下另一个神器 antlr4。

我也是在撰写这篇文章的时候才接触antlr4,还在第一次亲密接触中。

除去解析器设计方面的与众不同 - LL(*) - antlr4对我而言,有三个强大的地方: 各种现成的语法定义(基本都是MIT/BSD license,跪拜吧,少年!)。

打开这个repo:/antlr/grammars-v4, 有没有想哭的赶脚? 生成主流程序语言的parser。

嗯,你可以对着g4语法文件轻松生成python,javascript等的源码,然后集成到你自己的项目里。

继续哭吧。

SAX-like event driven。

antlr4直接替你生成好了复杂的语法树 - 一般而言,antlr4生成的语法树没有使用instaparse/bison等生成的那么清爽,所以直接处理起来有些费劲,antlr4的创新之处在于:我先帮你生成好树,然后你可以随意遍历。

就像SAX处理XML那样,每条规则(可以类比XML的每个Node)你都可以设置enter listener和exit listener,你把callback注册在你关心的节点上,antlr4会把上下文交给你处理。

比如说为SQlite的语法生成javascript的lexer/parser,然后撰写一个简单的index.js调用: 调用结果(解析树): 由于antlr4有大部分的语言的语法定义,你可以把精力花在transform上而不是语法定义上。

比如老板说:小明啊,把我司codebase里面所有超过100行的,里面没有一行注释的函数给我找出来,我要审审这帮不写注释的孙子。

这种以前看上去无解的恶心需求,现在可能只需要一天就能搞定了: 假如代码是python3,找到python3的g4 file,用antlr4生成lexer/parser listen每个 def 规则,统计里面的有效代码数(不含空行),和注释数,如果注释为0,代码数超过100,把函数名和文件名,起始/结束行号记下来,然后用 git blame 找到作者,生成一个csv文件。

用excel打开这个csv,调整一下格式,通知里面出现的认识的每一个小伙伴和名字看上去像中文名字的人,让其把各自的代码赶紧加上注释,从名单里剔除(嘿嘿),然后聚合出 10 大坏蛋,饼图,柱状图什么的作为「表哥/表姐」的你随意 把excel文件发给老板 嗯,接受小伙伴的祝福,如果对方要请吃晚餐的话,不要拒绝,尤其是妹子(汉子)的。

:) 好了,最后一个,parsec。

parsec是个神器。

一个我没用过但是要BB一下的Haskell下的神器。

Haskell是门学了要走火入魔的语言,你看练斗转星移的慕容复在复国的路上可悲地疯了,练乾坤大挪移的张教主在革命的路上想不清楚选那个美人可耻地匿了就可以看出,如果满脑子里都装着position,最会不可避免地看起来像精神病(大智若愚)。

上文所述的parser其实都是parser generator,generate出来的代码都是不pose的,你写一个SQL parser,不能说先写一个select的parser,然后再写一个create table的parser,把两pose起来,就是支持select和create的parser。

你无法这么做。

但parsec可以。

在parsec里,你可以从一个很细力度的parser写起,一路将pose成一个非常复杂的parser。

当然,parsec已经替你完成了很多parser,你只需要定义一些新的,然后把他们和已有pose起来就好。

这便是parsec所谓的 "A monadic binator" 的意思。

究竟神马是monad?这是个好问题,我们先放下不表,以后的文章再讲。

(三) 这篇文章并未告诉你LALR(1),LL(1),LL(*)等概念,没有具体解释lexical parser,grammar parser的详细步骤,虽然举了一些BNF(及其变体)的例子,也没有触及如何撰写BNF。

这些内容很重要,但在你写一个parser之前,都是不打紧的内容。

你需要知道的是,除了regular expression,你还有其他的工具处理更为复杂的带格式的文本。

你应该了解了parser可能的一些应用场景,你也看到了一些主要的工具是怎么使用的,有什么优缺点。

你不必立刻放下手边的活去学习这些工具 —— 最好的学习方法之一是 learning by practising 而不是 learning by reading a book (manual)。

下次老板让你做点和文本处理相关的任务,你要记得,除了regular expression,你还有一些可以处理更复杂问题的工具!不要怕,接下这个任务,相信deadline的威力足以把你从做parser的小白变成一个大白。

还有,下次如果你觉得markdown的语法缺点什么,想加些更丰富的内容进去,你大概知道该怎么做,可以用什么工具去做了。

快云科技,美国VPS 2H5G独享20M 仅售19.8/月  年付仅需148

快云科技已稳步运行进两年了 期间没出现过线路不稳 客户不满意等一系列问题 本司资质齐全 持有IDC ICP ISP等正规手续 有独特的网站设计理念 在前几天刚是参加过魔方系统举行的设计大赛拿获最佳设计奖第一名 本公司主营产品 香港弹性云服务器,美国vps和日本vps,香港物理机,国内高防物理机以及美国日本高防物理机 2020年的国庆推出过一款香港的回馈用户特惠机 已作为传家宝 稳定运行 马上又到了...

百纵科技:美国独立服务器租用/高配置;E52670/32G内存/512G SSD/4IP/50M带宽,999元/月

百纵科技怎么样?百纵科技国人商家,ISP ICP 电信增值许可证的正规公司,近期上线美国C3机房洛杉矶独立服务器,大带宽/高配置多ip站群服务器。百纵科技拥有专业技术售后团队,机器支持自动化,自助安装系统 重启,开机交付时间 30分钟内交付!美国洛杉矶高防服务器配置特点: 硬件配置高 线路稳定 洛杉矶C3机房等级T4 平价销售,支持免费测试,美国独服适合做站,满意付款。点击进入:百纵科技官方网站地...

硅云香港CN2+BGP云主机仅188元/年起(香港云服务器专区)

硅云怎么样?硅云是一家专业的云服务商,硅云的主营产品包括域名和服务器,其中香港云服务器、香港云虚拟主机是非常受欢迎的产品。硅云香港可用区接入了中国电信CN2 GIA、中国联通直连、中国移动直连、HGC、NTT、COGENT、PCCW在内的数十家优质的全球顶级运营商,是为数不多的多线香港云服务商之一。目前,硅云香港云服务器,CN2+BGP线路,1核1G香港云主机仅188元/年起,域名无需备案,支持个...

parser为你推荐
linux开放8080端口linux系统,tomcat 8080端口,本机访问没问题,远程访问失败,华为云服务登录电脑版华为账户必须要华为手机登入吗?国外手机号求个美国手机号码 麻烦了 万分感激搭建服务器教程内网搭建服务器详细步骤?cdn的作用CDN制作的用途是什么香港亚马逊官网网址亚马逊卖家后台的登录网址是多少?io域名注册io 域名怎么样服务器网速测试如何测试服务器网速好看的div样式几种常见的DIV边框样式cdn能防ddos吗云主机可以防DDOS攻击吗?
域名购买 中文域名申请 免费动态域名 krypt flashfxp怎么用 80vps yardvps godaddy主机 国内永久免费云服务器 mediafire下载 轻量 html空间 坐公交投2700元 hktv Updog 网站在线扫描 阿里云官方网站 帽子云排名 谷歌台湾 wordpress中文主题 更多