词法分析之正则文法和有限自动机

497 阅读3分钟

1 词法分析是把程序分割成一个个 Token 的过程,可以通过构造有限自动机来实现。

2语法分析是把程序的结构识别出来,并形成一棵便于由计算机处理的抽象语法树。 可以用递归下降的算法来实现。

3语义分析是消除语义模糊,生成一些属性信息,让计算机能够依据这些信息生成目标代码。

正则负责解析,自动机负责规则。

词法分析的工作是一边读取一边识别字符串的,不是把字符串都读到内存再识别。和人类类似,在听一位朋友讲话的时候,其实也是同样的过程,一边听,一边提取信息。

要实现一个词法分析器,首先需要写出每个词法的正则表达式,并画出有限自动机,之后,只要用代码表示这种状态迁移过程就可以了。

字符串是一连串的字符形成的,怎么把它断开成一个个的 Token 呢

是关系表达式、变量声明和初始化语句,以及算术表达式:

age >= 45

int age = 40

2+3*5

词法规则

标识符

标识符:第一个字符必须是字母,后面的字符可以是字母或数字

比较操作符

比较操作符:> 和 >=(其他比较操作符暂时忽略)。

数字字面量

数字字面量:全部由数字构成(像带小数点的浮点数,)。

image.png

  1. 初始状态:刚开始启动词法分析的时候,程序所处的状态。

  2. 标识符状态:在初始状态时,当第一个字符是字母的时候,迁移到状态 2。当后续字符是字母和数字时,保留在状态 2。如果不是,就离开状态 2,写下该 Token,回到初始状态。

  3. 大于操作符(GT):在初始状态时,当第一个字符是 > 时,进入这个状态。它是比较操作符的一种情况。

  4. 大于等于操作符(GE):如果状态 3 的下一个字符是 =,就进入状态 4,变成 >=。它也是比较操作符的一种情况。

  5. 数字字面量:在初始状态时,下一个字符是数字,进入这个状态。如果后续仍是数字,就保持在状态 5。

Java代码演示

DfaState newState = DfaState.Initial;
if (isAlpha(ch)) {              //第一个字符是字母
    newState = DfaState.Id; //进入Id状态
    token.type = TokenType.Identifier;
    tokenText.append(ch);
} else if (isDigit(ch)) {       //第一个字符是数字
    newState = DfaState.IntLiteral;
    token.type = TokenType.IntLiteral;
    tokenText.append(ch);
} else if (ch == '>') {         //第一个字符是>
    newState = DfaState.GT;
    token.type = TokenType.GT;
    tokenText.append(ch);
}

其中 Token 是自定义的一个数据结构,它有两个主要的属性:一个是“type”,就是 Token 的类型,它用的也是一个枚举类型的值;一个是“text”,也就是这个 Token 的文本值。

此文章为3月Day23学习笔记,内容来源于极客时间《02 | 正则文法和有限自动机:纯手工打造词法分析器 (geekbang.org)