flex或lex是否执行DFA最小化?
如果是,那么我有这些问题:
使用了什么算法?
说,我们的规格如下
%{
#include <stdio.h>
%}
%%
a printf("a\n");
b printf("b\n");
%%
这对应于正则表达式a|b
,DFA构造可以导致DFA有3个状态来解析此表达式(采用JSON格式):
{states: [0, 1, 2],
moves: [
{from: 0, char: 'a', to: 1},
{from: 0, char: 'b', to: 2}
],
start: 0,
final: [1, 2]
}
虽然这个DFA运行良好,并且对于每个接受状态,它正确调用所需的动作,但Hopcroft的DFA最小化算法会将两个接受状态合并为一个,这将导致DFA具有两个状态。这可能是一个问题,因为我们不知道在接受状态下调用哪个动作。 flex或lex如何处理这个?
答案 0 :(得分:1)
Flex不会最小化DFA,原来的lex也没有。我不能代表存在的每一种可能的lex实现。
Hopcroft算法首先将状态分为两组:接受状态和非接受状态。这些集合显然是不同的,算法的其余部分通过细化分区来进行。由于算法的基本属性,只需要重新检查其中一个分区。
在词汇规范的情况下,接受状态也带有动作号,结果是接受状态的集合不能被认为是同质的。相反,初始分区必须是N+1
个子集,其中N
是词法分析器操作的数量。除非只有一个动作,否则这不是二进制优化,因此基本属性不适用,所有分区都需要重新检查。
此外,经典的Hopcroft算法假定DFA是完整的;每个州都有每个输入的过渡。 (f)lex生成的DFA不是这种情况。对算法有一些修改可以解决这个问题,或者你可以只为状态集添加一个宿状态(所有的转换都是循环的)。