4 词法分析的基本概念

在上一篇我们讨论了编译器的结构,包括编译器的各个阶段和它们之间的关系。今天我们将深入探讨编译器的重要组成部分之一:词法分析。词法分析是编译过程的第一步,其主要任务是将源代码转化为一系列的“词法单元”或记号(tokens),为后续的语法分析打下基础。

1. 词法分析的目的

词法分析的主要目的是将输入的字符流转换为意义明确的记号序列。每个记号代表源代码中的一个基本元素,比如关键字、变量、运算符等。比如,对于输入代码int a = 5;,词法分析的输出可能是以下几个记号:

  • int(关键字)
  • a(标识符)
  • =(运算符)
  • 5(常量)
  • ;(分隔符)

这种转化使得后续的语法分析可以更容易地理解程序的结构。

2. 词法分析的工作机制

词法分析器会负责以下几个主要任务:

  1. 读取输入源代码:逐字符读取源代码。
  2. 识别记号:根据定义的规则识别出不同的记号类型。
  3. 生成输出:将识别出来的记号输出给语法分析器,同时也可以生成错误报告和跳过注释等过程。

3. 记号的分类

在词法分析的过程中,我们需要将记号分为几种基本类别:

  • 关键字:如 intifwhile 等。
  • 标识符:变量名、函数名等用户定义的名称。
  • 常量:数字、字符串等。
  • 运算符:如 +-*/ 等。
  • 分隔符:如 ;,() 等。

4. 词法分析的实现

词法分析器通常会用到一个有限状态机来进行状态转换,从而识别不同类型的记号。以下是一个简单的词法分析的代码示例,使用 Python 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import re

def lexer(input_code):
# 定义正则表达式
token_specs = [
("NUMBER", r'\d+'), # 数字
("ASSIGN", r'='), # 赋值符号
("ID", r'[A-Za-z]+'), # 标识符
("SEMICOLON", r';'), # 分号
("SKIP", r'[ \t]+'), # 跳过空白
("NEWLINE", r'\n'), # 换行
("MISMATCH", r'.'), # 其他字符
]

# 将正则表达式编译成模式对象
tok_regex = '|'.join(f'(?P<{pair[0]}>{pair[1]})' for pair in token_specs)
get_token = re.compile(tok_regex).match

line_num = 1
line_start = 0
tokens = []

# 逐字符读取输入源代码
mo = get_token(input_code)
while mo is not None:
typ = mo.lastgroup
if typ == "NUMBER":
value = int(mo.group())
tokens.append(('NUMBER', value))
elif typ == "ID":
value = mo.group()
tokens.append(('ID', value))
elif typ == "ASSIGN":
tokens.append(('ASSIGN', '='))
elif typ == "SEMICOLON":
tokens.append(('SEMICOLON', ';'))
elif typ == "NEWLINE":
line_start = mo.end()
line_num += 1
elif typ == "MISMATCH":
raise RuntimeError(f'{mo.group()} unexpected on line {line_num}')
mo = get_token(input_code, mo.end())

return tokens

# 测试词法分析器
input_code = "int a = 5;"
tokens = lexer(input_code)
for token in tokens:
print(token)

在这个简化的例子中,我们使用正则表达式来定义不同类型的记号。词法分析器通过get_token函数循环匹配输入代码,将匹配到的记号和相应的值存储到一个tokens列表中。

5. 小结

本篇文章介绍了词法分析的基本概念,包括词法分析的目的、工作机制、记号的分类以及简单的实现示例。通过词法分析,编译器可以将源代码转换成结构化的记号序列,从而为后续的语法分析和其他编译器阶段做好准备。

在下一篇,我们将进一步讨论正则表达式与有限自动机的关系,这是理解词法分析重要的一环。通过学习这些基础知识,读者将能更好地掌握编译器设计中的词法分析阶段。

4 词法分析的基本概念

https://zglg.work/compiler-zero/4/

作者

IT教程网(郭震)

发布于

2024-08-11

更新于

2024-08-12

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论