写完词法部分,又有很多杂事,周末终于有空来实现伟大的语法解析部分了。

撸完代码之后发现,程序太短了,不算上状态机,才186行(含注释),关键代码不到100行。运行调试过后,发现还行。居然可以解析OneThink里面的function.php。这个文件堪称Php程序的集大成者,里面什么妖魔鬼怪都有,调试的时候真是一把辛酸泪。当然我也是不会说的,哈

有鉴于程序太短,所以我准备详细地来说说,以免大家不太明白其中奥妙:)

我们知道,语法解析一般有LL(1),LR(0),SLR(1),LALR(1),LR(1)等分析方法。比较常见的,就是LL(1),LR(0)

LL这种分析方法是从左到右扫描,最左推导;LR是从左到右扫描,最右推导;LL采用的是预测表,LR采用的是分析表;LR的难度在LL之上,分析能力也在LL之上,而且,LR的变化也更多。所以这样一个玩票的项目,当然要用LR才能稳稳地创(zhuang)新(bi)。

LR分析器的模型如下图。

包括两个栈,其中最首要地工作是生成LR分析表。当然我并不准备老老实实地按课本上的经典方法来,如何创(tou)新(lan)呢?这是关键。

我们看SLR(1),LALR(1),LR(1)都是对LR(0)的一种改进,其中最重要的就是那个(1),代表向前查看。为什么要向前看?为了减少分析表的规模。未来有无数的可能性,向前看了,可能性减少了,分析的规模也会大大减少。我们要减少分析的规模就必须向前看,而且看得越多分析表越小,而相反的编程难度也越大。那么,有没有一种方法让我站着把钱赚了,让我不向前看,难度不增加,分析表又减少呢。

有,还真有,这难不倒一个资深懒汉。我们知道,向前看的需求,来源于文法表达式:如A → Abc,它的单个表达式长度越长,不确定性越大。所以,限制方法表达式的最大长度,可以在此长度内保证100%的确定性,也就完全不需要向前看了。我把这种方法命名限长LR,即LLLR(0,n),n>=3。

如此,这次我理所当然地选择LLLR(0,3)做为分析方法,而且为了实现方便,我决定不保存状态,也就不需要生成分析表了,不生成表了,不生成表了……

妈蛋!这也太偷懒了。不保存状态,意味着每次都需要从头搜索,效率呢效率,这是程序员的生命!

稍安勿躁,表达式的最大长度为3,最多搜索3步即可,放心吧,就这么定了。:)

这就是100行超简Php编译器的奥秘,如何,够创(zhuang)新(bi)吧。源码在此:converterV0.4.zip Enjoy!

<未完待续>

