1 词法分析是把程序分割成一个个 Token 的过程,可以通过构造有限自动机来实现。
2语法分析是把程序的结构识别出来,并形成一棵便于由计算机处理的抽象语法树。 可以用递归下降的算法来实现。
3语义分析是消除语义模糊,生成一些属性信息,让计算机能够依据这些信息生成目标代码。
正则负责解析,自动机负责规则。
词法分析的工作是一边读取一边识别字符串的,不是把字符串都读到内存再识别。和人类类似,在听一位朋友讲话的时候,其实也是同样的过程,一边听,一边提取信息。
要实现一个词法分析器,首先需要写出每个词法的正则表达式,并画出有限自动机,之后,只要用代码表示这种状态迁移过程就可以了。
字符串是一连串的字符形成的,怎么把它断开成一个个的 Token 呢
是关系表达式、变量声明和初始化语句,以及算术表达式:
age >= 45
int age = 40
2+3*5
词法规则
标识符
标识符:第一个字符必须是字母,后面的字符可以是字母或数字
比较操作符
比较操作符:> 和 >=(其他比较操作符暂时忽略)。
数字字面量
数字字面量:全部由数字构成(像带小数点的浮点数,)。
-
初始状态:刚开始启动词法分析的时候,程序所处的状态。
-
标识符状态:在初始状态时,当第一个字符是字母的时候,迁移到状态 2。当后续字符是字母和数字时,保留在状态 2。如果不是,就离开状态 2,写下该 Token,回到初始状态。
-
大于操作符(GT):在初始状态时,当第一个字符是 > 时,进入这个状态。它是比较操作符的一种情况。
-
大于等于操作符(GE):如果状态 3 的下一个字符是 =,就进入状态 4,变成 >=。它也是比较操作符的一种情况。
-
数字字面量:在初始状态时,下一个字符是数字,进入这个状态。如果后续仍是数字,就保持在状态 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)》