《编程语言实现模式?可以理解为编程语言的《设计模式》,这本书的中文翻译通俗易懂,非常适合没有基础的人阅读。 本节主要介绍第一部分,词法分析和句法分析。

1.为什么需要学习这些模式

因为需要自定义DSL(领域自定义语言). 
人的智能非常强大,能够灵活地处理各种问题。计算机虽然迅速,但远远不及人类灵活。因此才有编程语言作为桥梁,建立人和机器的沟通方式。 
然而,通用语言功能强大,但针对特定的应用环境,可能不够简洁,同时有很多噪音,也可能难以被领域专家理解。更夸张的情况是,一些方法用通用语言非常难实现,而使用DSL则容易得多,比如正则表达式。 
在我们还不能构造出足够智能的机器前,使用DSL简洁流畅地反映人的算法和概念,便是一种折中的选择。

即使不去设计DSL,能理解DSL的原理和方法,对编程水平的提高都非常有帮助。

设计DSL看起来有难度,但当有足够的经验之后,就会发现其实有很多固定的模式可以借鉴,通过学习和熟悉这些模式,就能够更快速,方便,精确的构造自己的DSL和语言应用。

2.词法分析

字母的组合构成单词,单词的组合构成句子,所有正确的句子的组合则构成一门语言。 
对语言来说,如何判定句子是否正确?规定句子是否正确的规则称为文法。 
为了能够正确理解句子,就需要先将句子拆分成多个单词。对自然语言这叫做分词;对编程语言,则叫做词法分析。 
通常来说,一个TOKEN可能是数字,符号,单词,或是字符串。因而通过正则表达式,可以流式的切分并确定TOKEN的类型。 
值得指出,TOKEN的类型由于二义性,并不能在词法分析,而需要在语法分析时确定。

3.语法分析

在完成词法分析后,就是语法分析的阶段。语法分析的目标是将文本翻译为句法树。

LL(1)模式

语法分析就像贪吃蛇,词法分析得到的单词就像一颗颗的糖豆,最简单的语法分析可以理解为一次吃一颗糖豆。 
如果没有递归子结构,形成的结果更像一个链表,而非树结构。 
一旦语言支持嵌套结构,就需要递归下降语法分析器。如果使用本模式,生成的将是直接调用自身而无限递归的函数。 
递归下降的问题是,无法识别左递归,否则将陷入无限循环。另外,由于只向前看一个单元,可能并不能直接判断出当前的文法。

LL(k)模式

为了解决这个问题,可能需要向前多看几个单元。往前看的单元越多,贪吃蛇就在遇到交叉时顺着不同的路径看的更远,从而越知道该选择哪条路径。而做解析决策的能力越强,语言就更容易编写。 
最简单的方式,就是使用数组来缓冲所有的输入符号,以整数输入作为下标的指针。使用环形缓冲区能够方便地保存数据。

回溯解析器

有时,当文法要求语言能够支持任意多的重复结构时,要求LL(k)中的缓冲要无限大,这是不可能的。为了解决这个问题,需要采用回溯解析。 
其概念就像走迷宫,既然不能只看不走,那么就尝试去走每一个可能的选项,直到找到合适的为止。这样等价于任意地向前看。 
回溯可以设计为遇到成功的,就不尝试其他路径;也可以不论是否成功,都尝试全部路径,最后选择最长,最短,或其他自定义的筛选方法。 
回溯解析的性能远远不及LL(k),其中一大原因是重复。可能两个路径A和B, B路径中又包含了A路径。这样A路径就可能探查两遍。为了避免重复,可以通过消耗少量的内存引入记忆机制。

记忆解析器

记忆解析器使用了类似动态规划的概念,记录在某一位置时,使用某条文法的尝试结果,如成功,失败或其他的匹配特征。这样就能大大减少重复,使得回溯解析能尽可能地达到LL(k)模式的性能。

谓词解析器

有时,通过纯粹的文法很难判断选择哪一条匹配路径,因而可以通过嵌入判断逻辑,借助运行时信息调整解析策略。 
谓词解析的常用实现,是在文法中嵌入代码(如通用语言),解析引擎在运行时执行这些代码,来调整决策。

3.语言优化

生成AST结构之后,就可以对树进行操作了。主要的操作有两部分,遍历和规约。 
节点结构本身的设计值得考量,基本上有两种风格:

  • 同构弱类型:所有的节点类型一致,只通过标识符区分操作,通过列表保存子节点。 优点是开发方便,缺点是少了运行时检查。
  • 异构强类型:节点类型不一致,但都继承于一个基类。如果方法很多,会产生大量的节点类型。对于编程的工作量可能较大。另外,也不适合自动工具生成时嵌入自定义代码。

遍历

所谓遍历,看似很容易。但有一些需要注意的点。

  • 访问和执行是其实是分离的,先访问不一定代表先执行。根据执行代码相对于访问代码的位置,可以生成前序,中序和后序遍历。
  • 遍历中肯定要执行操作,对操作的描述可以放在节点定义文件中,也可以设计外部访问器

规约

在生成句法树后,可能一些树结构是冗余或无效的,也可能可以被优化为更好的结构,例如: 
0*(x+5) 由于任何数字乘以0都为0,所以应该直接被规约为0。 
规约涉及到两个问题,首先要识别特定的树结构,这就需要对树进行模式匹配,ANLNR已经有现成的工具和语法支持这类操作。

4.总结

