我想学习如何编写像flex这样的词法分析器生成器。我一直在阅读“编译原理:技术、原理和工具”(即“龙书”),对flex的工作原理有了基本的了解。
我的初始方法是:用户将提供一个正则表达式的哈希映射,将一个正则表达式映射到一个标记枚举。程序将按照给定顺序循环遍历每个正则表达式,并查看它们是否与字符串的开头匹配(我可以在每个正则表达式的开头添加
我的第一个问题是,这是最有效的方法吗?目前我必须循环遍历每个正则表达式,但从理论上讲,我可以从组合所有正则表达式中构造一个DFA,并更有效地进行步进。然而,创建这个DFA会有一些开销。
我的第二个问题是,我该如何实现最长匹配字符串的选择器,就像flex一样?也就是说,我想将
我的两个问题都指向编写自己的从正则表达式到DFA的翻译器。这是必需的吗,还是我仍然可以使用普通的正则表达式(由标准库实现),并获得最长的匹配?
编辑:我没有提到我正在使用哪个正则表达式引擎,因为我想要一个通用的答案,但我正在使用Rust的正则表达式库:http://static.rust-lang.org/doc/master/regex/index.html
我的初始方法是:用户将提供一个正则表达式的哈希映射,将一个正则表达式映射到一个标记枚举。程序将按照给定顺序循环遍历每个正则表达式,并查看它们是否与字符串的开头匹配(我可以在每个正则表达式的开头添加
^
来实现此目的)。如果匹配成功,我可以将该正则表达式的标记添加到程序的标记列表中。我的第一个问题是,这是最有效的方法吗?目前我必须循环遍历每个正则表达式,但从理论上讲,我可以从组合所有正则表达式中构造一个DFA,并更有效地进行步进。然而,创建这个DFA会有一些开销。
我的第二个问题是,我该如何实现最长匹配字符串的选择器,就像flex一样?也就是说,我想将
ifa
匹配为标识符,而不是关键字if
后面跟着字母a
。我没有看到任何有效的使用正则表达式的方法。我想我必须遍历所有的正则表达式,尝试匹配它们,如果有多个匹配结果,就选择最长的一个。然而,如果我将正则表达式转换为DFA(也就是我的自己的DFA数据结构),那么我可以继续在字符上进行步进,直到DFA上没有更多的可能性转移边。此时,我可以将我通过接受状态的最后一次经过作为一个标记的实际匹配,因为这应该是最长的匹配。我的两个问题都指向编写自己的从正则表达式到DFA的翻译器。这是必需的吗,还是我仍然可以使用普通的正则表达式(由标准库实现),并获得最长的匹配?
编辑:我没有提到我正在使用哪个正则表达式引擎,因为我想要一个通用的答案,但我正在使用Rust的正则表达式库:http://static.rust-lang.org/doc/master/regex/index.html