CS143 3. Lexical Analysis

Lexcial analysis(词法分析)即将一个代码段中的字符或字符串(token)进行分类。

what is token? a token class corresponds to a set of substrings

目的

词法分析完成后,分析器会将结果给后面的解析器(Parser),解析器会根据不同的分类对不同类的token做不一样的处理,因此需要词法分析。

分类

在自然语言中我们可以将词分为:名词、动词、形容词、副词等,而在编程语言中我们也可以进行分类,有如下几类(不同的编程语言分类中的内容有区别):

  • Identifier——标识符(变量名或类型名)
  • Keyword——关键字,如ifwhile
  • Number——数字
  • WhiteSpace——空白字符,如\n\t、空格等
  • Operator——操作符,如+-=
  • Punctuation——标点符号,如:;"等,通常每个标点自己作为一类

流程

  1. 传入代码段
  2. 将代码段分成多个小字符串,每个字符串中的内容都隶属于上面的某一类
  3. 对每个字符串进行分类
  4. 得到多个<类型, 字符串>这样的<key,value>对,传给后面的解析器Parser

一个简单的例子

// C++
if (i == j)
    z = 0;
else 
    z = 1;

将上面的代码段中的字符先按字符串形式写出:

if (i == j)\n\tz = 0;\nelse\n\tz = 1;

然后进行划分(用|分隔):

|if| |(|i| |==| |j|)|\n|\t|z| |=| |0|;|\n|else|\n|\t|z| |=| |1|;|

最后再对每个子串分类,最后产生如<keyword, if>这样的<key-value>对。
难点

  1. 一个字符串如何划分,可能会产生歧义:
cin >> a; // 1

foo<bar<int>> // 2

12中都出现了>>,但意义完全不同,在1中它是输入流的一个操作符,而2中却不应该看成一个整体。

  1. 如何划分,有时候还要看后面的内容是什么,如,==被看作是一个整体,但解析到第一个=时,我们不知道是否应该就此停止,将这个=单独作为一个token,还是说将其和后面的内容结合,为了辨识这一点,需要看后面串的内容。

为了解决困难,需要引入正则语言(regression language)。

正则语言

设集合AB为字符、字符串、数字的集合,空字符串集记作 ϵ \epsilon ϵ ϵ = { \epsilon = \{ ϵ={“” } \} },但不是空集),有如下计算:

  1. Union——并: A + B = { s ∣ s ∈ A 或 s ∈ B } A + B = \{s| s \in A 或 s \in B\} A+B={ssAsB}
  2. Concatenation——连接: A B = { a b ∣ a ∈ A 且 b ∈ B } AB = \{ab| a \in A 且 b \in B\} AB={abaAbB}
  3. Kleene closure——Kleene闭包: A ∗ = ∪ i ⩾ 0 A i A^* = \cup_{i \geqslant 0}A^i A=i0Ai
  4. closure——闭包: A + = ∪ i ⩾ 1 A i A^+ = \cup_{i \geqslant 1}A^i A+=i1Ai

rs为正则表达式,L(r)L(s)分别为rs所能表达的字符串集合,则:

  1. r ∣ s r|s rs 为一个正则表达式,其表示 L ( r ) ∪ L ( s ) L(r) \cup L(s) L(r)L(s)
  2. r s rs rs 为一个正则表达式,其表示 L ( r ) L ( s ) L(r)L(s) L(r)L(s)
  3. r ∗ r^* r为一个正则表达式,其表示 ( L ( r ) ) ∗ (L(r))^* (L(r))

用正则表达式表示:

  • 数字: 0 ∣ − ∗ [ 1 − 9 ] [ 0 − 9 ] ∗ 0 | -^*[1-9][0-9]^* 0∣[19][09]
    ®L(s)$
  1. r ∗ r^* r为一个正则表达式,其表示 ( L ( r ) ) ∗ (L(r))^* (L(r))

用正则表达式表示:

  • 数字: 0 ∣ − ∗ [ 1 − 9 ] [ 0 − 9 ] ∗ 0 | -^*[1-9][0-9]^* 0∣[19][09]
  • 以字母开头的字母、数字串: [ a − z A − Z ] + [ a − z A − z 0 − 9 ] ∗ [a-zA-Z]+[a-zA-z0-9]^* [azAZ]+[azAz09]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值