编译原理的书看似很枯燥(确实很枯燥),所以一定要去实践,实践后再去看这些概念,就会觉得非常漂亮了。
目前已经采用这些技术,开发了面向序列模式发现和抽取的一套DSL。不久后将会发布。未来将开发针对树结构的分析DSL。
下一部分的内容,是该书的后半部分,程序的解释执行。然而这一部分,我还没有深入去研究,因此估计周期会比较长了。

《编程语言实现模式》笔记(一)词法和句法分析相关推荐

  1. 复旦大学邱锡鹏教授:词法、句法分析研究进展综述

    本文为第十六届自然语言处理青年学者研讨会 YSSNLP2019 报告<词法.句法分析研究进展综述>的简要文字整理,本报告主要回顾词法.句法领域的最新研究进展. 关于报告人: 邱锡鹏,复旦大 ...

  2. 句法依存分析_复旦大学邱锡鹏教授:词法、句法分析研究进展综述

    本文为第十六届自然语言处理青年学者研讨会 YSSNLP2019 报告<词法.句法分析研究进展综述>的简要文字整理,本报告主要回顾词法.句法领域的最新研究进展. 关于报告人: 邱锡鹏,复旦大 ...

  3. CM1模式笔记(科研数值模拟向)

    CM1模式笔记 成果展示 文档解读 快速入门 快速case inputsouding探空 参数详解 焓系数 输出文件的格式 wspmax 降水 相关文献理解 实验解读 第一篇引用 探空资料 爬取探空数 ...

  4. 23种设计模式模式笔记+易懂案例

    Java设计模式 前言 这其实算我个人学习的一个笔记,我这里的标题只有22种,俗称的23种是因为工厂模式一般分为两种,工厂模式与抽象工厂. 一.设计模式是什么? 1.设计模式的定义 设计模式的一般定义 ...

  5. 118云原生编程语言Golang学习笔记

    Golang学习笔记 文章目录 1.Go简介 1.1 简介 1.2 设计初衷 1.3 Golang vs Java 1.4 应用领域 1.5 用go语言的公司 2.Go下载和安装 2.1 开发工具 2 ...

  6. Singleton模式笔记

    在C++中,尽量用Singleton替换全局变量是个很好的建议,Singleton一般如下: class  CSingleton { private:     static CSingleton* m ...

  7. SQL反模式笔记17——用一条sql解决复杂问题

    目标:检查sql查询次数 反模式:试图用一条sql解决复杂问题 结果是:性能很低,而且往往得到了一个笛卡尔积. 解决方案:分而治之 用多个sql得到数据,再进行整合.或者union多个sql的结果. ...

  8. SQL反模式笔记7——多列属性

    目标:存储多值属性 反模式:创建多个列.比如产品主图,开始需求是,每个产品都是3张图,但随着时间的推移,可能就不止3张了. 1.查询:多个列的话,查询时可能不得不用IN,或者多个OR 2.添加.删除. ...

  9. 设计模式之Composite模式(笔记)

    组合模式:将对象组合成树形结构以表示"部分-总体"的层次结构. 组合模式使得用户对单个对象和组合对象的使用具有一致性. 适用场合:当需求中是体现部分与总体层次的结构时,以及希望用户 ...

最新文章

  1. web项目数据存入mysql数据库中文乱码问题
  2. 把Java程序打包成jar文件包并执行
  3. Python 骚操作!如何让自己在斗图中立于不败之地?
  4. 1.9 编程基础之二分查找 13:整数去重 python
  5. Exchange Server 2013多域名证书申请
  6. linux下运行exe程序之wine的使用与安装
  7. Selenium和Appium教程合集
  8. 调频连续波雷达(FMCW)测距/测速原理
  9. springweb项目连接数据库的时候报错Access denied for user ‘cyy‘@‘192.168.56.1‘ (using password: YES)
  10. Java基础 (适合新手入门保姆级)
  11. wps连接mysql odbc_如何在WPS中使用ADO连接数据库?
  12. python方差膨胀因子_讲讲共线性问题
  13. Opencv imread读取图片结果一直为空
  14. 运维体系建设(第二章)
  15. word 分章节,如何下一章页眉单独改动,不影响上一章
  16. 公司财务发工资时,记录了当时发工资的资料Employee.txt 1.定义公司员工类Employee,属性有:工号,姓名,性别,工资(double类型),进行属性的隐藏和封装,重写toString.
  17. AtCoder Beginner Contest 167 A Registration 字符串比较
  18. Java JDK 安装方法---阿哲专属版
  19. Cis-Glyoxal-Cyclam ,CAS: 74199-16-9,CIS-十氢-1H,6H-3A,5A,8A,10A-四氮杂芘
  20. 编写程序,解决鸡兔同笼问题:一个笼子里关着鸡和兔子。问笼中各有多少只鸡和兔?

热门文章

  1. 输入一个字符,一个数字,一个单精度浮点数,一个双精度浮点数,按顺序输出它们四个 且数字指定占4个字符宽靠右对齐,单精度浮点数保留2位小数,双精度保留12位小数,占一行输出、空格分隔
  2. VQA系列论文(三)
  3. 学习日记day27 平面设计 构图
  4. linux网口初始化_Linux 初始化系统配置(CentOS 6)
  5. vue-element-admin--使用体验
  6. [AX2012] 用户权限模拟与测试工具
  7. NotePad++ 打开多个文件
  8. Rk3128 按键驱动
  9. 如何嗅探并下载ts并合成视频文件,m3u8文件处理
  10. 自适应遗传算法 matlab,自适应遗传算法MATLAB代码