这几天比较忙,让大家久等了。但是我语法分析篇还需要一些准备,所以今天带来一个特别娱乐项目。其实也正好想多举一些例子,介绍VBF.Compilers.Scanner库的使用方法。今天的问题来自于一道腾讯的PHP面试题,原题如下:

我们碰到了大麻烦,一个新来的传教士惹恼了上帝,上帝很愤怒,要求我们把圣经背熟,直至他说哪个单词,我们就要飞快的回答出这个单词在第几行第几个单词位置。听说你是个优秀的程序员,那么髟助我们完成这个不可能的任务吧。

要求如下:

1)/myworks/example/bbe.txt,98版本英文圣经一本

2)输入部分要求如下:php ./example.php [单词]

3)输出部分如下:[单词] 1,2 2,4 5,6表示:此单词在1行2列(第二个单词),2行4列...

说明:

1)此文本4MB之巨...

2)单词的含义:由英文字母(大小写),数字(0-9)组成的串

3)提供给你的机器OS为ubuntu 9.10,内存只有1G,而且,很不幸的,其中700M用来做了别的

4)上机考试不允许上网,但我装了man文档以及读取CHM以及PDF的阅读器,在电脑的桌面的CHM文件夹中,有相应的PHP参考手册

5)算法复杂度要求不能大于O(N^2)(就是N的平方)

6)什么?PHP低效且用起来不顺手,好的,你可以用别的语言来实现。但注意:提供给你的机器上只有python 2.4/perl 5.8/gcc[g++] 4.1

原题是要求使用PHP的,我们只是娱乐,不是真面试,当然就无视各种规定了。这道题不必使用词法分析的原理,可以写出很快的算法。但是用词法分析库来实现也是个不错的注意,因为DFA词法分析是O(N)的算法而且实际执行起来效率相当不错。下面我们就用VBF.Compilers.Scanner库来解决这道题:

Imports VBF.Compilers.Scanners
Imports VBF.Compilers.Scanners.RegularExpression
Imports System.IOModule ProgramSub Main(args As String())Dim findword = args(0)Dim bibleLexicon As New Lexicon()Dim lex = bibleLexicon.DefaultLexer'定义要寻找单词的词法Dim TARGET = lex.DefineToken(Literal(findword))'定义一般单词的词法Dim WORD = lex.DefineToken((Range("0"c, "9"c) OrRange("a"c, "z"c) OrRange("A"c, "Z"c)).Many1)'定义换行Dim LF = lex.DefineToken(Symbol(vbLf) Or Literal(vbCrLf))'定义其他所有符号均忽略Dim OTHER = lex.DefineToken(Range(ChrW(0), ChrW(255)))Dim bibleScanner As New PeekableScanner(bibleLexicon.CreateScannerInfo())bibleScanner.SetSkipTokens(OTHER.Index)Using sr As New StreamReader("bible.txt")Dim source As New SourceReader(sr)bibleScanner.SetSource(source)Dim scannerWatch As New StopwatchDim lines = 1, columns = 1, totalwords = 0, targetwords = 0scannerWatch.Start()Do While bibleScanner.Peek() <> bibleScanner.ScannerInfo.EndOfStreamTokenIndexDim x As Lexeme = bibleScanner.Read()Select Case x.TokenIndexCase TARGET.IndexConsole.WriteLine("第{0}行,第{1}列", lines, columns, x.Value)columns += 1targetwords += 1totalwords += 1Case WORD.Indexcolumns += 1totalwords += 1Case LF.Indexlines += 1columns = 1End SelectLoopscannerWatch.Stop()Console.WriteLine("总单词数: " & totalwords)Console.WriteLine("目标单词出现次数: " & targetwords)Console.WriteLine("消耗时间: " & scannerWatch.ElapsedMilliseconds)End UsingEnd SubEnd Module

这就是完整的代码。为了统计是第几个单词,我们按照题目的规定,定义了一般单词的词法,目标单词的词法,并且忽略所有其他字符(设定为SkipTokens)。分析过程就是不断读取下一个单词,直到文件的末尾。注意,这次我展示的是具有超前查看功能的PeekableScanner类,它可以超前查看任意多个单词,其实也可以用普通的Scanner而且性能更好。现在大家可以试试圣经中出现了什么单词,比如我们试一下apple:

第5769行,第29列
第14112行,第8列
第16578行,第14列
第17558行,第8列
第17646行,第25列
第20351行,第34列
第22304行,第23列
第22908行,第31列

可见我手里这本圣经出现了8次apple(我特意看了前面,亚当和夏娃吃的是fruit,不是apple……)。如果搜microsoft的话发现圣经中并没有出现,怪不得苹果最近这么风光……

源代码和圣经文件可以在这里下载:BibleFinder.7z

另外有不少同学问虎书是什么书,这里有龙书、虎书和鲸书的介绍:http://unistd.blog.51cto.com/1126453/260372。下一篇开始我们正式进入语法分析部分。希望大家继续关注我的VBF项目:https://github.com/Ninputer/VBF 和我的微博:http://weibo.com/ninputer 多谢大家支持!

