有限自动机(Finite State Machine, FSM)详解
有限自动机(Finite State Machine, FSM)是一种数学模型,用来描述具有有限个状态的系统及其状态之间的转移。它广泛应用于计算机科学中,尤其是在编译器的词法分析阶段、状态控制、正则表达式引擎等领域。
FSM 通过状态和状态转移规则来模拟系统的行为。它的基本构成包括:
- 状态集(States):有限个状态,表示系统在某一时刻可能处于的状态。
- 输入符号集(Input Alphabet):可以使系统发生状态转移的输入符号集合。
- 状态转移函数(Transition Function):定义了从一个状态到另一个状态的转移规则,通常以一个表或图的形式表现。
- 初始状态(Initial State):FSM 开始时的状态。
- 终止状态(Accepting State):一个或多个接受状态,表示系统在这些状态下处理成功或满足某种条件。
1. FSM 的基本结构和工作原理
有限自动机的工作过程可以想象成“阅读输入并在不同的状态之间跳跃”。FSM 从初始状态开始,根据输入符号的不同,转移到下一个状态。FSM 运行时,会从输入符号流中读取一个个字符(或符号),并依据当前状态及符号来决定下一个状态,直到输入完毕。
FSM 的类型
FSM 有两种主要类型:
- 确定性有限自动机(DFA, Deterministic Finite Automaton):
- 对于每个输入符号,在每个状态下只有一个明确的转移。
- 无论在任何状态下,输入某个字符后,FSM 只能跳到唯一的下一个状态。
- DFA 的状态转换是确定的,即每个状态对每个可能的输入符号都有唯一的转移。
- 非确定性有限自动机(NFA, Nondeterministic Finite Automaton):
- 对于某个输入符号,某个状态可能有多个不同的转移,甚至可能没有任何转移。
- NFA 允许同时在多个状态之间跳跃(即并行处理)。
- 虽然 NFA 在理论上更加灵活,但通常需要转换为 DFA 才能高效地执行。
DFA 和 NFA 的区别
- 确定性(DFA):每个状态对每个输入符号有唯一的转移。
- 非确定性(NFA):某个状态对某些输入符号可能有多个转移,或者没有任何转移。
尽管 NFA 和 DFA 在理论上等价,NFA 可以转换成等价的 DFA,但 NFA 的实现通常比 DFA 更加灵活和简洁,尤其适用于正则表达式的解析。
2. FSM 的工作过程
假设我们要实现一个简单的有限自动机,用来识别由数字和字母组成的标识符(例如 myVar123
)。我们可以设计一个简单的 DFA,定义如下:
- 初始状态为
S0
,表示输入的字符还未开始处理。 - 如果输入的字符是字母,FSM 转移到状态
S1
(字母状态)。 - 如果输入的字符是数字,FSM 进入状态
S2
(数字状态)。 - 如果状态是
S1
,再输入一个字母或数字,FSM 保持在S1
状态,继续处理下去。 - 如果状态是
S2
,再输入一个字母或数字,FSM 会转回S1
状态。
状态转移图如下所示:
- 状态
S0
(初始状态):接收字母 →S1
,接收数字 →S2
。 - 状态
S1
:接收字母 →S1
,接收数字 →S1
,接收其他字符 → 错误状态。 - 状态
S2
:接收字母 →S1
,接收数字 →S2
,接收其他字符 → 错误状态。
当输入流结束时,如果当前状态是 S1
或 S2
,表示输入的字符是有效的标识符。
状态转移图
S0 --letter--> S1 --letter/digit--> S1
| |
| v
+--digit--> S2 --letter--> S1
| |
+---------------------+
3. FSM 在编译器中的应用
有限自动机在编译器中的应用主要体现在词法分析阶段。编译器的词法分析器(又叫扫描器)使用有限自动机将源代码拆解成一个个 Token。每种 Token 类型(如关键字、标识符、常量等)都可以用一个有限自动机来表示。
例如,假设我们需要处理标识符(由字母和数字组成),可以设计一个 DFA 来识别标识符的 Token;如果是处理数字常量(如 123
或 3.14
),我们可以使用另一个 DFA 来识别数字 Token。
词法分析中的应用示例:
假设我们需要实现一个能够识别简单数字字面量(整数)的 DFA:
- 状态 S0:表示还未读取任何字符。
- 如果读取到数字字符(
0-9
),转移到状态S1
。 - 如果读取到其他字符,错误结束。
- 如果读取到数字字符(
- 状态 S1:表示已经读取了一个或多个数字字符。
- 如果继续读取数字字符(
0-9
),保持在状态S1
。 - 如果读取到非数字字符,表示数字字面量结束。
- 如果继续读取数字字符(
在实际的实现中,这个过程可以通过一个简单的状态机来模拟。
状态转移图示例:
S0 --digit--> S1 --digit--> S1
| |
+---------------------+
当输入的字符为 12345
时,FSM 会从状态 S0
转移到状态 S1
,并保持在状态 S1
,直到输入完毕。
4. FSM 的优化与变种
虽然有限自动机简单且高效,但它也有一些限制。例如,FSM 不能处理某些类型的语言(如上下文相关语言),它只能处理正则表达式定义的语言。为了解决这一问题,通常会将 FSM 和其他类型的自动机(如栈自动机)结合使用。
优化技巧:
- DFA 最小化:通过合并等价状态来减少状态数量,优化 FSM 的效率。
- NFA 转换:使用 NFA 来简化正则表达式的处理,再转换为 DFA 进行高效的执行。
5. 总结
有限自动机(FSM)是编译器中不可或缺的工具,尤其在词法分析阶段,用于将输入的字符流转化为具有意义的 Token。通过状态机的方式,它能够高效地完成输入的解析,并为语法分析提供基础。FSM 的核心思想是通过状态和状态转移规则来处理输入,在许多计算机科学领域中都有广泛的应用。