资讯专栏INFORMATION COLUMN

从零开始写个编译器吧 - Parser 语法分析器

fai1017 / 2800人阅读

摘要:这样的程序或称工具有很多现成的可供选择包括在平台上可用的,但既然我这个系列叫做从零开始写个编译器吧,那显然如果我用现成的工具,那是犯规行为。

Parser(语法分析器)的编写相对于 Tokenizer (词法分析器)要复杂得多,因此,在编写之前可能也会铺垫得更多一些。当然,本系列旨在“写出”一个编译器,所以理论方面只会简单介绍 tao 语言所涉及的部分。
之前的几章中,我纯手写了tao 语言的 Tokenizer。但如果我准备也纯手写一个 Parser,那将是非常麻烦且繁琐的一件事情。实际上,就在在写出这篇文章之前,我已完成了 Parser 的编写,并测试妥当,因此我可以在此面对各位得出这个结论。

我将使用这么一种方式“制造”出 Parser:

将 tao 语言的所有语法细节描述出来,即定义 tao 语言。

写一个能”根据定义,生成 tao 语言的 Parser“的程序。

如果以上描述有些让人困惑,那我举个通俗点的例子吧:

  

假如我想要制作一双鞋子,通常的方案是,我会买好材料,并把鞋子做出来。但还有另一种方案,我先画出鞋子的设计图,再造一台能依照设计图造出鞋子的机器,然后把设计图交给机器,再发动机器,得到鞋子

在”制造鞋子的世界“中,除非我要开鞋厂,否则若我仅仅想造双鞋子,那么前一个方案显然更好。但在”制造编译器的世界“中,却与直觉相反,当语言本身足够复杂的时候,后一种方案比前一种方案要方便得多。

至此,我需要一个能读懂 tao 语言的定义,并根据定义生成 Parser 的一个程序。这种程序我们称之为 Compiler-compiler 。这样的程序(或称工具)有很多现成的可供选择(包括在 Java 平台上可用的),但既然我这个系列叫做《从零开始写个编译器吧》,那显然如果我用现成的工具,那是犯规行为。

因此,我还要写一个 Compiler-compiler 出来才行。

那么,让我先贴一张图,以描述我将会写出的 Compiler-compiler 的工作原理吧。

Compiler-compiler 会将 tao 语言的定义编译成某种数据结构,而这种数据结构是 Parser 初始化的参数。Parser 只有获得了这种数据结构才能正常工作。

当 Parser 初始化之后,它会读取 Tokenizer 生成的 Token 序列,并同时通过解释 Compiler-compiler 生成的数据结构,最后生成 Syntax Tree。

至此,在编写 Parser 的章节中,我必须完成如下三个任务。

定义 tao 语言的语法细节,并挑选一个合适的形式描述出来。

编写一个 Compiler-compiler,它能编译 tao 语言的定义,并生成某种数据结构。

编写一个 Parser,它通过解释 Compiler-compiler 生成的数据结构,将 Token 序列编译成 Syntax Tree。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64263.html

相关文章

  • 从零开始写个译器 - 译器的结构

    摘要:自然,我们还是先从语言的编译器下手吧。在动手写编译器之前,得容我将编译器的结构进行进一步的划分。这些将被语法分析器接收并进行进一步处理。由于本系列将着重于写出编译器,必要的理论和概念还是会交代的。从零开始写个编译器吧编译器的结构的博客 自然,我们还是先从 tao 语言的编译器下手吧。在动手写编译器之前,得容我将编译器的结构进行进一步的划分。编译器可视为一个黑盒,从其一端输入源代码,另一...

    wudengzan 评论0 收藏0
  • 从零开始写个译器系列

    摘要:是的,这个系列将呈现一个完整的编译器从无到有的过程。但在写这个编译器的过程中,我可不会偷工减料,该有的一定会写上的。该语言的虚拟机将运行于之上,同时编译器将使用实现。我早有写编译器的想法之前没写过,故希望一边写编译器一边完成这个系列。 是的,这个系列将呈现一个完整的编译器从无到有的过程。当然,为了保证该系列内容的简洁(也为了降低难度),仅仅保证编译器的最低要求,即仅能用。但在写这个编译...

    genedna 评论0 收藏0
  • 从零开始写个译器 - 词法析器是一个状态机

    摘要:词法分析器本身就是一个状态机,生成这个状态机有很多种方法,而我打算采取手写的方式。状态机不断从源代码即一个字符串中读入一个一个字符,读到不同的字符将使状态机的状态从一个状态变化到另外一个状态。 词法分析器 Tokenizer 本身就是一个状态机,生成这个状态机有很多种方法,而我打算采取手写的方式。因为 tao 语言的词法还是相对比较简单的,手写不成问题。 先新建一个LexicalAna...

    calx 评论0 收藏0
  • 从零开始写个译器 - TerminalSymbol.java 与 NonTerminalSymb

    摘要:对于而言,终结符与的是对应的。这些内容,我将其称之为终结符的值。对于一个非终结符的产生式对于非终结符,其对象的字段则会表现成如下形式。对于里面的数组,其元素可能为终结符对象非终结符对象或表达式枚举对象。 首先是 TerminalSymbol.java 即终结符。 package com.taozeyu.taolan.analysis; import java.util.HashSet...

    darry 评论0 收藏0
  • 从零开始写个译器 - 分析非终结符

    摘要:基于这个结论,对某个非终结符展开形式的判定就变得明了起来。但严格的要求一个非终结符最多只能有一个产生式可以导出。这意味着我们必须明确知道每一个非终结符能不能导出。如果集包含这个终结符,则表明该非终结符需要导出。 tao 语言的 Parser 的语法分析是不带回溯的,自顶向下的。文法选用 LL(1),这种文法虽然略显薄弱,但还尚可用。 回顾上一章提到的 LL(1) 的定义,可以得出如下结...

    snifes 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<