转换器4:手写PHP转Python编译器,语法解析部分的更多相关文章

  1. 转换器3:手写PHP转Python编译器,词法部分

    上周写了<ThinkPhp模板转Flask.Django模板> 一时技痒,自然而然地想搞个大家伙,把整个PHP程序转成Python.不比模板,可以用正则匹配偷懒,这次非写一个Php编译器不 ...

  2. 为sproto手写了一个python parser

    这是sproto系列文章的第三篇,可以参考前面的<为sproto添加python绑定>.<为python-sproto添加map支持>. sproto是云风设计的序列化协议,用 ...

  3. 手写 Vue2 系列 之 编译器

    前言 接下来就要正式进入手写 Vue2 系列了.这里不会从零开始,会基于 lyn-vue 直接进行升级,所以如果你没有阅读过 手写 Vue 系列 之 Vue1.x,请先从这篇文章开始,按照顺序进行学习 ...

  4. KNN手写实践:Python基于数据集整体计算以及排序

    1. 距离计算,不要通过遍历每个样本来计算和指定样本距离,而是通过对于指定样本进行广播(复制)成为一个shape和全局一致后,再进行整体计算,这里的广播 / 复制采用的是tile函数来实现的: 2. ...

  5. 用java实现一个简易编译器-语法解析

    语法和解析树: 举个例子看看,语法解析的过程.句子:“我看到刘德华唱歌”.在计算机里,怎么用程序解析它呢.从语法上看,句子的组成是由主语,动词,和谓语从句组成,主语是“我”,动词是“看见”, 谓语从句 ...

  6. Python学习宝典,Python400集让你成为从零基础到手写神经网络的Python大神

    当您学完Python,你学到了什么? 开发网站! 或者, 基础语法要点.函数.面向对象编程.调试.IO编程.进程与线程.正则表达式... 当你学完Python,你可以干什么? 当程序员! 或者, 手写 ...

  7. TensorFlow下利用MNIST训练模型识别手写数字

    本文将参考TensorFlow中文社区官方文档使用mnist数据集训练一个多层卷积神经网络(LeNet5网络),并利用所训练的模型识别自己手写数字. 训练MNIST数据集,并保存训练模型 # Pyth ...

  8. 手写 Vue2 系列 之 初始渲染

    前言 上一篇文章 手写 Vue2 系列 之 编译器 中完成了从模版字符串到 render 函数的工作.当我们得到 render 函数之后,接下来就该进入到真正的挂载阶段了: 挂载 -> 实例化渲 ...

  9. 手写一个IOC容器

    链接:https://pan.baidu.com/s/1MhKJYamBY1ejjjhz3BKoWQ 提取码:e8on 明白什么是IOC容器: IOC(Inversion of Control,控制反 ...

随机推荐

  1. ORACLE Postgresql中文排序

    当我们order排序不能够实现我们想要的内容时候,尝试一下NLSSORT这个函数吧 他不仅仅按照姓氏排序,名也会排序: nls_param用于指定语言特征,格式为nls_sort      = sor ...

  2. Redis缓存数据之简单逻辑

    并发不高的情况: 读: 读redis->没有,读DataBase->把DB数据写回redis,有的话直接从redis中取: 写: 写DataBase->成功,再写redis: 并发高 ...

  3. Zookeeper以Windows服务安装运行

    1.下载的Zookeeper是.cmd的批处理命令运行的,默认没有提供以windows服务的方式运行的方案 下载地址:http://zookeeper.apache.org/ 2.下载prunsrv ...

  4. 【Spring-web】AsyncRestTemplate源码学习

    2017-01-23 by 安静的下雪天 http://www.cnblogs.com/quiet-snowy-day/p/6343347.html 本篇概要 类说明 类图 简单例子 精辟的内部类 类 ...

  5. HDU 2585 [Hotel]字符串递归处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2585 题目大意:马克思要找个曾经去过的很好的旅馆,可惜他记不完整旅馆的名字.他有已知的部分信息和可能的 ...

  6. CSS实现的几款不错的菜单栏

    前言 自从做了智慧城市这个项目之后,我一个做后端的开发者,瞬间转为前端开发,不过我还是很喜欢前端的.前端那些事,其实蛮有意思的,HTML实现的是静态的,使用ajax之后就可以和数据库交互了,加上js和 ...

  7. java_db2错误码对应值

    DB2-SQLSTATE消息 2012-08-27 10:35:27|  分类: db2|举报|字号 订阅     本节列示 SQLSTATE 及其含义.SQLSTATE 是按类代码进行分组的:对于子 ...

  8. 初识 BFC、 IFC、GFC、FFC

    首先本文中介绍的 BFC. IFC.GFC.FFC 均为 CSS 中常见问题的解读,如没兴趣,可以绕道了. 然后在介绍这么多的 *FC 之前,我们得了解 一下 Box 和 Formatting Con ...

  9. swift注意

    赋值的时候要想为空 可以用   ? 例如 var age1:Int? // ?表示age1的类型为可选类型,其值可以为空print(age1) 判断一个字符串为空字符串if str_empty.isE ...

  10. 网络请求 ---iOS

    //1.url要访问的资源 NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; //2.请求,要向服务器请求 N ...