自己动手写编译器:实现命令行模块

在前面一系列章节中,我们完成了词法解析的各种算法。包括解析正则表达式字符串,构建 NFA 状态就,从 NFA 转换为 DFA 状态机,最后实现状态机最小化,接下来我们注重词法解析模块的工程化实现,也就是我们将所有算法集合起来完成一个可用的程序,由此在接下来的章节中,我们将重点放在工程实现上而不是编译原理算法上。

为何我们一个强调编译原理算法的专栏会花费大力气在工程实现上呢。英语有句俗语"you don’t know it if you can’t build it",也就是你做不出来就意味着你没有掌握它,这一点是我们传统教育的痛点,你上了计算机课程中的编译原理,操作系统,你掌握了一堆名词和算法描述,但完成这些课程,考试通过,那意味着你掌握这些知识了吗?如果学了操作系统,你不能做出一个可运行的系统,学了编译原理,你搞不出一个能编译代码的编译器,那说明你对所学知识根本没有真正掌握,你只是模模糊糊,一知半解。

为了真正掌握,我们必须构建出一个可运行的具体实体。在实现这个具体实体过程中,我们会发现很多我们以为理解了的算法或概念,实际上我们根本就没有掌握。本节开始我们要为 GoLex 添加更多复杂功能,当我们完成 GoLex 工具后,它的作用如下:
请添加图片描述
GoLex 程序运行时需要输入两个文件,分别为 input.lex 和 lex.par,其中 input.lex 我们已经认识过,lex.par 其实是一个 c 语言模板文件,它的内容我们在后面章节中会花很大力气去剖析和实现,GoLex 会读取这两个文件的内容,然后生成两个文件 lex.yy.c 和 lex.yy.h,这两个文件是给定语言词法解析器的代码,假设我们要开发一个能识别 sql 语言词法的程序,那么我们把识别 sql 语言中关键字,变量名等字符串对应的正则表达式放在 input.lex 中,然后调用 GoLex 生成 lex.yy.c,lex.yy.h 两个 c 语言源代码文件,然后再使用 gcc 对这些文件进行编译,最后得到的可执行文件 a.out 就是能用于对 sql 代码文件进行词法解析的可执行文件,也就是说 GoLex 其实是用于生成另一个可执行程序源代码的程序,这类似于微积分中的二阶求导。

废话少说,能动手就不要逼逼。首先在工程目录下创建一个名为 cmd 的文件夹,然后创建一个名为 cmd.go 的文件,实现代码如下:

package command_line

import (
	"fmt"
	"time"
)

type CommandLine struct {
   
}

func NewCommandLine() *CommandLine {
   
	return &CommandLine{
   }
}

func (c *CommandLine) Signon() {
   
	//这里设置当前时间
	date := time.Now()
	//这里设置你的名字
	name := "yichen"
	fmt.Printf("GoLex 1.0 [%s] . (c) %s, All rights reserved\n", date.Format("01-02-2006"), name)
}

上面代码运行后会打印出一行”版权“信息,它能让我们感觉好像搞了什么牛逼得不行的东西,有一种老子是大神的牛逼哄哄获得感。下面我们提供一个函数叫 PrintHeader,它的作用是输出对未压缩 DFA 的 C语言注释,首先我们把原来在 main 函数中的那些代码挪到 CommandLine 对象的构造函数中,相关代码如下:

package command_line

import (
	"fmt"
	"nfa"
	"time"
)

type CommandLine struct {
   
	lexerReader  *nfa.LexReader
	parser       *nfa.RegParser
	nfaConverter *nfa.NfaDfaConverter
}

func NewCommandLine() *CommandLine {
   
	lexReader, _ := nfa.NewLexReader("input.lex", "output.py")
	lexReader.Head()
	parser, _ := nfa
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值