实现词法分析器时的 DFA 与正则表达式?

Posted

技术标签:

【中文标题】实现词法分析器时的 DFA 与正则表达式?【英文标题】:DFAs vs Regexes when implementing a lexical analyzer? 【发布时间】:2013-01-03 09:13:59 【问题描述】:

(我只是在学习如何编写编译器,所以如果我提出任何不正确的声明,请纠正我)

当人们可以简单地使用正则表达式时,为什么还要在代码中实现 DFA(goto 语句、表驱动的实现)?据我了解,词法分析器接收一串字符并生成一个标记列表,这些标记在语言的语法定义中是终端,使得它们可以用正则表达式来描述。循环一堆正则表达式,如果找到匹配项就跳出循环不是更容易吗?

【问题讨论】:

主要原因是表格驱动的 DFA 可以很容易地由程序(例如 lex)生成。 【参考方案1】:

您说的完全正确,在许多情况下,编写正则表达式比编写 DFA 更容易。然而,一个值得思考的好问题是

这些正则表达式匹配器是如何工作的?

正则表达式匹配器的大多数非常快速的实现都是通过在内部编译成某种类型的自动机(NFA 或最小状态 DFA)来工作的。如果您想构建一个扫描器,通过使用正则表达式来描述要匹配的标记,然后循环遍历所有标记,您绝对可以这样做,但在内部它们可能会编译为 DFA。

很少有人真正编写 DFA 来进行扫描或解析,因为它实在是太复杂了。这就是为什么有像lexflex 这样的工具的原因,它们可以让您指定要匹配的正则表达式,然后在后台自动编译为DFA。这样,您就可以两全其美 - 您可以使用更好的正则表达式框架来描述要匹配的内容,但您可以在幕后获得 DFA 的速度和效率。

关于构建巨型 DFA 的一个更重要的细节是,可以构建一个尝试并行匹配多个不同正则表达式的单个 DFA。这提高了效率,因为可以在字符串上运行匹配的 DFA,同时搜索所有可能的正则表达式匹配。

希望这会有所帮助!

【讨论】:

此外,正则表达式模式往往比使用好的词法分析器要慢,只有好的正则表达式系统才能处理匹配多个嵌套的分隔符(如括号)。 @GuyCoder 在编译器中,解析器处理括号,而不是词法分析器。 @EJP 你的权利。我现在正忙于解析器组合器,并没有考虑词法分析器/解析器。

以上是关于实现词法分析器时的 DFA 与正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

编译原理-第三章 词法分析-3.7 从正则表达式到自动机-从NFA到DFA的转换

编译原理词法分析

从正则表达式(RE)到最小确定性有限状态自动机(DFA)

词法分析器:通过有限自动机实现正则表达式?

如何使用 DFA 正则表达式匹配器实现正则表达式断言/环视(即 \b 样式字边界)

词法分析练习题2 DFA极小化正则式转NFA编译原理