正则表达式语言是否需要下推自动机进行解析?


12

我想将用户输入的正则表达式转换为NFA,以便随后可以对字符串运行NFA以进行匹配。可用于解析正则表达式的最低机器是什么?

我认为它必须是下推式自动机,因为方括号的含义意味着需要计数,而DFA / NFA不能执行任意计数。这个假设正确吗?例如,表达式a(bc *)d需要使用PDA,以便正确处理括号中的子表达式。


1
“解析”到底是什么意思?您是要检查输入是否确实是正则表达式,还是要考虑更复杂的事情,例如输出相应NFA描述的计算机?(如果不确定输入是否确实是正则表达式,并且需要对其进行检查,则需要能够检查括号是否正确,并且通常意味着使用堆栈。)
Kaveh,2012年

对于实际的答案,可以查看grep.yPlan 9 Grep源
Bruce Ediger

Answers:


8

你是对的。使用标准技术可以很容易地证明正则表达式的语法不是正则。

REG(p)p

也就是说,您可能不想手工编写PDA。考虑使用解析器生成器,例如ANTLRbyacc。另一方面,如果您想自己编写解析器来研究语言的解析,则应继续使用其他基本解析算法,例如CYKEarley递归下降LR


谢谢。这些任务编写的代码创建一个更好的理解,而不是为了被视为有效像法现有公用事业,YACC,野牛等
菲尔·赖特

@PhilWright:我知道了,太好了!我为这种情况编写了更多的指针。
拉斐尔

我希望为此编写一个手工编码的递归下降解析器。
戴夫·克拉克

如果为此目的手动编写解析器,则可以选择递归下降(在分解和按摩之后),用于C < sites.google.com/site/lccretargetablecompiler > 的LCC解析器具有处理许多运算符的有趣方法。但是,也许最容易进行手工构建的是优先级解析。
vonbrand

3

我建议您也阅读cstheory上Jukka对“ 使用正则表达式匹配正则表达式 ” 问题的很好回答。摘录:

例如,我们可以如下修改标准符号,以获得“压缩的”正则表达式

  • 您可以删除由(的
  • 您可以删除由)的序列组成的所有后缀

即,((a|b)*c)de(f|g)可以在使用“压缩”表示法来表示,例如,以下任何一种形式:a|b)*c)de(f|g((a|b)*c)de(f|g(a|b)*c)de(f|g)

[...]

(正则表达式的)“压缩”符号是一种正则语言。

这只是对正则表达式语言一个有趣的(根据我而言)“不同观点”的链接。如以下注释中强调的那样,它对于构建语法树没有用。如果您想手工编写解析器代码,我会建议您在代码项目“ Writing-own-regular-expression-parser ” 上这篇简单的文章。


Jukka从根本上消除了括号必须保持平衡的要求。我不知道实际执行此操作的任何实例,但是值得一提的是,通过更改语义,您可以“简化”语法。
拉斐尔

4
您(和Jukka)不是在解析正则表达式,而只是在识别它们。“是的,这是(压缩的)正则表达式。”
吉尔(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.