转载于:https://www.cnblogs.com/Ninputer/archive/2011/06/16/2083092.html

自己动手开发编译器特别篇——用词法分析器解决背诵圣经问题相关推荐

  1. 自己动手开发编译器(我们的朋友 -- 装配脑袋走了)

    编者: 昨天在微信群里得知 我们的朋友--装配脑袋(施凡老师),因白血病离我们而去,自从得病以来,施老师在积极的接受治疗,8.27 得到的消息还是比较让人开心的,大家都在期待着他能够重出江湖.装配脑袋 ...

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

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

  3. 自己动手开发编译器(四)利用DFA转换表建立扫描器

    上回我们介绍了两种有穷自动机模型--确定性有穷自动机DFA和非确定性有穷自动机,以及从正则表达式经过NFA最终转化为DFA的算法.有些同学表示还是难以理解NFA到底怎么转化为DFA.所以本篇开头时我想 ...

  4. 游戏开发心得——书籍篇——《游戏引擎框架》-专业工具

    游戏开发心得--书籍篇--<游戏引擎框架>-专业工具 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: 学习<游戏引擎框架&g ...

  5. 手把手教你构建 C 语言编译器(3)- 词法分析器

    本章我们要讲解如何构建词法分析器. 手把手教你构建 C 语言编译器系列共有10个部分: 手把手教你构建 C 语言编译器(0)--前言 手把手教你构建 C 语言编译器(1)--设计 手把手教你构建 C ...

  6. 玄惭 mysql_阿里云数据库专家玄惭的“武功”全记录之最佳实践、双十一特别篇...

    原标题:阿里云数据库专家玄惭的"武功"全记录之最佳实践.双十一特别篇 专题简介 玄惭,真名罗龙九,阿里云DBA专家,负责阿里云RDS线上稳定以及专家服务团队.他经历过阿里历年双11 ...

  7. 乐高计算机发展史教程,【乐高产品发展史特别篇】乐高恐龙发展史

    -- 写在前面 -- 2018年6月22日,<侏罗纪世界2:失落王国>全球上映:4月16日,乐高同名系列套装全球发售.恐龙是一个伴随了乐高产品二十余年的主题,其实在一年以前就有这样一个计划 ...

  8. 自己动手写编译器、链接器目录结构

    <自己动手写编译器.链接器>第1章引言1 1.1HelloWorld编译过程分析1 1.1.1HelloWorld程序源文件1 1.1.2词法分析2 1.1.3语法分析3 1.1.4语义分 ...

  9. pb 查询客户端ip地址_特别篇-SAP 客户端(配置、测试、生产)

    特别篇-SAP 客户端(配置.测试.生产) 1.登录SAP系统的途径 有两种途径: 一种是通过企业门户网站: 一种是安装SAP GUI,通过GUI登录: 2.什么是SAP 客户端? 看下图 图1 图2 ...

最新文章

  1. 提高数据中心空间使用率,助力数字新基建
  2. Algorand 共识算法 BA* 入门
  3. Spring mvc HandlerMapping 实现机制
  4. live555 源码分析:ServerMediaSession
  5. 无法从套接字中获取更多数据_数据科学中应引起更多关注的一个组成部分
  6. SpringBoot微服务项目构建war包 部署排除指定jar
  7. android 开机动画尺寸,Android开机Logo动画制作
  8. 防御CSRF、XSS和SQL注入***
  9. 在线中英文符号转换工具
  10. AttributeError: module 'torch._C' has no attribute '_cuda_setDevice'(在python命令后面加上 --gpu_ids -1)
  11. 《啊哈算法》的Java实现| 第五章:图
  12. 视频转GIF软件哪个好用 怎么将视频转为GIF
  13. 人工智能在药物不良反应预测中的应用
  14. 微信开发如何优雅的注入token(2)
  15. RabbitMQ的消息补偿机制
  16. 智慧城市的互联网大脑架构图,大社交网络与智慧城市结合是关键
  17. Flutter | bloc 之 state 使用优化
  18. 网站建设(3)——CDN及CDN加速原理
  19. PyCharm汉化:简单两步搞定!PyCharm怎么设置中文简体,为什么我的pycharm搜不到中文语言包(Chinese ​(Simplified)​ Language Pack)
  20. Python游戏开发,Python实现童年小游戏推箱子 附带源码

热门文章

  1. 10年老分析师最终抛弃Excel,它不是最好的数据分析工具
  2. 深度解析艾瑞咨询《2017年度中国商业智能行业研究报告》
  3. mysql多字段分库分表基因码_一文学会常用 MySQL 分库分表方案
  4. 哪几所大学计算机软件方面是强项,计算机软件工程专业排名靠前的大学是那几所...
  5. vue设置列表数据添加
  6. 计算机组成原理 第四章 指令系统
  7. 计算机算法设计与分析 最大子段和问题
  8. 30个常用python实现
  9. Java 1.3 控制流程(条件语句、循环结构)
  10. PyTorch报错“/.../Loss.cu: ... [59,0,0] Assertion input_val >= zero input_val <= one failed.”