手写词法分析器(一)
学习目标
通过本集的学习,你将能够:
- 理解逐个字符读取
- 掌握状态转换思路
- 学会识别数字
1. 逐个字符读取
词法分析器的基本循环:
while 还有字符:
读取下一个字符
根据当前状态决定做什么1.1 简单实现框架
class Lexer:
def __init__(self, source):
self.source = source
self.pos = 0
self.current_char = self.source[0] if source else None
def advance(self):
self.pos += 1
if self.pos < len(self.source):
self.current_char = self.source[self.pos]
else:
self.current_char = None2. 识别数字
2.1 数字的状态机
状态图:
开始 → [0-9] → 数字状态 → [0-9] → 数字状态
→ 其他 → 结束2.2 代码实现
def number(self):
result = ''
while self.current_char is not None and self.current_char.isdigit():
result += self.current_char
self.advance()
return ('NUMBER', int(result))3. 实用案例
3.1 完整数字识别器
class SimpleLexer:
def __init__(self, text):
self.text = text
self.pos = 0
self.current_char = self.text[self.pos]
def error(self):
raise Exception('Invalid character')
def advance(self):
self.pos += 1
if self.pos > len(self.text) - 1:
self.current_char = None
else:
self.current_char = self.text[self.pos]
def skip_whitespace(self):
while self.current_char is not None and self.current_char.isspace():
self.advance()
def integer(self):
result = ''
while self.current_char is not None and self.current_char.isdigit():
result += self.current_char
self.advance()
return int(result)
def get_next_token(self):
while self.current_char is not None:
if self.current_char.isspace():
self.skip_whitespace()
continue
if self.current_char.isdigit():
return ('INTEGER', self.integer())
self.error()
return ('EOF', None)4. 自测问题
- 词法分析器如何逐个字符读取?
- 什么是状态转换?
- 如何识别数字?
5. 下集预告
下一集我们将学习手写词法分析器(二)!
参考资料
- 《编译原理》(龙书)