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