我想使用FLEX计算某个正则表达式的DFA状态总数。哪些C文件或函数可以帮助我使用FLEX完成此任务?
答案 0 :(得分:2)
如果您查看由flex
生成的文件,那么yy_accept
(和yy_base
)中的条目数可能会很好地指示所使用的状态数生成DFA。如果您使用-Cf
选项,则yy_nxt
包含DFA的转换函数,表中的行数也是使用状态的数量。
您可能有不同版本的flex
,其中表的命名方式不同,但很可能它们的名称非常相似。
在回答您的问题时:假设DFA已经最小化,DFA中的状态数量可以被认为是非常明确的。然而,转换次数的定义不太明确。
首先,flex
对每个输入字符都有一个转换,因为它将ECHO
任何不属于定义语言的字符。这是通过一个新的新状态来实现的。使用调试器可以反向设计这是哪种状态。但请注意,如果使用开始条件,则可能必须考虑存在多个此类状态的可能性。如果您想分析许多正则表达式,那么您可能需要查看其他一些工具或从flex
获取来源并从那里开始。
在第二位flex
有策略来最小化所有表的总大小。 -Cf
选项指示它不这样做。一个这样的优化是找到字符的等价类,并且仅对每个字符类使用转换。输入字符首先被转换为其类,而后者又用于确定转换。因此,转换的数量要低得多,但确定字符类需要一个额外的表(请参阅yy_ec
)。
因此,过渡次数是一个定义不太明确的概念。如果您对确定扫描仪的内存占用率感兴趣,那么我会查看扫描仪数据部分的大小。例如objdump -h
文件上使用lex.yy.o
。 .rodata
部分的大小可以非常准确地估算表格的总大小。
您似乎已找到-v
的{{1}}选项,它以更详细的形式提供DFA中的状态数。为了回答flex
给出5个州的原因,您也可以使用"a" {}
选项,因为它会在生成时为DFA提供。显然还有--trace
规则,我认为它用于文件结束。对于每个开始条件,有两种状态,一种在线的开始处使用,一种在线的中间使用。这使得3个接受状态(一个用于End Marker
,一个用于"a"
,一个用于End Marker
)加上两个状态用于单个开始条件。
源文件(.|"\n")
不是生成代码的一部分,但如果您觉得勇敢,您当然可以更改dfa.c
的来源以进一步分析您自己的代码。我快速浏览了一下,似乎代码的生成与转换交织在一起,这使得它的模块化程度低于实验平台所需的模块化程度。还要注意K& R原型,它们可以有效地禁用对原型的任何类型检查。