C语言解释器的实现词法分析(二)

  上一篇:C语言解释器的实现--存储结构(一)

  词法分析是编译原理中最容易理解的,就算没有了解过编译原理,也能写出一个词法分析器。我们不用理解正则表达式,不用理解状态机原理,就可以轻松的完成词法的分析。
  这里首先介绍下自顶向下的解析过程,所谓的自顶向下,按我的理解,就是从一个大的集合解析到小的集合。例如:解析一个文件,那么进入文件,解析一个函数,进入一个函数,解析局部变量,解析表达式,进入表达式,解析变量、常量等等,最终完成一个C文件的解析过程。整个过程,其实就是一个猜测的过程。但是这个过程中,我们必须依赖于文件中的每个词(token),token可以看成是解析过程中的一个单位。
  例如:
  1. 关键词有:int char double long for while ......
  2. 运算符有:+ - * / ......
  3. 数字常量:12 0x34 3.45
  4. 字符串  :"hello"
  ...
  等等.
 
  那么我们必须实现一个函数get_token,执行这个函数,我们获取文件中的一个token。例如现在一个C文件:
  int main(int agrc, char **argv ){
      return 0;
  }
  
  那么多次执行get_token,分别得到的token为:
  int
  main
  (           <----③
  int
  argc
  ...
  ...
  
  除了一个get_token函数外,还需要一个叫做put_back的函数,因为脚本解析是一个猜测的过程。有时候我们必须知道下一个的token是什么,才能判断该走哪个分支。还是上面的例子,在③的地方,我们得到了"(",所以知道main是一个函数,那么如果该token不是"(", 而是"=", 我们知道它不是一个函数,而是一个基本的变量定义,并且需要初始化。那么我们必须调用put_back函数,把该token重新放到缓存中,使得下次get_token的时候,还会拿到这个token,而不是下个token。
  至于get_token和put_back函数如何实现,我就不多说了。我使用了最笨的方法,无非就是每个字符一个一个的向后扫描,判断是该返回什么标示。每个token被分为各种类型token_type:
  enum tok_types{ DELIMITER = 1, IDENTIFIER, KEYWORD, TEMP, STRING, CHARACTOR, NUMBER, TYPE, BLOCK, PRECOMPILE };
  类型           意义               例如
  -----------------------------------------------------------------------------
  DELIMITER      标示分隔符         ; | + -
  IDENTIFIER     标示ID标示符       var hello
  KEYWORD        关键字             int char while do
  STRING         字符串             "string"
  CHARACTOR      字符               'c'
  NUMBER         数字常量           123 012 0x34
  TYPE           类型               typedef int int32;   那么int32就被标示为TYPE
  BLOCK          块标志             { }
  PRECOMPILE     预编译行           #define
  TEMP           保留              
  词法分析的目的就是扫描源码,区分出这些类型,变返回该token。供解释器的其他模块使用。

原文地址:https://www.cnblogs.com/linxr/p/2303397.html