c语言编译器_学C语言写自己的K语言:编译器词法分析。

词法分析(lexical analysis),是计算机科学中将字符序列转换为记录(Token)序列化的过程。词法分析一般分手动与自动,自动是基于lex,flex词法分析器使用正则式来配置,我们这里将学习手动构造。

一、明白词法分析所要做的事情。

下面是Source code:

int 

通过词法分析后得到的结果:

[

通过上述示例可以看出,词法分析是输入字符串,输出的是记号流。为了达到这样的结果,业务上有一套算法理论支持,所以你需要了解一下:正规式、有限自动机。

二、自动实现的原理

  • 正规式。

正规式与正则表达式类似,都是以表达式来表示字符串属性。只是正规式更基础、更简单,它只有5种基本语法。

1. 

正规式的作用是用来设定程序语言中的规则,从下列示例中可以看出,正规式的定义有时比较复杂,所以在flex(一种词法分析器,可适匹于多种语言)中使用的是正则式:

1. 
  • 有限自动机。

有限自动机(finite automata)是一种数学模型,它可以用来描述识别输入符号串的过程,在这个机器中,它的状态总是处于有限状态中的某一个状态。又分为:确定的有限自动机(DFA)与不确定的有限自动机(NFA)。

  1. 确定的有限自动机(DFA),每一个输入只有单一状态可流转,可对应程序的分支、循环语句。
  2. 不确定的有限自动机(NFA),每一个输入有多个状态可流转,无法对应程序语句。
  • 为什么需要这两种有限自动机呢?
  1. 首先,不确定的有限自动机能对应正规式,通过Thompsont算法;
  2. 其次,不确定的有限自动机可转为确定的有限自动机,通过子集构造算法;
  3. 再次,转化出来的确定的有限自动机可以实现大幅简化,通过Hopcroft算法;
  4. 最后,确定的有限自动机可以对应程序的分支、循环语句,即可以通过程序来实现。

四、我们自己来实现一个手动的。

我们不去管词法分析理论的复杂性,只要记住前面所说的“要将字符串转为记号流”就可以了。我们逐个读取代码中的字符串,判断其属于Token类型的可能性,最终确定Token类型并保存相关的值,就这样,我们就能完成了词法分析器。

在这里,我们只对K语言的部分语法作词法分析处理,请留意。如果想查看相关原代码,请浏览姜友华的github的compiler项目。

  • 首先,写一个K语言程序,用到了部分K语言语法。文件:complier/king.txt。
// 定义一个函数,判断是否可上学。
  • 其次,写词法分析器头文件,供外部调用。文件:compiler/lexer/lexer.h。
  1. 开始部分,我们定义了所需要分析的词法类型;
  2. 接着,定义了记号流记号的节点形式;
  3. 后面,提供了几个方法,供外部调用,运行并获取记号流数据。
//
  • 再次,写词法分析器主体,分类逐步解决问题。文件:compiler/lexer/lexer.c。
  1. 开始,我们对代码中出现的保留字(如:bool, int, string, true, false, return, if, for, in)作了判断;
  2. 接着,我们对空、数字、字母等作了判断,这里没有用正则表达式;
  3. 然后,我们对非分割符作了判断,它们有可能是数字字面量、字符串字面量、变量名与保留字;
  4. 最后,是遂个读取字符,判断生成各类Token,保存在tokens里;
  5. 这样,我们有了记号流。
//
  • 最后,我们在Main函数中调用词法分析器并输出。
  1. 我们是读取原代码文件的,要记得使用文件的绝对路径;
  2. 运行后并输出了结果,那就是记号流。
//
  • 说明:
  1. 字节流使用了1024长度的Token数组,Token.value使用了256长度的char数组,目的是为了实现更简便。如果你更改原代码,请留意越界出错。
  2. 没有使用map来判断保留字,为每个保留字设计了函数。这是因为C没有map,自已实现HashMap有些复杂,留到以后去处理。
  3. 所实现部分只针对示例的代码。

下一章,学C语言写自己的K语言:编译器语法分析。

让我们在这里,遇见明天的自己!姜友华

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值