词法分析
正则表达式是一种可以很方便地描述词素模式的方法。
如何对正则表达式进行转换:首先转换为不确定有穷自动机,然后再转换为确定有穷自动机。
后两种表示方法可以作为一个“驱动程序”的输入。
这个驱动程序就是一段模拟这些自动机的代码,它使用这些自动机来确定下一个词法单元。
这个驱动程序以及对自动机的规约形成了词法分析器的核心部分。
词法分析器
词法分析/扫描(lexical analysis, scanning)
高级语言程序的源文件(文本文件),可将其看作字符流。
对源程序文件中的字符流进行扫描,切分成为词素流;
作用
词法分析时编译的第一阶段。
主要任务:
-
读入源程序的输入字符、将它们组成词素,生成并输出一个词法单元序列,每个词法单元对应一个词素。
-
词法单元序列被输出到语法分析器进行语法分析。
-
词法分析器需要喝符号表进行交互。当词法分析器发现了一个标识符的词素时,要将其添加到符号表中。
-
某些情况下,词法分析器会从符号表中读取有关标识符种类的信息,以确定向语法分析器传送哪个词法单元。
词法分析器可以分为两个级联的处理阶段:
- 扫描阶段: 主要负责完成一些不需要生成词法单元的简单处理,比如删除注释和将多个连续的空白字符压缩成一个字符;
- 词法分析阶段:较为复杂的部分,它处理扫描阶段的输出并生成词法单元。
编译过程划分为词法分析和语法分析两个阶段的原因
有三个原因:
- 最重要的考虑是简化编译器的设计。将词法分析和语法分析分离通常可以简化其中的一项任务
- 提高编译器效率。把词法分析器独立出来使我们能够使用专用于词法分析任务、不进行语法分析的技术。
- 增强编译器的可移植性。输入设备相关的特殊性可以被限制在词法分析器中。
语法分析中的三个概念
- 词法单元:类概念,例如:
自定义符 中的变量(数据和函数),常量(数值和字符串);
预定义符中的if, for, while, ++, +。
- 词素:字符序列;
词法单元的实例;例如,前例的position,initial是数据变量。
预定义符的实例只有一个 - 模式:词法单元的构成法则
词法分析的实现
使用“哨兵标记”来节约用于检查缓冲区末端的时间。
一种重要的机制就是利用两个交替读入的缓冲区。
程序为输入维护了两个指针:
- lexemeBegin指针:该指针指向当前词素的开始处。当前我们正试图确定这个词素的结尾。
- forward指针:它一直向前扫描,直到发现某个模式被匹配位置。作出这个决定所依据的策略将在本账的其余部分中讨论。
一旦确定了下一个词素,forward指针将指向该词素的结尾字符。词法分析器就将这个词素作为某个返回给语法分析器的词法单元的属性值记录下来。
然后使lexemeBegin指针指向刚刚找到的词素之后的第一个字符。
在处理完这个词素后,他会被左移一个位置。
如何区分兼容性的标识符
兼容性的标识符:
例如:<和<=; +和++; if 和iff; * 和**;
采用最长匹配原则
词法分析算法
至此,什么都不符合了
从ps 至 (forword - 1)的串, 为一个保留字。因为保留字优先变量。
开始解析下一标识符
此时仅只符合保留字(的正则定义)
词法单元
词法单元的构成特征:
一个词是一个字符串,或者叫一个字符序列,它的构成呈线性结构,即串接特性。
以变量为例:以字母或者下划线开头,接任意多个字 母、下划线,数字;
词法单元例子
- 自定义符:变量,数值常量,字符常量;
- 预定义符(reserved keywords):
if; else; do; while; for; else if
+; - ; * ; / ; ** ; ++; ±
=; ==; <; <=; >; >= ; !=
; , “ ” ‘ ’
blank;
词法单元的模式
- 变量:以字母或者下划线开头,接任意多个字母、下划线,数字;
- 数值常量:先举例:0.1; 32; 49.8; 3.6E8; 0.5E-2; 8.9E+5;
- 字符常量:引号括起来的字符串 ;
- reserved keywords:
if; else; do; while; for; else if
+; - ; * ; / ; ** ; ++; ±
=; ==; <; <=; >; >= ; !=
; , “ ” ‘ ’
blank;
正则表达式
正则语言是一门最简单的语言,
用途:用它描述目标语言的词法单元及其构成法则
本质:描述字符串的集合。
有三个概念:
- 字符
- 运算(并运算)
- 运算(接运算)
用正则语言描述字符串的集合
满足某一构成法则的字符串的集合称其为一个正则表达式。
构成法则的线性迭加则通过正则表达式的正则运算来表达。
最小的正则表达式为一个字符,它满足正则表达式的定义,因为 一个字符也可构成一个字符串,一个集合中可以只有一个元素