编译原理词法分析(一)

词法分析(一)

词法分析器(Lexical Analyzer)功能:

输入源程序、输出单词符号
单词符号的种类
基本字: 如begin,repeat,for……
标识符: 用来表示各种名字,如变量名、数组名和过程名
常数: 各种类型的常数
运算符:+,-,*,/,……
界符: 逗号、分号、括号和空白

词法分析器的输出
输出的单词符号的表示形式
(单词种别,单词自身的值)

  • 单词种别通常用整数编码表示
  • 若一个种别只有一个单词符号,则种别编码就代表该单词符号。假定基本字运算符界符都是一符一种。
  • 若一个种别有多个单词符号,则对于每个单词符号,给出种别编码自身的值
    • 标识符单列一种;标识符自身的值表示成按机器字节划分的内部码
    • 常数按类型分种;常数的值则表示成标准的二进制形式

例一:
编译原理词法分析(一)_第1张图片
例二:
编译原理词法分析(一)_第2张图片

词法分析器的两种形式

  • 一个词法分析器可以做为编译器中的独立的部分把字符流的源程序变成单词序列
  • 做为语法分析器的子程序当被语法分析器调用时返回一个词法单元。如下图:
    编译原理词法分析(一)_第3张图片

词法分析器的结构

1.预处理子程序扫描器的调用下,将源程序输入到输入缓冲区中。
2.预处理子程序读取输入缓冲区中的字符进行文本的预处理。主要包括:

  • 剔除无用的空白、跳格、回车和换行等编辑性字符
  • 区分标号区、 捻接续行和给出句末符等

3.经过预处理后,规范性更好的文本送入扫描缓冲区中。
4.预处理子程序返回扫描器扫描器继续从扫描缓冲区中读取预处理后的文本再根据词法规则识别单词符号。
如图:
编译原理词法分析(一)_第4张图片
扫描器规则
1.将扫描缓冲区分为两个半区互补使用,半区的长度是程序语言允许的单词最大长度。比如有些语言的单词长度不允许超过128,则扫描缓冲区的长度为256.
编译原理词法分析(一)_第5张图片

单词符号的识别:超前搜索

基本字标识符常数运算符界符 都会涉及超前搜索。为了避免使用超前搜索加上几点限制。

  • 所有基本字都是保留字;用户不能用它们作自己的标识符
  • 基本字作为特殊的标识符来处理,使用保留字表
  • 如果基本字、标识符和常数(或标号)之间没有确定的运算符或界符作间隔,则必须使用一个空白符作间隔DO99K=1,10要写成DO 99 K=1,10

状态转换图

  • 状态转换图是一张有限方向图

    • 结点代表状态,用圆圈表示
    • 状态之间用箭弧连结,箭弧上的标记(字符)代表射出结状态下可能出现的输入字符或字符类
    • 一张转换图只包含有限个状态,其中有一个为初态,用箭头指出;至少要有一个终态,用双圈表示。(注意:当双圈有一个星号是表示舍弃最后输入的字符)
  • 状态转换图可用于识别(或接受)一定的字符串

    • 若存在一条从初态到某一终态的道路 ,且这条路上所有弧上的标记符连接成的字等于a ,则称a被该状态转换图所识别(接受)。

例子: 第一条分支表示标识符;第二条分支表示常数。
编译原理词法分析(一)_第6张图片

状态转换图的代码实现

每个状态结点对应一小段程序
1.对于不含回路的结点
编译原理词法分析(一)_第7张图片
2.含回路的结点
编译原理词法分析(一)_第8张图片
3.终态
编译原理词法分析(一)_第9张图片

全局变量与过程

编译原理词法分析(一)_第10张图片
编译原理词法分析(一)_第11张图片
标识符的实现代码:
编译原理词法分析(一)_第12张图片

int code, value ;
StrToken :=""; /*置strToken为空串*/
GetChar() ; GetBC() ;
if (IsLetter() )
begin
	while (IsLetter() or IsDigit() )
	begin
		Concat () ; GetChar() ;
	end
	Retract () ;
	code := Reserve () ;
	if (code = 0)
	begin
		value :=. InsertId ( strToken) ;
		return ($ID, vabue) ;
	end
	else 
		return (code, -) ;
	end	

常数和、+、=实现代码:
编译原理词法分析(一)_第13张图片

else if (IsDigit() )
begin
	while (IsDigit() )
	begin
		Concat( ) ; GetChar( ) ;
	end
	Retract() ;
	value := InsertConst (s trToken) ;
	return ($INT, value) ;
end
else if (ch = '=' ) return ($ASSIGN, -) ;
else if (ch = '+' ) return ($PLUS, -) ;

编译原理词法分析(一)_第14张图片

else if (ch = '*')
begin
	GetChar () ;
	if (ch = '*') return ($POWER, -) ;
	Retract() ; return ( $STAR,-) ;
end
else if (ch =',') return ($COMMA, -) ;
else if (ch ='(') return ($LPAR, -) ;
else if (ch =')') return ($RPAR, -) ;
else ProcError( ) ; /*错误处理*/	

将状态图代码一般化

  • 变量curState用于保存现有的状态
  • 用二维数组表示状态图: stateTrans[state][ch]
    • 第一个下标[state]保存图中的状态编号
    • 第二个下标[ch]是可能输入的字符
    • stateTrans[state][ch]的值是[state]状态,输入[ch]后的状态

编译原理词法分析(一)_第15张图片

你可能感兴趣的:(编译原理词法分析(一))